diff options
-rw-r--r-- | plumbing/cache/object_lru.go | 8 | ||||
-rw-r--r-- | plumbing/cache/object_test.go | 20 | ||||
-rw-r--r-- | plumbing/format/packfile/decoder.go | 2 |
3 files changed, 24 insertions, 6 deletions
diff --git a/plumbing/cache/object_lru.go b/plumbing/cache/object_lru.go index d99a5c9..0494539 100644 --- a/plumbing/cache/object_lru.go +++ b/plumbing/cache/object_lru.go @@ -51,11 +51,11 @@ func (c *ObjectLRU) Put(obj plumbing.EncodedObject) { objSize := FileSize(obj.Size()) - if objSize >= c.MaxSize { + if objSize > c.MaxSize { return } - if c.actualSize+objSize > c.MaxSize { + for c.actualSize+objSize > c.MaxSize { last := c.ll.Back() lastObj := last.Value.(plumbing.EncodedObject) lastSize := FileSize(lastObj.Size()) @@ -63,10 +63,6 @@ func (c *ObjectLRU) Put(obj plumbing.EncodedObject) { c.ll.Remove(last) delete(c.cache, lastObj.Hash()) c.actualSize -= lastSize - - if c.actualSize+objSize > c.MaxSize { - return - } } ee := c.ll.PushFront(obj) diff --git a/plumbing/cache/object_test.go b/plumbing/cache/object_test.go index ec01d60..ac3f0a3 100644 --- a/plumbing/cache/object_test.go +++ b/plumbing/cache/object_test.go @@ -19,6 +19,7 @@ type ObjectSuite struct { bObject plumbing.EncodedObject cObject plumbing.EncodedObject dObject plumbing.EncodedObject + eObject plumbing.EncodedObject } var _ = Suite(&ObjectSuite{}) @@ -28,6 +29,7 @@ func (s *ObjectSuite) SetUpTest(c *C) { s.bObject = newObject("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 3*Byte) s.cObject = newObject("cccccccccccccccccccccccccccccccccccccccc", 1*Byte) s.dObject = newObject("dddddddddddddddddddddddddddddddddddddddd", 1*Byte) + s.eObject = newObject("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", 2*Byte) s.c = make(map[string]Object) s.c["two_bytes"] = NewObjectLRU(2 * Byte) @@ -70,6 +72,24 @@ func (s *ObjectSuite) TestPutCacheOverflow(c *C) { c.Assert(obj, NotNil) } +func (s *ObjectSuite) TestEvictMultipleObjects(c *C) { + o := s.c["two_bytes"] + + o.Put(s.cObject) + o.Put(s.dObject) // now cache is full with two objects + o.Put(s.eObject) // this put should evict all previous objects + + obj, ok := o.Get(s.cObject.Hash()) + c.Assert(ok, Equals, false) + c.Assert(obj, IsNil) + obj, ok = o.Get(s.dObject.Hash()) + c.Assert(ok, Equals, false) + c.Assert(obj, IsNil) + obj, ok = o.Get(s.eObject.Hash()) + c.Assert(ok, Equals, true) + c.Assert(obj, NotNil) +} + func (s *ObjectSuite) TestClear(c *C) { for _, o := range s.c { o.Put(s.aObject) diff --git a/plumbing/format/packfile/decoder.go b/plumbing/format/packfile/decoder.go index cb78701..f706e5d 100644 --- a/plumbing/format/packfile/decoder.go +++ b/plumbing/format/packfile/decoder.go @@ -407,6 +407,8 @@ func (d *Decoder) fillOFSDeltaObjectContent(obj plumbing.EncodedObject, offset i if err != nil { return 0, err } + + d.cachePut(base) } obj.SetType(base.Type()) |