44 "fmt"
55 "io"
66 "maps"
7+ "sync"
78
89 dbm "github.com/cosmos/cosmos-db"
910
@@ -33,16 +34,22 @@ type Store struct {
3334 traceContext types.TraceContext
3435}
3536
36- var _ types.CacheMultiStore = Store {}
37+ type PooledStore struct {
38+ Store
39+ }
40+
41+ var _ types.CacheMultiStore = & Store {}
42+
43+ var _ types.PooledCacheMultiStore = & PooledStore {}
3744
3845// NewFromKVStore creates a new Store object from a mapping of store keys to
3946// CacheWrapper objects and a KVStore as the database. Each CacheWrapper store
4047// is a branched store.
4148func NewFromKVStore (
4249 store types.KVStore , stores map [types.StoreKey ]types.CacheWrapper ,
4350 keys map [string ]types.StoreKey , traceWriter io.Writer , traceContext types.TraceContext ,
44- ) Store {
45- cms := Store {
51+ ) * Store {
52+ cms := & Store {
4653 db : cachekv .NewStore (store ),
4754 stores : make (map [types.StoreKey ]types.CacheWrap , len (stores )),
4855 keys : keys ,
@@ -69,11 +76,64 @@ func NewFromKVStore(
6976func NewStore (
7077 db dbm.DB , stores map [types.StoreKey ]types.CacheWrapper , keys map [string ]types.StoreKey ,
7178 traceWriter io.Writer , traceContext types.TraceContext ,
72- ) Store {
79+ ) * Store {
7380 return NewFromKVStore (dbadapter.Store {DB : db }, stores , keys , traceWriter , traceContext )
7481}
7582
76- func newCacheMultiStoreFromCMS (cms Store ) Store {
83+ var storePool = sync.Pool {
84+ New : func () any {
85+ return & PooledStore {
86+ Store : Store {
87+ stores : make (map [types.StoreKey ]types.CacheWrap ),
88+ keys : make (map [string ]types.StoreKey ),
89+ },
90+ }
91+ },
92+ }
93+
94+ func newFromKVStorePooled (
95+ store types.KVStore , stores map [types.StoreKey ]types.CacheWrap ,
96+ traceWriter io.Writer , traceContext types.TraceContext ,
97+ ) * PooledStore {
98+ cms := storePool .Get ().(* PooledStore )
99+ cms .traceWriter = traceWriter
100+ cms .traceContext = traceContext
101+ for key , store := range stores {
102+ var cwStore types.CacheWrapper = store
103+ if cms .TracingEnabled () {
104+ tctx := cms .traceContext .Clone ().Merge (types.TraceContext {
105+ storeNameCtxKey : key .Name (),
106+ })
107+
108+ cwStore = tracekv .NewStore (store .(types.KVStore ), cms .traceWriter , tctx )
109+ }
110+ cms .stores [key ] = cachekv .NewPooledStore (cwStore .(types.KVStore ))
111+ }
112+ cms .db = cachekv .NewPooledStore (store )
113+ return cms
114+ }
115+
116+ func (cms * PooledStore ) Release () {
117+ // clear the stores map
118+ for k , v := range cms .stores {
119+ if pStore , ok := v .(* cachekv.PooledStore ); ok {
120+ pStore .Release ()
121+ }
122+ delete (cms .stores , k )
123+ }
124+ for k := range cms .keys {
125+ delete (cms .keys , k )
126+ }
127+ if pStoreDb , ok := cms .db .(* cachekv.PooledStore ); ok {
128+ pStoreDb .Release ()
129+ }
130+ cms .db = nil
131+ cms .traceContext = nil
132+ cms .traceWriter = nil
133+ storePool .Put (cms )
134+ }
135+
136+ func newCacheMultiStoreFromCMS (cms * Store ) * Store {
77137 stores := make (map [types.StoreKey ]types.CacheWrapper )
78138 for k , v := range cms .stores {
79139 stores [k ] = v
@@ -84,7 +144,7 @@ func newCacheMultiStoreFromCMS(cms Store) Store {
84144
85145// SetTracer sets the tracer for the MultiStore that the underlying
86146// stores will utilize to trace operations. A MultiStore is returned.
87- func (cms Store ) SetTracer (w io.Writer ) types.MultiStore {
147+ func (cms * Store ) SetTracer (w io.Writer ) types.MultiStore {
88148 cms .traceWriter = w
89149 return cms
90150}
@@ -93,7 +153,7 @@ func (cms Store) SetTracer(w io.Writer) types.MultiStore {
93153// the given context with the existing context by key. Any existing keys will
94154// be overwritten. It is implied that the caller should update the context when
95155// necessary between tracing operations. It returns a modified MultiStore.
96- func (cms Store ) SetTracingContext (tc types.TraceContext ) types.MultiStore {
156+ func (cms * Store ) SetTracingContext (tc types.TraceContext ) types.MultiStore {
97157 if cms .traceContext != nil {
98158 maps .Copy (cms .traceContext , tc )
99159 } else {
@@ -104,54 +164,58 @@ func (cms Store) SetTracingContext(tc types.TraceContext) types.MultiStore {
104164}
105165
106166// TracingEnabled returns if tracing is enabled for the MultiStore.
107- func (cms Store ) TracingEnabled () bool {
167+ func (cms * Store ) TracingEnabled () bool {
108168 return cms .traceWriter != nil
109169}
110170
111171// LatestVersion returns the branch version of the store
112- func (cms Store ) LatestVersion () int64 {
172+ func (cms * Store ) LatestVersion () int64 {
113173 panic ("cannot get latest version from branch cached multi-store" )
114174}
115175
116176// GetStoreType returns the type of the store.
117- func (cms Store ) GetStoreType () types.StoreType {
177+ func (cms * Store ) GetStoreType () types.StoreType {
118178 return types .StoreTypeMulti
119179}
120180
121181// Write calls Write on each underlying store.
122- func (cms Store ) Write () {
182+ func (cms * Store ) Write () {
123183 cms .db .Write ()
124184 for _ , store := range cms .stores {
125185 store .Write ()
126186 }
127187}
128188
129189// Implements CacheWrapper.
130- func (cms Store ) CacheWrap () types.CacheWrap {
190+ func (cms * Store ) CacheWrap () types.CacheWrap {
131191 return cms .CacheMultiStore ().(types.CacheWrap )
132192}
133193
134194// CacheWrapWithTrace implements the CacheWrapper interface.
135- func (cms Store ) CacheWrapWithTrace (_ io.Writer , _ types.TraceContext ) types.CacheWrap {
195+ func (cms * Store ) CacheWrapWithTrace (_ io.Writer , _ types.TraceContext ) types.CacheWrap {
136196 return cms .CacheWrap ()
137197}
138198
139199// Implements MultiStore.
140- func (cms Store ) CacheMultiStore () types.CacheMultiStore {
200+ func (cms * Store ) CacheMultiStore () types.CacheMultiStore {
141201 return newCacheMultiStoreFromCMS (cms )
142202}
143203
204+ func (cms * Store ) CacheMultiStorePooled () types.PooledCacheMultiStore {
205+ return newFromKVStorePooled (cms .db , cms .stores , cms .traceWriter , cms .traceContext )
206+ }
207+
144208// CacheMultiStoreWithVersion implements the MultiStore interface. It will panic
145209// as an already cached multi-store cannot load previous versions.
146210//
147211// TODO: The store implementation can possibly be modified to support this as it
148212// seems safe to load previous versions (heights).
149- func (cms Store ) CacheMultiStoreWithVersion (_ int64 ) (types.CacheMultiStore , error ) {
213+ func (cms * Store ) CacheMultiStoreWithVersion (_ int64 ) (types.CacheMultiStore , error ) {
150214 panic ("cannot branch cached multi-store with a version" )
151215}
152216
153217// GetStore returns an underlying Store by key.
154- func (cms Store ) GetStore (key types.StoreKey ) types.Store {
218+ func (cms * Store ) GetStore (key types.StoreKey ) types.Store {
155219 s := cms .stores [key ]
156220 if key == nil || s == nil {
157221 panic (fmt .Sprintf ("kv store with key %v has not been registered in stores" , key ))
@@ -160,7 +224,7 @@ func (cms Store) GetStore(key types.StoreKey) types.Store {
160224}
161225
162226// GetKVStore returns an underlying KVStore by key.
163- func (cms Store ) GetKVStore (key types.StoreKey ) types.KVStore {
227+ func (cms * Store ) GetKVStore (key types.StoreKey ) types.KVStore {
164228 store := cms .stores [key ]
165229 if key == nil || store == nil {
166230 panic (fmt .Sprintf ("kv store with key %v has not been registered in stores" , key ))
0 commit comments