mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-05-17 00:26:36 +03:00
lib/lrucache: sizeBytes should also include key length (#10679)
There are cases then the key sizeBytes is much greater than the value sizeBytes. Therefore it is important to include the key sizeBytes into the total. Also fix some code comments. Signed-off-by: Artem Fetishev <rtm@victoriametrics.com>
This commit is contained in:
@@ -15,6 +15,10 @@ import (
|
||||
|
||||
// Cache caches Entry entries.
|
||||
//
|
||||
// If the cache is full the least recently used entries are evicted to make room
|
||||
// for new entries. Additionally, entries are evicted if not retrieved within
|
||||
// the last three minutes.
|
||||
//
|
||||
// Call NewCache() for creating new Cache.
|
||||
type Cache struct {
|
||||
resets atomic.Uint64
|
||||
@@ -276,7 +280,7 @@ func (c *cache) PutEntry(k string, e Entry) {
|
||||
}
|
||||
heap.Push(&c.lah, ce)
|
||||
c.m[k] = ce
|
||||
c.updateSizeBytes(e.SizeBytes())
|
||||
c.updateSizeBytes(uint64(len(k)) + e.SizeBytes())
|
||||
maxSizeBytes := c.getMaxSizeBytes()
|
||||
for c.SizeBytes() > maxSizeBytes && len(c.lah) > 0 {
|
||||
c.removeLeastRecentlyAccessedItem()
|
||||
@@ -285,7 +289,7 @@ func (c *cache) PutEntry(k string, e Entry) {
|
||||
|
||||
func (c *cache) removeLeastRecentlyAccessedItem() {
|
||||
ce := c.lah[0]
|
||||
c.updateSizeBytes(-ce.e.SizeBytes())
|
||||
c.updateSizeBytes(-(uint64(len(ce.k)) + ce.e.SizeBytes()))
|
||||
delete(c.m, ce.k)
|
||||
heap.Pop(&c.lah)
|
||||
}
|
||||
@@ -341,7 +345,8 @@ func (lah *lastAccessHeap) Pop() any {
|
||||
h := *lah
|
||||
e := h[len(h)-1]
|
||||
|
||||
// Remove the reference to deleted entry, so Go GC could free up memory occupied by the deleted entry.
|
||||
// Remove the reference to deleted entry, so Go GC could free up memory
|
||||
// occupied by the deleted entry.
|
||||
h[len(h)-1] = nil
|
||||
|
||||
*lah = h[:len(h)-1]
|
||||
|
||||
@@ -31,14 +31,16 @@ func TestCache(t *testing.T) {
|
||||
}
|
||||
k := "foobar"
|
||||
var e testEntry
|
||||
keySize := uint64(len(k))
|
||||
entrySize := e.SizeBytes()
|
||||
keyEntrySize := keySize + entrySize
|
||||
// Put a single entry into cache
|
||||
c.PutEntry(k, &e)
|
||||
if n := c.Len(); n != 1 {
|
||||
t.Fatalf("unexpected number of items in the cache; got %d; want %d", n, 1)
|
||||
}
|
||||
if n := c.SizeBytes(); n != entrySize {
|
||||
t.Fatalf("unexpected SizeBytes(); got %d; want %d", n, entrySize)
|
||||
if n := c.SizeBytes(); n != keyEntrySize {
|
||||
t.Fatalf("unexpected SizeBytes(); got %d; want %d", n, keyEntrySize)
|
||||
}
|
||||
if n := c.Requests(); n != 0 {
|
||||
t.Fatalf("unexpected number of requests; got %d; want %d", n, 0)
|
||||
@@ -77,8 +79,8 @@ func TestCache(t *testing.T) {
|
||||
}
|
||||
// Store the entry again.
|
||||
c.PutEntry(k, &e)
|
||||
if n := c.SizeBytes(); n != entrySize {
|
||||
t.Fatalf("unexpected SizeBytes(); got %d; want %d", n, entrySize)
|
||||
if n := c.SizeBytes(); n != keyEntrySize {
|
||||
t.Fatalf("unexpected SizeBytes(); got %d; want %d", n, keyEntrySize)
|
||||
}
|
||||
if e1 := c.GetEntry(k); e1 != &e {
|
||||
t.Fatalf("unexpected entry obtained; got %v; want %v", e1, &e)
|
||||
@@ -95,8 +97,8 @@ func TestCache(t *testing.T) {
|
||||
|
||||
// Manually clean the cache. The entry shouldn't be deleted because it was recently accessed.
|
||||
c.cleanByTimeout()
|
||||
if n := c.SizeBytes(); n != entrySize {
|
||||
t.Fatalf("unexpected SizeBytes(); got %d; want %d", n, entrySize)
|
||||
if n := c.SizeBytes(); n != keyEntrySize {
|
||||
t.Fatalf("unexpected SizeBytes(); got %d; want %d", n, keyEntrySize)
|
||||
}
|
||||
|
||||
// Reset cache.
|
||||
|
||||
Reference in New Issue
Block a user