Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

plumbing: cache, modify cache to delete more than one item to free space #720

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions plumbing/cache/object_lru.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,18 @@ 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 {
Copy link
Contributor

@ajnavarro ajnavarro Jan 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check if the object to add is bigger than the cache size to do not remove everything?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind, is already checked before the for.

last := c.ll.Back()
lastObj := last.Value.(plumbing.EncodedObject)
lastSize := FileSize(lastObj.Size())

c.ll.Remove(last)
delete(c.cache, lastObj.Hash())
c.actualSize -= lastSize

if c.actualSize+objSize > c.MaxSize {
return
}
}

ee := c.ll.PushFront(obj)
Expand Down
20 changes: 20 additions & 0 deletions plumbing/cache/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type ObjectSuite struct {
bObject plumbing.EncodedObject
cObject plumbing.EncodedObject
dObject plumbing.EncodedObject
eObject plumbing.EncodedObject
}

var _ = Suite(&ObjectSuite{})
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions plumbing/format/packfile/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down