From 5b1cde56bde4834805b14f1613e8f7fda1703bf8 Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Tue, 16 Jan 2018 11:48:12 +0000 Subject: [PATCH 1/3] Modify cache to delete more than one item to free space The previous version could only delete the oldest used object. If the object to cache was bigger than the space freed it could not be added. Also the decoder adds bases to the cache when they are needed. This change increases the speed creating indexes 2x. Signed-off-by: Javi Fontan --- plumbing/cache/object_lru.go | 6 +----- plumbing/format/packfile/decoder.go | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/plumbing/cache/object_lru.go b/plumbing/cache/object_lru.go index d99a5c92a..9e850b25e 100644 --- a/plumbing/cache/object_lru.go +++ b/plumbing/cache/object_lru.go @@ -55,7 +55,7 @@ func (c *ObjectLRU) Put(obj plumbing.EncodedObject) { 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/format/packfile/decoder.go b/plumbing/format/packfile/decoder.go index cb787017c..f706e5d84 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()) From c281165b48d9901d391c583b6d7c28d37edb4ff5 Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Tue, 16 Jan 2018 13:11:57 +0000 Subject: [PATCH 2/3] Cache should hold objects the same size as MaxSize Signed-off-by: Javi Fontan --- plumbing/cache/object_lru.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plumbing/cache/object_lru.go b/plumbing/cache/object_lru.go index 9e850b25e..049453950 100644 --- a/plumbing/cache/object_lru.go +++ b/plumbing/cache/object_lru.go @@ -51,7 +51,7 @@ func (c *ObjectLRU) Put(obj plumbing.EncodedObject) { objSize := FileSize(obj.Size()) - if objSize >= c.MaxSize { + if objSize > c.MaxSize { return } From 0f6c06db068acb7a8eab639df20b72fa717232c8 Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Tue, 16 Jan 2018 13:12:58 +0000 Subject: [PATCH 3/3] Test eviction of more than one object Signed-off-by: Javi Fontan --- plumbing/cache/object_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plumbing/cache/object_test.go b/plumbing/cache/object_test.go index ec01d6022..ac3f0a3f6 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)