File tree Expand file tree Collapse file tree 2 files changed +20
-3
lines changed Expand file tree Collapse file tree 2 files changed +20
-3
lines changed Original file line number Diff line number Diff line change @@ -5,18 +5,25 @@ package blockdb
55
66import (
77 "slices"
8+ "sync"
89
910 "go.uber.org/zap"
1011
1112 "github.com/ava-labs/avalanchego/cache/lru"
1213 "github.com/ava-labs/avalanchego/database"
1314)
1415
16+ // numShards is the number of mutex shards used to reduce lock contention for
17+ // concurrent Put operations. Using 256 shards provides a good balance between
18+ // memory usage (~2KB) and concurrency.
19+ const numShards = 256
20+
1521var _ database.HeightIndex = (* cacheDB )(nil )
1622
1723type cacheDB struct {
18- db * Database
19- cache * lru.Cache [BlockHeight , BlockData ]
24+ db * Database
25+ cache * lru.Cache [BlockHeight , BlockData ]
26+ shards [numShards ]sync.Mutex
2027}
2128
2229func newCacheDB (db * Database , size uint16 ) * cacheDB {
@@ -46,7 +53,18 @@ func (c *cacheDB) Get(height BlockHeight) (BlockData, error) {
4653 return data , nil
4754}
4855
56+ // Put writes block data at the specified height to both the underlying database
57+ // and the cache.
58+ //
59+ // Concurrent calls to Put with the same height are serialized using sharded
60+ // locking to ensure cache consistency with the underlying database.
61+ // This allows concurrent writes to different heights while preventing race
62+ // conditions for writes to the same height.
4963func (c * cacheDB ) Put (height BlockHeight , data BlockData ) error {
64+ shard := & c .shards [height % numShards ]
65+ shard .Lock ()
66+ defer shard .Unlock ()
67+
5068 if err := c .db .Put (height , data ); err != nil {
5169 return err
5270 }
Original file line number Diff line number Diff line change @@ -110,7 +110,6 @@ func TestCachePutOverridesSameHeight(t *testing.T) {
110110 cached , ok = db .cache .Get (height )
111111 require .True (t , ok )
112112 require .Equal (t , b2 , cached )
113- require .NotEqual (t , b1 , cached )
114113
115114 // Get should also return the new block
116115 data , err := db .Get (height )
You can’t perform that action at this time.
0 commit comments