@@ -3,18 +3,21 @@ package store
3
3
import (
4
4
"context"
5
5
6
+ corestoretypes "cosmossdk.io/core/store"
6
7
"cosmossdk.io/errors"
7
8
cachekv "cosmossdk.io/store/cachekv"
8
- "cosmossdk.io/store/types"
9
+ storetypes "cosmossdk.io/store/types"
9
10
bigcache "github.com/allegro/bigcache/v3"
10
11
)
11
12
13
+ var _ corestoretypes.KVStore = (* CacheStore )(nil )
14
+
12
15
type CacheStore struct {
13
- store types .CacheKVStore
16
+ store storetypes .CacheKVStore
14
17
cache * bigcache.BigCache
15
18
}
16
19
17
- func NewCacheStore (store types .KVStore , capacity int ) * CacheStore {
20
+ func NewCacheStore (store storetypes .KVStore , capacity int ) * CacheStore {
18
21
// default with no eviction and custom hard max cache capacity
19
22
cacheCfg := bigcache .DefaultConfig (0 )
20
23
cacheCfg .Verbose = false
@@ -31,33 +34,48 @@ func NewCacheStore(store types.KVStore, capacity int) *CacheStore {
31
34
}
32
35
}
33
36
37
+ // Get returns nil iff key doesn't exist. Errors on nil key.
34
38
func (c CacheStore ) Get (key []byte ) ([]byte , error ) {
35
- types .AssertValidKey (key )
39
+ storetypes .AssertValidKey (key )
36
40
37
- v , err := c .cache .Get (string (key ))
38
- // cache hit
39
- if err == nil {
40
- return v , nil
41
+ if value , err := c .cache .Get (string (key )); err == nil {
42
+ return value , nil
41
43
}
42
44
43
45
// get from store and write to cache
44
46
value := c .store .Get (key )
45
- err = c .cache .Set (string (key ), value )
46
- if err != nil {
47
- return nil , errors .Wrap (err , "failed to set cache" )
47
+ if value == nil {
48
+ return nil , nil
48
49
}
49
50
51
+ // ignore cache error
52
+ _ = c .cache .Set (string (key ), value )
53
+
50
54
return value , nil
51
55
}
52
56
57
+ // Has checks if a key exists. Errors on nil key.
53
58
func (c CacheStore ) Has (key []byte ) (bool , error ) {
54
59
_ , err := c .cache .Get (string (key ))
55
- return err == nil , err
60
+ if err == nil {
61
+ return true , nil
62
+ }
63
+
64
+ value := c .store .Get (key )
65
+ if value == nil {
66
+ return false , nil
67
+ }
68
+
69
+ // ignore cache error
70
+ _ = c .cache .Set (string (key ), value )
71
+
72
+ return true , nil
56
73
}
57
74
75
+ // Set sets the key. Errors on nil key or value.
58
76
func (c CacheStore ) Set (key , value []byte ) error {
59
- types .AssertValidKey (key )
60
- types .AssertValidValue (value )
77
+ storetypes .AssertValidKey (key )
78
+ storetypes .AssertValidValue (value )
61
79
62
80
err := c .cache .Set (string (key ), value )
63
81
if err != nil {
@@ -68,20 +86,35 @@ func (c CacheStore) Set(key, value []byte) error {
68
86
return nil
69
87
}
70
88
89
+ // Delete deletes the key. Errors on nil key.
71
90
func (c CacheStore ) Delete (key []byte ) error {
72
- types .AssertValidKey (key )
91
+ storetypes .AssertValidKey (key )
73
92
74
- _ = c .cache .Delete (string (key ))
93
+ err := c .cache .Delete (string (key ))
94
+ if err != nil && errors .IsOf (err , bigcache .ErrEntryNotFound ) {
95
+ return errors .Wrap (err , "failed to delete cache" )
96
+ }
75
97
c .store .Delete (key )
76
98
77
99
return nil
78
100
}
79
101
80
- func (c CacheStore ) Iterator (start , end []byte ) (types.Iterator , error ) {
102
+ // Iterator iterates over a domain of keys in ascending order. End is exclusive.
103
+ // Start must be less than end, or the Iterator is invalid.
104
+ // Iterator must be closed by caller.
105
+ // To iterate over entire domain, use store.Iterator(nil, nil)
106
+ // CONTRACT: No writes may happen within a domain while an iterator exists over it.
107
+ // Exceptionally allowed for cachekv.Store, safe to write in the modules.
108
+ func (c CacheStore ) Iterator (start , end []byte ) (storetypes.Iterator , error ) {
81
109
return c .store .Iterator (start , end ), nil
82
110
}
83
111
84
- func (c CacheStore ) ReverseIterator (start , end []byte ) (types.Iterator , error ) {
112
+ // ReverseIterator iterates over a domain of keys in descending order. End is exclusive.
113
+ // Start must be less than end, or the Iterator is invalid.
114
+ // Iterator must be closed by caller.
115
+ // CONTRACT: No writes may happen within a domain while an iterator exists over it.
116
+ // Exceptionally allowed for cachekv.Store, safe to write in the modules.
117
+ func (c CacheStore ) ReverseIterator (start , end []byte ) (storetypes.Iterator , error ) {
85
118
return c .store .ReverseIterator (start , end ), nil
86
119
}
87
120
0 commit comments