aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plumbing/cache/object_lru.go8
-rw-r--r--plumbing/cache/object_test.go20
-rw-r--r--plumbing/format/packfile/decoder.go2
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())