Skip to content

Commit 3bd1a1a

Browse files
Add support for measuring key size in caches (#1781)
1 parent 1de061a commit 3bd1a1a

File tree

4 files changed

+51
-21
lines changed

4 files changed

+51
-21
lines changed

cache/lru_sized_cache.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ type sizedLRU[K comparable, V any] struct {
2020
elements linkedhashmap.LinkedHashmap[K, V]
2121
maxSize int
2222
currentSize int
23-
size func(V) int
23+
size func(K, V) int
2424
}
2525

26-
func NewSizedLRU[K comparable, V any](maxSize int, size func(V) int) Cacher[K, V] {
26+
func NewSizedLRU[K comparable, V any](maxSize int, size func(K, V) int) Cacher[K, V] {
2727
return &sizedLRU[K, V]{
2828
elements: linkedhashmap.New[K, V](),
2929
maxSize: maxSize,
@@ -67,25 +67,25 @@ func (c *sizedLRU[_, _]) PortionFilled() float64 {
6767
}
6868

6969
func (c *sizedLRU[K, V]) put(key K, value V) {
70-
valueSize := c.size(value)
71-
if valueSize > c.maxSize {
70+
newEntrySize := c.size(key, value)
71+
if newEntrySize > c.maxSize {
7272
c.flush()
7373
return
7474
}
7575

7676
if oldValue, ok := c.elements.Get(key); ok {
77-
c.currentSize -= c.size(oldValue)
77+
c.currentSize -= c.size(key, oldValue)
7878
}
7979

8080
// Remove elements until the size of elements in the cache <= [c.maxSize].
81-
for c.currentSize > c.maxSize-valueSize {
82-
oldestKey, value, _ := c.elements.Oldest()
81+
for c.currentSize > c.maxSize-newEntrySize {
82+
oldestKey, oldestValue, _ := c.elements.Oldest()
8383
c.elements.Delete(oldestKey)
84-
c.currentSize -= c.size(value)
84+
c.currentSize -= c.size(oldestKey, oldestValue)
8585
}
8686

8787
c.elements.Put(key, value)
88-
c.currentSize += valueSize
88+
c.currentSize += newEntrySize
8989
}
9090

9191
func (c *sizedLRU[K, V]) get(key K) (V, bool) {
@@ -101,7 +101,7 @@ func (c *sizedLRU[K, V]) get(key K) (V, bool) {
101101
func (c *sizedLRU[K, _]) evict(key K) {
102102
if value, ok := c.elements.Get(key); ok {
103103
c.elements.Delete(key)
104-
c.currentSize -= c.size(value)
104+
c.currentSize -= c.size(key, value)
105105
}
106106
}
107107

cache/lru_sized_cache_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package cache
66
import (
77
"testing"
88

9+
"github.com/stretchr/testify/require"
10+
911
"github.com/ava-labs/avalanchego/ids"
1012
)
1113

@@ -20,3 +22,31 @@ func TestSizedLRUEviction(t *testing.T) {
2022

2123
TestEviction(t, cache)
2224
}
25+
26+
func TestSizedLRUWrongKeyEvictionRegression(t *testing.T) {
27+
require := require.New(t)
28+
29+
cache := NewSizedLRU[string, struct{}](
30+
3,
31+
func(key string, _ struct{}) int {
32+
return len(key)
33+
},
34+
)
35+
36+
cache.Put("a", struct{}{})
37+
cache.Put("b", struct{}{})
38+
cache.Put("c", struct{}{})
39+
cache.Put("dd", struct{}{})
40+
41+
_, ok := cache.Get("a")
42+
require.False(ok)
43+
44+
_, ok = cache.Get("b")
45+
require.False(ok)
46+
47+
_, ok = cache.Get("c")
48+
require.True(ok)
49+
50+
_, ok = cache.Get("dd")
51+
require.True(ok)
52+
}

cache/test_cacher.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import (
1111
"github.com/ava-labs/avalanchego/ids"
1212
)
1313

14-
const TestIntSize = 8
14+
const TestIntSize = ids.IDLen + 8
1515

16-
func TestIntSizeFunc(int64) int {
16+
func TestIntSizeFunc(ids.ID, int64) int {
1717
return TestIntSize
1818
}
1919

vms/platformvm/state/state.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -381,25 +381,25 @@ type txAndStatus struct {
381381
status status.Status
382382
}
383383

384-
func txSize(tx *txs.Tx) int {
384+
func txSize(_ ids.ID, tx *txs.Tx) int {
385385
if tx == nil {
386-
return pointerOverhead
386+
return ids.IDLen + pointerOverhead
387387
}
388-
return len(tx.Bytes()) + pointerOverhead
388+
return ids.IDLen + len(tx.Bytes()) + pointerOverhead
389389
}
390390

391-
func txAndStatusSize(t *txAndStatus) int {
391+
func txAndStatusSize(_ ids.ID, t *txAndStatus) int {
392392
if t == nil {
393-
return pointerOverhead
393+
return ids.IDLen + pointerOverhead
394394
}
395-
return len(t.tx.Bytes()) + wrappers.IntLen + pointerOverhead
395+
return ids.IDLen + len(t.tx.Bytes()) + wrappers.IntLen + pointerOverhead
396396
}
397397

398-
func blockSize(blk blocks.Block) int {
398+
func blockSize(_ ids.ID, blk blocks.Block) int {
399399
if blk == nil {
400-
return pointerOverhead
400+
return ids.IDLen + pointerOverhead
401401
}
402-
return len(blk.Bytes()) + pointerOverhead
402+
return ids.IDLen + len(blk.Bytes()) + pointerOverhead
403403
}
404404

405405
func New(

0 commit comments

Comments
 (0)