From 7c1db795998929e39e55b5ac2dfd90666e625d1a Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Mon, 13 Oct 2025 10:52:57 +0800 Subject: [PATCH 1/2] triedb/pathdb: make batch with pre-allocated size --- triedb/pathdb/history_index_block.go | 8 ++++---- triedb/pathdb/history_indexer.go | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/triedb/pathdb/history_index_block.go b/triedb/pathdb/history_index_block.go index 7648b99226c9..5abdee682ad6 100644 --- a/triedb/pathdb/history_index_block.go +++ b/triedb/pathdb/history_index_block.go @@ -25,10 +25,10 @@ import ( ) const ( - indexBlockDescSize = 14 // The size of index block descriptor - indexBlockEntriesCap = 4096 // The maximum number of entries can be grouped in a block - indexBlockRestartLen = 256 // The restart interval length of index block - historyIndexBatch = 1_000_000 // The number of state history indexes for constructing or deleting as batch + indexBlockDescSize = 14 // The size of index block descriptor + indexBlockEntriesCap = 4096 // The maximum number of entries can be grouped in a block + indexBlockRestartLen = 256 // The restart interval length of index block + historyIndexBatch = 512 * 1024 // The number of state history indexes for constructing or deleting as batch ) // indexBlockDesc represents a descriptor for an index block, which contains a diff --git a/triedb/pathdb/history_indexer.go b/triedb/pathdb/history_indexer.go index 368ff78d415e..18d8e28831ac 100644 --- a/triedb/pathdb/history_indexer.go +++ b/triedb/pathdb/history_indexer.go @@ -40,6 +40,11 @@ const ( stateHistoryIndexVersion = stateHistoryIndexV0 // the current state index version trienodeHistoryIndexV0 = uint8(0) // initial version of trienode index structure trienodeHistoryIndexVersion = trienodeHistoryIndexV0 // the current trienode index version + + // estimations for calculating the batch size for atomic database commit + estimatedStateHistoryIndexSize = 3 // The average size of each state history index entry is approximately 2–3 bytes + estimatedTrienodeHistoryIndexSize = 3 // The average size of each trienode history index entry is approximately 2-3 bytes + estimatedIndexBatchSizeFactor = 32 // The factor counts for the write amplification for each entry ) // indexVersion returns the latest index version for the given history type. @@ -150,6 +155,20 @@ func (b *batchIndexer) process(h history, id uint64) error { return b.finish(false) } +// makeBatch constructs a database batch based on the number of pending entries. +// The batch size is roughly estimated to minimize repeated resizing rounds, +// as accurately predicting the exact size is technically challenging. +func (b *batchIndexer) makeBatch() ethdb.Batch { + var size int + switch b.typ { + case typeStateHistory: + size = estimatedStateHistoryIndexSize + case typeTrienodeHistory: + size = estimatedTrienodeHistoryIndexSize + } + return b.db.NewBatchWithSize(size * estimatedIndexBatchSizeFactor * b.pending) +} + // finish writes the accumulated state indexes into the disk if either the // memory limitation is reached or it's requested forcibly. func (b *batchIndexer) finish(force bool) error { @@ -160,7 +179,7 @@ func (b *batchIndexer) finish(force bool) error { return nil } var ( - batch = b.db.NewBatch() + batch = b.makeBatch() batchMu sync.RWMutex start = time.Now() eg errgroup.Group From 5f8a77fc222d8a095558c64a5eefe6ee59d6aea9 Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Tue, 21 Oct 2025 18:26:55 +0800 Subject: [PATCH 2/2] triedb/pathdb: add default clause --- triedb/pathdb/history_indexer.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triedb/pathdb/history_indexer.go b/triedb/pathdb/history_indexer.go index 18d8e28831ac..893ccd652368 100644 --- a/triedb/pathdb/history_indexer.go +++ b/triedb/pathdb/history_indexer.go @@ -165,6 +165,8 @@ func (b *batchIndexer) makeBatch() ethdb.Batch { size = estimatedStateHistoryIndexSize case typeTrienodeHistory: size = estimatedTrienodeHistoryIndexSize + default: + panic(fmt.Sprintf("unknown history type %d", b.typ)) } return b.db.NewBatchWithSize(size * estimatedIndexBatchSizeFactor * b.pending) }