Skip to content

Commit 77ddb18

Browse files
yihuangmmsqe
authored andcommitted
prefix store support object store (cosmos#236)
1 parent 4dfbe1b commit 77ddb18

File tree

5 files changed

+86
-45
lines changed

5 files changed

+86
-45
lines changed

store/cachekv/store.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,10 @@ func (store *GStore[V]) Get(key []byte) (value V) {
9090
return value
9191
}
9292

93-
func (store *GStore[V]) assertValidValue(value V) {
94-
if store.isZero(value) {
95-
panic("value is nil")
96-
}
97-
types.AssertValidValueLength(store.valueLen(value))
98-
}
99-
10093
// Set implements types.KVStore.
10194
func (store *GStore[V]) Set(key []byte, value V) {
10295
types.AssertValidKey(key)
103-
store.assertValidValue(value)
96+
types.AssertValidValueGeneric(value, store.isZero, store.valueLen)
10497

10598
store.mtx.Lock()
10699
defer store.mtx.Unlock()

store/gaskv/store.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,10 @@ func (gs *GStore[V]) Get(key []byte) (value V) {
7575
return value
7676
}
7777

78-
func (gs *GStore[V]) assertValidValue(value V) {
79-
if gs.isZero(value) {
80-
panic("value is nil")
81-
}
82-
types.AssertValidValueLength(gs.valueLen(value))
83-
}
84-
8578
// Set implements KVStore.
8679
func (gs *GStore[V]) Set(key []byte, value V) {
8780
types.AssertValidKey(key)
88-
gs.assertValidValue(value)
81+
types.AssertValidValueGeneric(value, gs.isZero, gs.valueLen)
8982
gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostFlat, types.GasWriteCostFlatDesc)
9083
// TODO overflow-safe math?
9184
gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostPerByte*types.Gas(len(key)), types.GasWritePerByteDesc)

store/prefix/store.go

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,53 @@ import (
1010
"cosmossdk.io/store/types"
1111
)
1212

13-
var _ types.KVStore = Store{}
13+
type (
14+
Store = GStore[[]byte]
15+
ObjStore = GStore[any]
16+
)
17+
18+
var (
19+
_ types.KVStore = Store{}
20+
_ types.ObjKVStore = ObjStore{}
21+
)
22+
23+
func NewStore(parent types.KVStore, prefix []byte) Store {
24+
return NewGStore(
25+
parent, prefix,
26+
func(v []byte) bool { return v == nil },
27+
func(v []byte) int { return len(v) },
28+
)
29+
}
1430

15-
// Store is similar with cometbft/cometbft-db/blob/v1.0.1/prefixdb.go
31+
func NewObjStore(parent types.ObjKVStore, prefix []byte) ObjStore {
32+
return NewGStore(
33+
parent, prefix,
34+
func(v any) bool { return v == nil },
35+
func(v any) int { return 1 },
36+
)
37+
}
38+
39+
// GStore is similar with cometbft/cometbft-db/blob/v1.0.1/prefixdb.go
1640
// both gives access only to the limited subset of the store
1741
// for convenience or safety
18-
type Store struct {
19-
parent types.KVStore
42+
type GStore[V any] struct {
43+
parent types.GKVStore[V]
2044
prefix []byte
45+
46+
isZero func(V) bool
47+
valueLen func(V) int
2148
}
2249

23-
func NewStore(parent types.KVStore, prefix []byte) Store {
24-
return Store{
50+
func NewGStore[V any](
51+
parent types.GKVStore[V], prefix []byte,
52+
isZero func(V) bool, valueLen func(V) int,
53+
) GStore[V] {
54+
return GStore[V]{
2555
parent: parent,
2656
prefix: prefix,
57+
58+
isZero: isZero,
59+
valueLen: valueLen,
2760
}
2861
}
2962

@@ -34,7 +67,7 @@ func cloneAppend(bz, tail []byte) (res []byte) {
3467
return
3568
}
3669

37-
func (s Store) key(key []byte) (res []byte) {
70+
func (s GStore[V]) key(key []byte) (res []byte) {
3871
if key == nil {
3972
panic("nil key on Store")
4073
}
@@ -43,13 +76,13 @@ func (s Store) key(key []byte) (res []byte) {
4376
}
4477

4578
// GetStoreType implements Store
46-
func (s Store) GetStoreType() types.StoreType {
79+
func (s GStore[V]) GetStoreType() types.StoreType {
4780
return s.parent.GetStoreType()
4881
}
4982

5083
// CacheWrap implements CacheWrap
51-
func (s Store) CacheWrap() types.CacheWrap {
52-
return cachekv.NewStore(s)
84+
func (s GStore[V]) CacheWrap() types.CacheWrap {
85+
return cachekv.NewGStore(s, s.isZero, s.valueLen)
5386
}
5487

5588
// CacheWrapWithTrace implements the KVStore interface.
@@ -58,31 +91,31 @@ func (s Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types.Cach
5891
}
5992

6093
// Get implements KVStore
61-
func (s Store) Get(key []byte) []byte {
94+
func (s GStore[V]) Get(key []byte) V {
6295
res := s.parent.Get(s.key(key))
6396
return res
6497
}
6598

6699
// Has implements KVStore
67-
func (s Store) Has(key []byte) bool {
100+
func (s GStore[V]) Has(key []byte) bool {
68101
return s.parent.Has(s.key(key))
69102
}
70103

71104
// Set implements KVStore
72-
func (s Store) Set(key, value []byte) {
105+
func (s GStore[V]) Set(key []byte, value V) {
73106
types.AssertValidKey(key)
74-
types.AssertValidValue(value)
107+
types.AssertValidValueGeneric(value, s.isZero, s.valueLen)
75108
s.parent.Set(s.key(key), value)
76109
}
77110

78111
// Delete implements KVStore
79-
func (s Store) Delete(key []byte) {
112+
func (s GStore[V]) Delete(key []byte) {
80113
s.parent.Delete(s.key(key))
81114
}
82115

83116
// Iterator implements KVStore
84117
// Check https://github.com/cometbft/cometbft-db/blob/v1.0.1/prefixdb.go#L109
85-
func (s Store) Iterator(start, end []byte) types.Iterator {
118+
func (s GStore[V]) Iterator(start, end []byte) types.GIterator[V] {
86119
newstart := cloneAppend(s.prefix, start)
87120

88121
var newend []byte
@@ -99,7 +132,7 @@ func (s Store) Iterator(start, end []byte) types.Iterator {
99132

100133
// ReverseIterator implements KVStore
101134
// Check https://github.com/cometbft/cometbft-db/blob/v1.0.1/prefixdb.go#L132
102-
func (s Store) ReverseIterator(start, end []byte) types.Iterator {
135+
func (s GStore[V]) ReverseIterator(start, end []byte) types.GIterator[V] {
103136
newstart := cloneAppend(s.prefix, start)
104137

105138
var newend []byte
@@ -114,18 +147,18 @@ func (s Store) ReverseIterator(start, end []byte) types.Iterator {
114147
return newPrefixIterator(s.prefix, start, end, iter)
115148
}
116149

117-
var _ types.Iterator = (*prefixIterator)(nil)
150+
var _ types.Iterator = (*prefixIterator[[]byte])(nil)
118151

119-
type prefixIterator struct {
152+
type prefixIterator[V any] struct {
120153
prefix []byte
121154
start []byte
122155
end []byte
123-
iter types.Iterator
156+
iter types.GIterator[V]
124157
valid bool
125158
}
126159

127-
func newPrefixIterator(prefix, start, end []byte, parent types.Iterator) *prefixIterator {
128-
return &prefixIterator{
160+
func newPrefixIterator[V any](prefix, start, end []byte, parent types.GIterator[V]) *prefixIterator[V] {
161+
return &prefixIterator[V]{
129162
prefix: prefix,
130163
start: start,
131164
end: end,
@@ -135,17 +168,17 @@ func newPrefixIterator(prefix, start, end []byte, parent types.Iterator) *prefix
135168
}
136169

137170
// Domain implements Iterator
138-
func (pi *prefixIterator) Domain() ([]byte, []byte) {
171+
func (pi *prefixIterator[V]) Domain() ([]byte, []byte) {
139172
return pi.start, pi.end
140173
}
141174

142175
// Valid implements Iterator
143-
func (pi *prefixIterator) Valid() bool {
176+
func (pi *prefixIterator[V]) Valid() bool {
144177
return pi.valid && pi.iter.Valid()
145178
}
146179

147180
// Next implements Iterator
148-
func (pi *prefixIterator) Next() {
181+
func (pi *prefixIterator[V]) Next() {
149182
if !pi.valid {
150183
panic("prefixIterator invalid, cannot call Next()")
151184
}
@@ -157,7 +190,7 @@ func (pi *prefixIterator) Next() {
157190
}
158191

159192
// Key implements Iterator
160-
func (pi *prefixIterator) Key() (key []byte) {
193+
func (pi *prefixIterator[V]) Key() (key []byte) {
161194
if !pi.valid {
162195
panic("prefixIterator invalid, cannot call Key()")
163196
}
@@ -169,7 +202,7 @@ func (pi *prefixIterator) Key() (key []byte) {
169202
}
170203

171204
// Value implements Iterator
172-
func (pi *prefixIterator) Value() []byte {
205+
func (pi *prefixIterator[V]) Value() V {
173206
if !pi.valid {
174207
panic("prefixIterator invalid, cannot call Value()")
175208
}
@@ -178,13 +211,13 @@ func (pi *prefixIterator) Value() []byte {
178211
}
179212

180213
// Close implements Iterator
181-
func (pi *prefixIterator) Close() error {
214+
func (pi *prefixIterator[V]) Close() error {
182215
return pi.iter.Close()
183216
}
184217

185218
// Error returns an error if the prefixIterator is invalid defined by the Valid
186219
// method.
187-
func (pi *prefixIterator) Error() error {
220+
func (pi *prefixIterator[V]) Error() error {
188221
if !pi.Valid() {
189222
return errors.New("invalid prefixIterator")
190223
}

store/types/store.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,3 +597,17 @@ func NewMemoryStoreKeys(names ...string) map[string]*MemoryStoreKey {
597597

598598
return keys
599599
}
600+
601+
// NewObjectStoreKeys constructs a new map matching store key names to their
602+
// respective ObjectStoreKey references.
603+
// The function will panic if there is a potential conflict in names (see `assertNoPrefix`
604+
// function for more details).
605+
func NewObjectStoreKeys(names ...string) map[string]*ObjectStoreKey {
606+
assertNoCommonPrefix(names)
607+
keys := make(map[string]*ObjectStoreKey)
608+
for _, n := range names {
609+
keys[n] = NewObjectStoreKey(n)
610+
}
611+
612+
return keys
613+
}

store/types/validity.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ func AssertValidValue(value []byte) {
3030
AssertValidValueLength(len(value))
3131
}
3232

33+
// AssertValidValueGeneric checks if the value is valid(value is not nil and within length limit)
34+
func AssertValidValueGeneric[V any](value V, isZero func(V) bool, valueLen func(V) int) {
35+
if isZero(value) {
36+
panic("value is nil")
37+
}
38+
AssertValidValueLength(valueLen(value))
39+
}
40+
3341
// AssertValidValueLength checks if the value length is within length limit
3442
func AssertValidValueLength(l int) {
3543
if l > MaxValueLength {

0 commit comments

Comments
 (0)