Skip to content

Commit 73eb838

Browse files
yihuangJayT106
authored andcommitted
prefix store support object store (#236)
1 parent c72940a commit 73eb838

File tree

6 files changed

+87
-46
lines changed

6 files changed

+87
-46
lines changed

store/cachekv/store.go

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

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

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

store/gaskv/store.go

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

74-
func (gs *GStore[V]) assertValidValue(value V) {
75-
if gs.isZero(value) {
76-
panic("value is nil")
77-
}
78-
types.AssertValidValueLength(gs.valueLen(value))
79-
}
80-
8174
// Implements KVStore.
8275
func (gs *GStore[V]) Set(key []byte, value V) {
8376
types.AssertValidKey(key)
84-
gs.assertValidValue(value)
77+
types.AssertValidValueGeneric(value, gs.isZero, gs.valueLen)
8578
gs.gasMeter.ConsumeGas(gs.gasConfig.WriteCostFlat, types.GasWriteCostFlatDesc)
8679
// TODO overflow-safe math?
8780
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
@@ -8,20 +8,53 @@ import (
88
"cosmossdk.io/store/types"
99
)
1010

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

13-
// Store is similar with cometbft/cometbft/libs/db/prefix_db
29+
func NewObjStore(parent types.ObjKVStore, prefix []byte) ObjStore {
30+
return NewGStore(
31+
parent, prefix,
32+
func(v any) bool { return v == nil },
33+
func(v any) int { return 1 },
34+
)
35+
}
36+
37+
// GStore is similar with cometbft/cometbft/libs/db/prefix_db
1438
// both gives access only to the limited subset of the store
1539
// for convinience or safety
16-
type Store struct {
17-
parent types.KVStore
40+
type GStore[V any] struct {
41+
parent types.GKVStore[V]
1842
prefix []byte
43+
44+
isZero func(V) bool
45+
valueLen func(V) int
1946
}
2047

21-
func NewStore(parent types.KVStore, prefix []byte) Store {
22-
return Store{
48+
func NewGStore[V any](
49+
parent types.GKVStore[V], prefix []byte,
50+
isZero func(V) bool, valueLen func(V) int,
51+
) GStore[V] {
52+
return GStore[V]{
2353
parent: parent,
2454
prefix: prefix,
55+
56+
isZero: isZero,
57+
valueLen: valueLen,
2558
}
2659
}
2760

@@ -32,7 +65,7 @@ func cloneAppend(bz, tail []byte) (res []byte) {
3265
return
3366
}
3467

35-
func (s Store) key(key []byte) (res []byte) {
68+
func (s GStore[V]) key(key []byte) (res []byte) {
3669
if key == nil {
3770
panic("nil key on Store")
3871
}
@@ -41,41 +74,41 @@ func (s Store) key(key []byte) (res []byte) {
4174
}
4275

4376
// Implements Store
44-
func (s Store) GetStoreType() types.StoreType {
77+
func (s GStore[V]) GetStoreType() types.StoreType {
4578
return s.parent.GetStoreType()
4679
}
4780

4881
// Implements CacheWrap
49-
func (s Store) CacheWrap() types.CacheWrap {
50-
return cachekv.NewStore(s)
82+
func (s GStore[V]) CacheWrap() types.CacheWrap {
83+
return cachekv.NewGStore(s, s.isZero, s.valueLen)
5184
}
5285

5386
// Implements KVStore
54-
func (s Store) Get(key []byte) []byte {
87+
func (s GStore[V]) Get(key []byte) V {
5588
res := s.parent.Get(s.key(key))
5689
return res
5790
}
5891

5992
// Implements KVStore
60-
func (s Store) Has(key []byte) bool {
93+
func (s GStore[V]) Has(key []byte) bool {
6194
return s.parent.Has(s.key(key))
6295
}
6396

6497
// Implements KVStore
65-
func (s Store) Set(key, value []byte) {
98+
func (s GStore[V]) Set(key []byte, value V) {
6699
types.AssertValidKey(key)
67-
types.AssertValidValue(value)
100+
types.AssertValidValueGeneric(value, s.isZero, s.valueLen)
68101
s.parent.Set(s.key(key), value)
69102
}
70103

71104
// Implements KVStore
72-
func (s Store) Delete(key []byte) {
105+
func (s GStore[V]) Delete(key []byte) {
73106
s.parent.Delete(s.key(key))
74107
}
75108

76109
// Implements KVStore
77110
// Check https://github.com/cometbft/cometbft/blob/master/libs/db/prefix_db.go#L106
78-
func (s Store) Iterator(start, end []byte) types.Iterator {
111+
func (s GStore[V]) Iterator(start, end []byte) types.GIterator[V] {
79112
newstart := cloneAppend(s.prefix, start)
80113

81114
var newend []byte
@@ -92,7 +125,7 @@ func (s Store) Iterator(start, end []byte) types.Iterator {
92125

93126
// ReverseIterator implements KVStore
94127
// Check https://github.com/cometbft/cometbft/blob/master/libs/db/prefix_db.go#L129
95-
func (s Store) ReverseIterator(start, end []byte) types.Iterator {
128+
func (s GStore[V]) ReverseIterator(start, end []byte) types.GIterator[V] {
96129
newstart := cloneAppend(s.prefix, start)
97130

98131
var newend []byte
@@ -107,18 +140,18 @@ func (s Store) ReverseIterator(start, end []byte) types.Iterator {
107140
return newPrefixIterator(s.prefix, start, end, iter)
108141
}
109142

110-
var _ types.Iterator = (*prefixIterator)(nil)
143+
var _ types.Iterator = (*prefixIterator[[]byte])(nil)
111144

112-
type prefixIterator struct {
145+
type prefixIterator[V any] struct {
113146
prefix []byte
114147
start []byte
115148
end []byte
116-
iter types.Iterator
149+
iter types.GIterator[V]
117150
valid bool
118151
}
119152

120-
func newPrefixIterator(prefix, start, end []byte, parent types.Iterator) *prefixIterator {
121-
return &prefixIterator{
153+
func newPrefixIterator[V any](prefix, start, end []byte, parent types.GIterator[V]) *prefixIterator[V] {
154+
return &prefixIterator[V]{
122155
prefix: prefix,
123156
start: start,
124157
end: end,
@@ -128,17 +161,17 @@ func newPrefixIterator(prefix, start, end []byte, parent types.Iterator) *prefix
128161
}
129162

130163
// Implements Iterator
131-
func (pi *prefixIterator) Domain() ([]byte, []byte) {
164+
func (pi *prefixIterator[V]) Domain() ([]byte, []byte) {
132165
return pi.start, pi.end
133166
}
134167

135168
// Implements Iterator
136-
func (pi *prefixIterator) Valid() bool {
169+
func (pi *prefixIterator[V]) Valid() bool {
137170
return pi.valid && pi.iter.Valid()
138171
}
139172

140173
// Implements Iterator
141-
func (pi *prefixIterator) Next() {
174+
func (pi *prefixIterator[V]) Next() {
142175
if !pi.valid {
143176
panic("prefixIterator invalid, cannot call Next()")
144177
}
@@ -150,7 +183,7 @@ func (pi *prefixIterator) Next() {
150183
}
151184

152185
// Implements Iterator
153-
func (pi *prefixIterator) Key() (key []byte) {
186+
func (pi *prefixIterator[V]) Key() (key []byte) {
154187
if !pi.valid {
155188
panic("prefixIterator invalid, cannot call Key()")
156189
}
@@ -162,7 +195,7 @@ func (pi *prefixIterator) Key() (key []byte) {
162195
}
163196

164197
// Implements Iterator
165-
func (pi *prefixIterator) Value() []byte {
198+
func (pi *prefixIterator[V]) Value() V {
166199
if !pi.valid {
167200
panic("prefixIterator invalid, cannot call Value()")
168201
}
@@ -171,13 +204,13 @@ func (pi *prefixIterator) Value() []byte {
171204
}
172205

173206
// Implements Iterator
174-
func (pi *prefixIterator) Close() error {
207+
func (pi *prefixIterator[V]) Close() error {
175208
return pi.iter.Close()
176209
}
177210

178211
// Error returns an error if the prefixIterator is invalid defined by the Valid
179212
// method.
180-
func (pi *prefixIterator) Error() error {
213+
func (pi *prefixIterator[V]) Error() error {
181214
if !pi.Valid() {
182215
return errors.New("invalid prefixIterator")
183216
}

store/types/store.go

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

584584
return keys
585585
}
586+
587+
// NewObjectStoreKeys constructs a new map matching store key names to their
588+
// respective ObjectStoreKey references.
589+
// The function will panic if there is a potential conflict in names (see `assertNoPrefix`
590+
// function for more details).
591+
func NewObjectStoreKeys(names ...string) map[string]*ObjectStoreKey {
592+
assertNoCommonPrefix(names)
593+
keys := make(map[string]*ObjectStoreKey)
594+
for _, n := range names {
595+
keys[n] = NewObjectStoreKey(n)
596+
}
597+
598+
return keys
599+
}

store/types/validity.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ func AssertValidValue(value []byte) {
2727
AssertValidValueLength(len(value))
2828
}
2929

30+
// AssertValidValueGeneric checks if the value is valid(value is not nil and within length limit)
31+
func AssertValidValueGeneric[V any](value V, isZero func(V) bool, valueLen func(V) int) {
32+
if isZero(value) {
33+
panic("value is nil")
34+
}
35+
AssertValidValueLength(valueLen(value))
36+
}
37+
3038
// AssertValidValueLength checks if the value length is within length limit
3139
func AssertValidValueLength(l int) {
3240
if l > MaxValueLength {

types/context.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ func (c Context) TransientStore(key storetypes.StoreKey) storetypes.KVStore {
350350
}
351351

352352
// ObjectStore fetches an object store from the MultiStore,
353-
func (c Context) OjectStore(key storetypes.StoreKey) storetypes.ObjKVStore {
353+
func (c Context) ObjectStore(key storetypes.StoreKey) storetypes.ObjKVStore {
354354
return gaskv.NewObjStore(c.ms.GetObjKVStore(key), c.gasMeter, c.transientKVGasConfig)
355355
}
356356

0 commit comments

Comments
 (0)