add block cache

Signed-off-by: Delweng <delweng@gmail.com>
This commit is contained in:
Delweng 2025-07-23 22:42:12 +08:00 committed by jsvisa
parent a259ae54e8
commit cbe8bf82dc
2 changed files with 31 additions and 8 deletions

View file

@ -160,11 +160,19 @@ func (r *indexReader) readGreaterThan(id uint64) (uint64, error) {
blob []byte blob []byte
) )
start := time.Now() start := time.Now()
key := fmt.Sprintf("%s:%d", r.state.String(), desc.id)
if val, ok := historyBlockCache.Get(key); ok {
blob = val
} else {
if r.state.account { if r.state.account {
blob = rawdb.ReadAccountHistoryIndexBlock(r.db, r.state.addressHash, desc.id) blob = rawdb.ReadAccountHistoryIndexBlock(r.db, r.state.addressHash, desc.id)
} else { } else {
blob = rawdb.ReadStorageHistoryIndexBlock(r.db, r.state.addressHash, r.state.storageHash, desc.id) blob = rawdb.ReadStorageHistoryIndexBlock(r.db, r.state.addressHash, r.state.storageHash, desc.id)
} }
if len(blob) > 0 {
historyBlockCache.Add(key, blob)
}
}
if r.timings != nil { if r.timings != nil {
r.timings.kvdbBlock = time.Since(start) r.timings.kvdbBlock = time.Since(start)
} }
@ -423,10 +431,11 @@ func (d *indexDeleter) pop(id uint64) error {
// //
// This function is safe to be called multiple times. // This function is safe to be called multiple times.
func (d *indexDeleter) finish(batch ethdb.Batch) { func (d *indexDeleter) finish(batch ethdb.Batch) {
if key := d.state.String(); historyIndexCache.Contains(key) {
historyIndexCache.Remove(key)
}
for _, id := range d.dropped { for _, id := range d.dropped {
key := fmt.Sprintf("%s:%d", d.state.String(), id)
if historyBlockCache.Contains(key) {
historyBlockCache.Remove(key)
}
if d.state.account { if d.state.account {
rawdb.DeleteAccountHistoryIndexBlock(batch, d.state.addressHash, id) rawdb.DeleteAccountHistoryIndexBlock(batch, d.state.addressHash, id)
} else { } else {
@ -437,14 +446,23 @@ func (d *indexDeleter) finish(batch ethdb.Batch) {
// Flush the content of last block writer, regardless it's dirty or not // Flush the content of last block writer, regardless it's dirty or not
if !d.bw.empty() { if !d.bw.empty() {
buf := d.bw.finish()
key := fmt.Sprintf("%s:%d", d.state.String(), d.bw.desc.id)
if historyBlockCache.Contains(key) {
historyBlockCache.Add(key, buf)
}
if d.state.account { if d.state.account {
rawdb.WriteAccountHistoryIndexBlock(batch, d.state.addressHash, d.bw.desc.id, d.bw.finish()) rawdb.WriteAccountHistoryIndexBlock(batch, d.state.addressHash, d.bw.desc.id, buf)
} else { } else {
rawdb.WriteStorageHistoryIndexBlock(batch, d.state.addressHash, d.state.storageHash, d.bw.desc.id, d.bw.finish()) rawdb.WriteStorageHistoryIndexBlock(batch, d.state.addressHash, d.state.storageHash, d.bw.desc.id, buf)
} }
} }
// Flush the index metadata into the supplied batch // Flush the index metadata into the supplied batch
if d.empty() { if d.empty() {
if key := d.state.String(); historyIndexCache.Contains(key) {
historyIndexCache.Remove(key)
}
if d.state.account { if d.state.account {
rawdb.DeleteAccountHistoryIndex(batch, d.state.addressHash) rawdb.DeleteAccountHistoryIndex(batch, d.state.addressHash)
} else { } else {
@ -455,6 +473,10 @@ func (d *indexDeleter) finish(batch ethdb.Batch) {
for _, desc := range d.descList { for _, desc := range d.descList {
buf = append(buf, desc.encode()...) buf = append(buf, desc.encode()...)
} }
if key := d.state.String(); historyIndexCache.Contains(key) {
historyIndexCache.Add(key, buf)
}
if d.state.account { if d.state.account {
rawdb.WriteAccountHistoryIndex(batch, d.state.addressHash, buf) rawdb.WriteAccountHistoryIndex(batch, d.state.addressHash, buf)
} else { } else {

View file

@ -34,6 +34,7 @@ import (
var ( var (
historyIndexCache = lru.NewCache[string, []byte](10000) historyIndexCache = lru.NewCache[string, []byte](10000)
historyBlockCache = lru.NewCache[string, []byte](10000)
) )
// stateIdent represents the identifier of a state element, which can be // stateIdent represents the identifier of a state element, which can be