Skip to content

Commit 268f5a9

Browse files
author
Dan Laine
authored
MerkleDB -- add eviction batch size config (ava-labs#1586)
1 parent aed31ae commit 268f5a9

File tree

4 files changed

+65
-130
lines changed

4 files changed

+65
-130
lines changed

x/merkledb/db.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ import (
2828
)
2929

3030
const (
31-
RootPath = EmptyPath
32-
evictionBatchSize = 100
31+
RootPath = EmptyPath
3332
// TODO: name better
3433
rebuildViewSizeFractionOfCacheSize = 50
3534
minRebuildViewSizePerCommit = 1000
@@ -116,6 +115,9 @@ type MerkleDB interface {
116115
}
117116

118117
type Config struct {
118+
// The number of nodes that are evicted from the cache and written to
119+
// disk at a time.
120+
EvictionBatchSize int
119121
// The number of changes to the database that we store in memory in order to
120122
// serve change proofs.
121123
HistoryLength int
@@ -144,8 +146,9 @@ type merkleDB struct {
144146
metadataDB database.Database
145147

146148
// If a value is nil, the corresponding key isn't in the trie.
147-
nodeCache onEvictCache[path, *node]
148-
onEvictionErr utils.Atomic[error]
149+
nodeCache onEvictCache[path, *node]
150+
onEvictionErr utils.Atomic[error]
151+
evictionBatchSize int
149152

150153
// Stores change lists. Used to serve change proofs and construct
151154
// historical views of the trie.
@@ -172,12 +175,13 @@ func newDatabase(
172175
metrics merkleMetrics,
173176
) (*merkleDB, error) {
174177
trieDB := &merkleDB{
175-
metrics: metrics,
176-
nodeDB: prefixdb.New(nodePrefix, db),
177-
metadataDB: prefixdb.New(metadataPrefix, db),
178-
history: newTrieHistory(config.HistoryLength),
179-
tracer: config.Tracer,
180-
childViews: make([]*trieView, 0, defaultPreallocationSize),
178+
metrics: metrics,
179+
nodeDB: prefixdb.New(nodePrefix, db),
180+
metadataDB: prefixdb.New(metadataPrefix, db),
181+
history: newTrieHistory(config.HistoryLength),
182+
tracer: config.Tracer,
183+
childViews: make([]*trieView, 0, defaultPreallocationSize),
184+
evictionBatchSize: config.EvictionBatchSize,
181185
}
182186

183187
// Note: trieDB.OnEviction is responsible for writing intermediary nodes to
@@ -757,7 +761,7 @@ func (db *merkleDB) onEviction(n *node) error {
757761
// just [n], so that we don't immediately evict and write another
758762
// node, because each time this method is called we do a disk write.
759763
var err error
760-
for removedCount := 0; removedCount < evictionBatchSize; removedCount++ {
764+
for removedCount := 0; removedCount < db.evictionBatchSize; removedCount++ {
761765
_, n, exists := db.nodeCache.removeOldest()
762766
if !exists {
763767
// The cache is empty.

x/merkledb/db_test.go

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strconv"
1111
"testing"
1212

13+
"github.com/prometheus/client_golang/prometheus"
1314
"github.com/stretchr/testify/require"
1415

1516
"github.com/ava-labs/avalanchego/database"
@@ -26,6 +27,16 @@ func newNoopTracer() trace.Tracer {
2627
return tracer
2728
}
2829

30+
func newDefaultConfig() Config {
31+
return Config{
32+
EvictionBatchSize: 100,
33+
HistoryLength: 100,
34+
NodeCacheSize: 1_000,
35+
Reg: prometheus.NewRegistry(),
36+
Tracer: newNoopTracer(),
37+
}
38+
}
39+
2940
func Test_MerkleDB_Get_Safety(t *testing.T) {
3041
db, err := getBasicDB()
3142
require.NoError(t, err)
@@ -86,11 +97,7 @@ func Test_MerkleDB_DB_Load_Root_From_DB(t *testing.T) {
8697
db, err := New(
8798
context.Background(),
8899
rdb,
89-
Config{
90-
Tracer: newNoopTracer(),
91-
HistoryLength: 100,
92-
NodeCacheSize: 100,
93-
},
100+
newDefaultConfig(),
94101
)
95102
require.NoError(err)
96103

@@ -112,11 +119,7 @@ func Test_MerkleDB_DB_Load_Root_From_DB(t *testing.T) {
112119
db, err = New(
113120
context.Background(),
114121
rdb,
115-
Config{
116-
Tracer: newNoopTracer(),
117-
HistoryLength: 100,
118-
NodeCacheSize: 100,
119-
},
122+
newDefaultConfig(),
120123
)
121124
require.NoError(err)
122125
reloadedRoot, err := db.GetMerkleRoot(context.Background())
@@ -132,14 +135,13 @@ func Test_MerkleDB_DB_Rebuild(t *testing.T) {
132135

133136
initialSize := 10_000
134137

138+
config := newDefaultConfig()
139+
config.NodeCacheSize = initialSize
140+
135141
db, err := New(
136142
context.Background(),
137143
rdb,
138-
Config{
139-
Tracer: newNoopTracer(),
140-
HistoryLength: 100,
141-
NodeCacheSize: initialSize,
142-
},
144+
config,
143145
)
144146
require.NoError(err)
145147

@@ -167,10 +169,7 @@ func Test_MerkleDB_Failed_Batch_Commit(t *testing.T) {
167169
db, err := New(
168170
context.Background(),
169171
memDB,
170-
Config{
171-
Tracer: newNoopTracer(),
172-
HistoryLength: 300,
173-
},
172+
newDefaultConfig(),
174173
)
175174
require.NoError(t, err)
176175

@@ -190,11 +189,7 @@ func Test_MerkleDB_Value_Cache(t *testing.T) {
190189
db, err := New(
191190
context.Background(),
192191
memDB,
193-
Config{
194-
Tracer: newNoopTracer(),
195-
HistoryLength: 300,
196-
NodeCacheSize: minCacheSize,
197-
},
192+
newDefaultConfig(),
198193
)
199194
require.NoError(t, err)
200195

@@ -815,11 +810,7 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest) {
815810
dbTrie, err := newDatabase(
816811
context.Background(),
817812
memdb.New(),
818-
Config{
819-
Tracer: newNoopTracer(),
820-
HistoryLength: 0,
821-
NodeCacheSize: minCacheSize,
822-
},
813+
newDefaultConfig(),
823814
&mockMetrics{},
824815
)
825816
require.NoError(err)

x/sync/client_test.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/golang/mock/gomock"
14+
"github.com/prometheus/client_golang/prometheus"
1415

1516
"github.com/stretchr/testify/require"
1617

@@ -27,6 +28,16 @@ import (
2728
syncpb "github.com/ava-labs/avalanchego/proto/pb/sync"
2829
)
2930

31+
func newDefaultDBConfig() merkledb.Config {
32+
return merkledb.Config{
33+
EvictionBatchSize: 100,
34+
HistoryLength: defaultRequestKeyLimit,
35+
NodeCacheSize: defaultRequestKeyLimit,
36+
Reg: prometheus.NewRegistry(),
37+
Tracer: newNoopTracer(),
38+
}
39+
}
40+
3041
func sendRangeRequest(
3142
t *testing.T,
3243
db SyncableDB,
@@ -377,21 +388,14 @@ func TestGetChangeProof(t *testing.T) {
377388
trieDB, err := merkledb.New(
378389
context.Background(),
379390
memdb.New(),
380-
merkledb.Config{
381-
Tracer: newNoopTracer(),
382-
HistoryLength: defaultRequestKeyLimit,
383-
NodeCacheSize: defaultRequestKeyLimit,
384-
},
391+
newDefaultDBConfig(),
385392
)
386393
require.NoError(t, err)
394+
387395
verificationDB, err := merkledb.New(
388396
context.Background(),
389397
memdb.New(),
390-
merkledb.Config{
391-
Tracer: newNoopTracer(),
392-
HistoryLength: defaultRequestKeyLimit,
393-
NodeCacheSize: defaultRequestKeyLimit,
394-
},
398+
newDefaultDBConfig(),
395399
)
396400
require.NoError(t, err)
397401
startRoot, err := trieDB.GetMerkleRoot(context.Background())

0 commit comments

Comments
 (0)