diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-12-20 19:11:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-20 19:11:16 +0100 |
commit | 50725139e8b96f88d74e253c8312fd4864640771 (patch) | |
tree | 70d0c7ce9b0d9201a3e94b19948d14b815337c76 /plumbing/cache | |
parent | ca59809a0c74f6af498347a102a64242e26b0ab0 (diff) | |
parent | e39559fba6ea936c5f4659c03c22f9a5a256a4d7 (diff) | |
download | go-git-50725139e8b96f88d74e253c8312fd4864640771.tar.gz |
Merge pull request #698 from jfontan/improvement/use-decoder-cache
plumbing: cache, enforce the use of cache in packfile decoder
Diffstat (limited to 'plumbing/cache')
-rw-r--r-- | plumbing/cache/common.go | 2 | ||||
-rw-r--r-- | plumbing/cache/object_lru.go | 5 | ||||
-rw-r--r-- | plumbing/cache/object_test.go | 101 |
3 files changed, 67 insertions, 41 deletions
diff --git a/plumbing/cache/common.go b/plumbing/cache/common.go index 9efc26c..e77baf0 100644 --- a/plumbing/cache/common.go +++ b/plumbing/cache/common.go @@ -11,6 +11,8 @@ const ( type FileSize int64 +const DefaultMaxSize FileSize = 96 * MiByte + // Object is an interface to a object cache. type Object interface { // Put puts the given object into the cache. Whether this object will diff --git a/plumbing/cache/object_lru.go b/plumbing/cache/object_lru.go index e8414ab..d99a5c9 100644 --- a/plumbing/cache/object_lru.go +++ b/plumbing/cache/object_lru.go @@ -24,6 +24,11 @@ func NewObjectLRU(maxSize FileSize) *ObjectLRU { return &ObjectLRU{MaxSize: maxSize} } +// NewObjectLRUDefault creates a new ObjectLRU with the default cache size. +func NewObjectLRUDefault() *ObjectLRU { + return &ObjectLRU{MaxSize: DefaultMaxSize} +} + // Put puts an object into the cache. If the object is already in the cache, it // will be marked as used. Otherwise, it will be inserted. A single object might // be evicted to make room for the new object. diff --git a/plumbing/cache/object_test.go b/plumbing/cache/object_test.go index b38272f..ec01d60 100644 --- a/plumbing/cache/object_test.go +++ b/plumbing/cache/object_test.go @@ -14,7 +14,7 @@ import ( func Test(t *testing.T) { TestingT(t) } type ObjectSuite struct { - c Object + c map[string]Object aObject plumbing.EncodedObject bObject plumbing.EncodedObject cObject plumbing.EncodedObject @@ -29,70 +29,89 @@ func (s *ObjectSuite) SetUpTest(c *C) { s.cObject = newObject("cccccccccccccccccccccccccccccccccccccccc", 1*Byte) s.dObject = newObject("dddddddddddddddddddddddddddddddddddddddd", 1*Byte) - s.c = NewObjectLRU(2 * Byte) + s.c = make(map[string]Object) + s.c["two_bytes"] = NewObjectLRU(2 * Byte) + s.c["default_lru"] = NewObjectLRUDefault() } func (s *ObjectSuite) TestPutSameObject(c *C) { - s.c.Put(s.aObject) - s.c.Put(s.aObject) - _, ok := s.c.Get(s.aObject.Hash()) - c.Assert(ok, Equals, true) + for _, o := range s.c { + o.Put(s.aObject) + o.Put(s.aObject) + _, ok := o.Get(s.aObject.Hash()) + c.Assert(ok, Equals, true) + } } func (s *ObjectSuite) TestPutBigObject(c *C) { - s.c.Put(s.bObject) - _, ok := s.c.Get(s.aObject.Hash()) - c.Assert(ok, Equals, false) + for _, o := range s.c { + o.Put(s.bObject) + _, ok := o.Get(s.aObject.Hash()) + c.Assert(ok, Equals, false) + } } func (s *ObjectSuite) TestPutCacheOverflow(c *C) { - s.c.Put(s.aObject) - s.c.Put(s.cObject) - s.c.Put(s.dObject) + // this test only works with an specific size + o := s.c["two_bytes"] + + o.Put(s.aObject) + o.Put(s.cObject) + o.Put(s.dObject) - obj, ok := s.c.Get(s.aObject.Hash()) + obj, ok := o.Get(s.aObject.Hash()) c.Assert(ok, Equals, false) c.Assert(obj, IsNil) - obj, ok = s.c.Get(s.cObject.Hash()) + obj, ok = o.Get(s.cObject.Hash()) c.Assert(ok, Equals, true) c.Assert(obj, NotNil) - obj, ok = s.c.Get(s.dObject.Hash()) + obj, ok = o.Get(s.dObject.Hash()) c.Assert(ok, Equals, true) c.Assert(obj, NotNil) } func (s *ObjectSuite) TestClear(c *C) { - s.c.Put(s.aObject) - s.c.Clear() - obj, ok := s.c.Get(s.aObject.Hash()) - c.Assert(ok, Equals, false) - c.Assert(obj, IsNil) + for _, o := range s.c { + o.Put(s.aObject) + o.Clear() + obj, ok := o.Get(s.aObject.Hash()) + c.Assert(ok, Equals, false) + c.Assert(obj, IsNil) + } } func (s *ObjectSuite) TestConcurrentAccess(c *C) { - var wg sync.WaitGroup - - for i := 0; i < 1000; i++ { - wg.Add(3) - go func(i int) { - s.c.Put(newObject(fmt.Sprint(i), FileSize(i))) - wg.Done() - }(i) - - go func(i int) { - if i%30 == 0 { - s.c.Clear() - } - wg.Done() - }(i) - - go func(i int) { - s.c.Get(plumbing.NewHash(fmt.Sprint(i))) - wg.Done() - }(i) + for _, o := range s.c { + var wg sync.WaitGroup + + for i := 0; i < 1000; i++ { + wg.Add(3) + go func(i int) { + o.Put(newObject(fmt.Sprint(i), FileSize(i))) + wg.Done() + }(i) + + go func(i int) { + if i%30 == 0 { + o.Clear() + } + wg.Done() + }(i) + + go func(i int) { + o.Get(plumbing.NewHash(fmt.Sprint(i))) + wg.Done() + }(i) + } + + wg.Wait() } +} + +func (s *ObjectSuite) TestDefaultLRU(c *C) { + defaultLRU := s.c["default_lru"].(*ObjectLRU) - wg.Wait() + c.Assert(defaultLRU.MaxSize, Equals, DefaultMaxSize) } type dummyObject struct { |