mirror of
https://github.com/restic/restic.git
synced 2025-01-03 13:45:20 +00:00
Check cap instead of len in bloblru
restic dump uses bloblru.Cache to keep buffers alive, but also reuses evicted buffers. That means large buffers may be used to store small blobs, causing the cache to think it's using less memory than it actually does.
This commit is contained in:
parent
1ebcb1d097
commit
634a9c162d
2 changed files with 9 additions and 7 deletions
|
@ -47,7 +47,7 @@ func New(size int) *Cache {
|
||||||
func (c *Cache) Add(id restic.ID, blob []byte) (old []byte) {
|
func (c *Cache) Add(id restic.ID, blob []byte) (old []byte) {
|
||||||
debug.Log("bloblru.Cache: add %v", id)
|
debug.Log("bloblru.Cache: add %v", id)
|
||||||
|
|
||||||
size := len(blob) + overhead
|
size := cap(blob) + overhead
|
||||||
if size > c.size {
|
if size > c.size {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ func (c *Cache) Add(id restic.ID, blob []byte) (old []byte) {
|
||||||
for size > c.free {
|
for size > c.free {
|
||||||
_, val, _ := c.c.RemoveOldest()
|
_, val, _ := c.c.RemoveOldest()
|
||||||
b := val.([]byte)
|
b := val.([]byte)
|
||||||
if len(b) > len(old) {
|
if cap(b) > cap(old) {
|
||||||
// We can only return one buffer, so pick the largest.
|
// We can only return one buffer, so pick the largest.
|
||||||
old = b
|
old = b
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,6 @@ func (c *Cache) Get(id restic.ID) ([]byte, bool) {
|
||||||
|
|
||||||
func (c *Cache) evict(key, value interface{}) {
|
func (c *Cache) evict(key, value interface{}) {
|
||||||
blob := value.([]byte)
|
blob := value.([]byte)
|
||||||
debug.Log("bloblru.Cache: evict %v, %d bytes", key, len(blob))
|
debug.Log("bloblru.Cache: evict %v, %d bytes", key, cap(blob))
|
||||||
c.free += len(blob) + overhead
|
c.free += cap(blob) + overhead
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,11 @@ func TestCache(t *testing.T) {
|
||||||
rtest.Equals(t, exp, blob)
|
rtest.Equals(t, exp, blob)
|
||||||
}
|
}
|
||||||
|
|
||||||
addAndCheck(id1, make([]byte, 32*kiB))
|
// Our blobs have len 1 but larger cap. The cache should check the cap,
|
||||||
addAndCheck(id2, make([]byte, 30*kiB))
|
// since it more reliably indicates the amount of memory kept alive.
|
||||||
addAndCheck(id3, make([]byte, 10*kiB))
|
addAndCheck(id1, make([]byte, 1, 32*kiB))
|
||||||
|
addAndCheck(id2, make([]byte, 1, 30*kiB))
|
||||||
|
addAndCheck(id3, make([]byte, 1, 10*kiB))
|
||||||
|
|
||||||
_, ok := c.Get(id2)
|
_, ok := c.Get(id2)
|
||||||
rtest.Assert(t, ok, "blob %v not present", id2)
|
rtest.Assert(t, ok, "blob %v not present", id2)
|
||||||
|
|
Loading…
Reference in a new issue