mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
close evicted era files
This commit is contained in:
parent
930d969611
commit
01e48f3e19
4 changed files with 39 additions and 6 deletions
|
|
@ -22,9 +22,10 @@ package lru
|
||||||
// This type is not safe for concurrent use.
|
// This type is not safe for concurrent use.
|
||||||
// The zero value is not valid, instances must be created using NewCache.
|
// The zero value is not valid, instances must be created using NewCache.
|
||||||
type BasicLRU[K comparable, V any] struct {
|
type BasicLRU[K comparable, V any] struct {
|
||||||
list *list[K]
|
list *list[K]
|
||||||
items map[K]cacheItem[K, V]
|
items map[K]cacheItem[K, V]
|
||||||
cap int
|
cap int
|
||||||
|
onEvicted func(key K, value V)
|
||||||
}
|
}
|
||||||
|
|
||||||
type cacheItem[K any, V any] struct {
|
type cacheItem[K any, V any] struct {
|
||||||
|
|
@ -61,6 +62,10 @@ func (c *BasicLRU[K, V]) Add(key K, value V) (evicted bool) {
|
||||||
elem = c.list.removeLast()
|
elem = c.list.removeLast()
|
||||||
delete(c.items, elem.v)
|
delete(c.items, elem.v)
|
||||||
evicted = true
|
evicted = true
|
||||||
|
if c.onEvicted != nil {
|
||||||
|
v := c.items[elem.v]
|
||||||
|
c.onEvicted(elem.v, v.value)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
elem = new(listElem[K])
|
elem = new(listElem[K])
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +147,11 @@ func (c *BasicLRU[K, V]) RemoveOldest() (key K, value V, ok bool) {
|
||||||
return key, item.value, true
|
return key, item.value, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnEvicted sets a callback function to be called when an item is evicted from the cache.
|
||||||
|
func (c *BasicLRU[K, V]) OnEvicted(fn func(k K, v V)) {
|
||||||
|
c.onEvicted = fn
|
||||||
|
}
|
||||||
|
|
||||||
// Keys returns all keys in the cache.
|
// Keys returns all keys in the cache.
|
||||||
func (c *BasicLRU[K, V]) Keys() []K {
|
func (c *BasicLRU[K, V]) Keys() []K {
|
||||||
keys := make([]K, 0, len(c.items))
|
keys := make([]K, 0, len(c.items))
|
||||||
|
|
|
||||||
|
|
@ -93,3 +93,11 @@ func (c *Cache[K, V]) Keys() []K {
|
||||||
|
|
||||||
return c.cache.Keys()
|
return c.cache.Keys()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnEvicted sets a callback function to be called when an item is evicted from the cache.
|
||||||
|
func (c *Cache[K, V]) OnEvicted(fn func(key K, value V)) {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
c.cache.OnEvicted(fn)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,19 +61,32 @@ func New(datadir string) (*EraDatabase, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
db := &EraDatabase{datadir: datadir, cache: lru.NewCache[uint64, *era.Era](openFileLimit)}
|
db := &EraDatabase{datadir: datadir, cache: lru.NewCache[uint64, *era.Era](openFileLimit)}
|
||||||
|
db.cache.OnEvicted(func(key uint64, value *era.Era) {
|
||||||
|
// Close the era1 file when it is evicted from the cache
|
||||||
|
// to avoid leaks.
|
||||||
|
if value != nil {
|
||||||
|
if err := value.Close(); err != nil {
|
||||||
|
log.Warn("Error closing era1 file", "epoch", key, "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
log.Info("Opened erastore", "datadir", datadir)
|
log.Info("Opened erastore", "datadir", datadir)
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes all open era1 files in the cache.
|
// Close closes all open era1 files in the cache.
|
||||||
func (db *EraDatabase) Close() {
|
func (db *EraDatabase) Close() error {
|
||||||
// Close all open era1 files in the cache.
|
// Close all open era1 files in the cache.
|
||||||
keys := db.cache.Keys()
|
keys := db.cache.Keys()
|
||||||
|
errs := make([]error, len(keys))
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
if e, ok := db.cache.Get(key); ok {
|
if e, ok := db.cache.Get(key); ok {
|
||||||
e.Close()
|
if err := e.Close(); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawBody returns the raw body for a given block number.
|
// GetRawBody returns the raw body for a given block number.
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,9 @@ func (f *Freezer) Close() error {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
if f.eradb != nil {
|
if f.eradb != nil {
|
||||||
f.eradb.Close()
|
if err := f.eradb.Close(); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if errs != nil {
|
if errs != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue