package cache import ( "bytes" "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 *ObjectSuite) TestPutSameBufferWithDifferentSize(c *C) { aBuffer := []byte("a") bBuffer := []byte("bbb") cBuffer := []byte("ccccc") dBuffer := []byte("ddddddd") cache := NewBufferLRU(7 * Byte) cache.Put(1, aBuffer) cache.Put(1, bBuffer) cache.Put(1, cBuffer) cache.Put(1, dBuffer) c.Assert(cache.MaxSize, Equals, 7*Byte) c.Assert(cache.actualSize, Equals, 7*Byte) c.Assert(cache.ll.Len(), Equals, 1) buf, ok := cache.Get(1) c.Assert(bytes.Equal(buf, dBuffer), Equals, true) c.Assert(FileSize(len(buf)), Equals, 7*Byte) 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) }