aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/cache/buffer_test.go
diff options
context:
space:
mode:
authorJavi Fontan <jfontan@gmail.com>2018-08-14 11:59:11 +0200
committerJavi Fontan <jfontan@gmail.com>2018-08-14 13:24:51 +0200
commita8c4426d204f42e683e902dcb277494004d5e59d (patch)
treecdfe5c3ca9ee85931474f589120eb9a453085bab /plumbing/cache/buffer_test.go
parenta28c2ce44695f13ddf28748958f236afd8e0b544 (diff)
downloadgo-git-a8c4426d204f42e683e902dcb277494004d5e59d.tar.gz
plumbing: add buffer cache and use it in packfile parser
It uses less memory and is faster as slices don't have to be converted from/to MemoryObject and they are indexed by offset. Signed-off-by: Javi Fontan <jfontan@gmail.com>
Diffstat (limited to 'plumbing/cache/buffer_test.go')
-rw-r--r--plumbing/cache/buffer_test.go128
1 files changed, 128 insertions, 0 deletions
diff --git a/plumbing/cache/buffer_test.go b/plumbing/cache/buffer_test.go
new file mode 100644
index 0000000..262138a
--- /dev/null
+++ b/plumbing/cache/buffer_test.go
@@ -0,0 +1,128 @@
+package cache
+
+import (
+ "sync"
+
+ . "gopkg.in/check.v1"
+)
+
+type BufferSuite struct {
+ c map[string]Buffer
+ aBuffer []byte
+ bBuffer []byte
+ cBuffer []byte
+ dBuffer []byte
+ eBuffer []byte
+}
+
+var _ = Suite(&BufferSuite{})
+
+func (s *BufferSuite) SetUpTest(c *C) {
+ s.aBuffer = []byte("a")
+ s.bBuffer = []byte("bbb")
+ s.cBuffer = []byte("c")
+ s.dBuffer = []byte("d")
+ s.eBuffer = []byte("ee")
+
+ s.c = make(map[string]Buffer)
+ s.c["two_bytes"] = NewBufferLRU(2 * Byte)
+ s.c["default_lru"] = NewBufferLRUDefault()
+}
+
+func (s *BufferSuite) TestPutSameBuffer(c *C) {
+ for _, o := range s.c {
+ o.Put(1, s.aBuffer)
+ o.Put(1, s.aBuffer)
+ _, ok := o.Get(1)
+ c.Assert(ok, Equals, true)
+ }
+}
+
+func (s *BufferSuite) TestPutBigBuffer(c *C) {
+ for _, o := range s.c {
+ o.Put(1, s.bBuffer)
+ _, ok := o.Get(2)
+ c.Assert(ok, Equals, false)
+ }
+}
+
+func (s *BufferSuite) TestPutCacheOverflow(c *C) {
+ // this test only works with an specific size
+ o := s.c["two_bytes"]
+
+ o.Put(1, s.aBuffer)
+ o.Put(2, s.cBuffer)
+ o.Put(3, s.dBuffer)
+
+ obj, ok := o.Get(1)
+ c.Assert(ok, Equals, false)
+ c.Assert(obj, IsNil)
+ obj, ok = o.Get(2)
+ c.Assert(ok, Equals, true)
+ c.Assert(obj, NotNil)
+ obj, ok = o.Get(3)
+ c.Assert(ok, Equals, true)
+ c.Assert(obj, NotNil)
+}
+
+func (s *BufferSuite) TestEvictMultipleBuffers(c *C) {
+ o := s.c["two_bytes"]
+
+ o.Put(1, s.cBuffer)
+ o.Put(2, s.dBuffer) // now cache is full with two objects
+ o.Put(3, s.eBuffer) // this put should evict all previous objects
+
+ obj, ok := o.Get(1)
+ c.Assert(ok, Equals, false)
+ c.Assert(obj, IsNil)
+ obj, ok = o.Get(2)
+ c.Assert(ok, Equals, false)
+ c.Assert(obj, IsNil)
+ obj, ok = o.Get(3)
+ c.Assert(ok, Equals, true)
+ c.Assert(obj, NotNil)
+}
+
+func (s *BufferSuite) TestClear(c *C) {
+ for _, o := range s.c {
+ o.Put(1, s.aBuffer)
+ o.Clear()
+ obj, ok := o.Get(1)
+ c.Assert(ok, Equals, false)
+ c.Assert(obj, IsNil)
+ }
+}
+
+func (s *BufferSuite) TestConcurrentAccess(c *C) {
+ for _, o := range s.c {
+ var wg sync.WaitGroup
+
+ for i := 0; i < 1000; i++ {
+ wg.Add(3)
+ go func(i int) {
+ o.Put(int64(i), []byte{00})
+ wg.Done()
+ }(i)
+
+ go func(i int) {
+ if i%30 == 0 {
+ o.Clear()
+ }
+ wg.Done()
+ }(i)
+
+ go func(i int) {
+ o.Get(int64(i))
+ wg.Done()
+ }(i)
+ }
+
+ wg.Wait()
+ }
+}
+
+func (s *BufferSuite) TestDefaultLRU(c *C) {
+ defaultLRU := s.c["default_lru"].(*BufferLRU)
+
+ c.Assert(defaultLRU.MaxSize, Equals, DefaultMaxSize)
+}