From b3cbd1918628995a97c365061ccf3c7db3a027e5 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sat, 19 Oct 2013 20:36:33 +0800 Subject: [PATCH] initial tests --- bucket.go | 6 ++--- bucket_test.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ cache.go | 6 ++--- configuration.go | 22 ++++++++-------- item_test.go | 14 ++++++++++ 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 bucket_test.go create mode 100644 item_test.go diff --git a/bucket.go b/bucket.go index 6cf9562..06d5002 100755 --- a/bucket.go +++ b/bucket.go @@ -9,13 +9,13 @@ type Bucket struct { lookup map[string]*Item } -func (b *Bucket) Get(key string) *Item { +func (b *Bucket) get(key string) *Item { b.RLock() defer b.RUnlock() return b.lookup[key] } -func (b *Bucket) Set(key string, value Value) *Item { +func (b *Bucket) set(key string, value Value) *Item { b.Lock() defer b.Unlock() if existing, exists := b.lookup[key]; exists { @@ -30,7 +30,7 @@ func (b *Bucket) Set(key string, value Value) *Item { } -func (b *Bucket) Remove(key string) { +func (b *Bucket) remove(key string) { b.Lock() defer b.Unlock() delete(b.lookup, key) diff --git a/bucket_test.go b/bucket_test.go new file mode 100644 index 0000000..7ee4db5 --- /dev/null +++ b/bucket_test.go @@ -0,0 +1,66 @@ +package ccache + +import ( + "time" + "testing" + "github.com/karlseguin/gspec" +) + +func TestGetMissFromBucket(t *testing.T) { + bucket := testBucket() + gspec.New(t).Expect(bucket.get("invalid")).ToBeNil() +} + +func TestGetHitFromBucket(t *testing.T) { + bucket := testBucket() + item := bucket.get("power") + assertValue(t, item, "9000") +} + +func TestRemovesItemFromBucket(t *testing.T) { + bucket := testBucket() + bucket.remove("power") + gspec.New(t).Expect(bucket.get("power")).ToBeNil() +} + +func TestSetsANewBucketItem(t *testing.T) { + bucket := testBucket() + item := bucket.set("spice", newTestValue("flow")) + assertValue(t, item, "flow") + item = bucket.get("spice") + assertValue(t, item, "flow") +} + +func TestSetsAnExistingItem(t *testing.T) { + bucket := testBucket() + item := bucket.set("power", newTestValue("9002")) + assertValue(t, item, "9002") + item = bucket.get("power") + assertValue(t, item, "9002") +} + +func testBucket() *Bucket { + b := &Bucket{lookup: make(map[string]*Item),} + b.lookup["power"] = &Item{ + key: "power", + value: newTestValue("9000"), + } + return b +} + +func assertValue(t *testing.T, item *Item, expected string) { + value := item.value.(*TestValue) + gspec.New(t).Expect(value.v).ToEqual(expected) +} + +type TestValue struct { + v string +} + +func newTestValue(v string) *TestValue { + return &TestValue{v: v,} +} + +func (v *TestValue) Expires() time.Time { + return time.Now() +} diff --git a/cache.go b/cache.go index 019a6f9..ebadb38 100755 --- a/cache.go +++ b/cache.go @@ -37,14 +37,14 @@ func New(config *Configuration) *Cache { } func (c *Cache) Get(key string) Value { - item := c.bucket(key).Get(key) + item := c.bucket(key).get(key) if item == nil { return nil } c.promote(item) return item.value } func (c *Cache) Set(key string, value Value) { - item := c.bucket(key).Set(key, value) + item := c.bucket(key).set(key, value) c.promote(item) } @@ -89,7 +89,7 @@ func (c *Cache) gc() { element := c.list.Back() if element == nil { return } item := element.Value.(*Item) - c.bucket(item.key).Remove(item.key) + c.bucket(item.key).remove(item.key) c.list.Remove(element) } } diff --git a/configuration.go b/configuration.go index ad32b98..6088688 100755 --- a/configuration.go +++ b/configuration.go @@ -17,16 +17,26 @@ func Configure() *Configuration { buckets: 64, itemsToPrune: 500, promoteBuffer: 1024, - size: 500 * 1024 * 1024, //500MB + size: 500 * 1024 * 1024, promoteDelay: time.Minute * -5, } } +func (c *Configuration) Size(bytes uint64) *Configuration { + c.size = bytes + return c +} + func (c *Configuration) Buckets(count int) *Configuration { c.buckets = count return c } +func (c *Configuration) ItemsToPrune(count int) *Configuration { + c.itemsToPrune = count + return c +} + func (c *Configuration) PromoteBuffer(size int) *Configuration { c.promoteBuffer = size return c @@ -36,13 +46,3 @@ func (c *Configuration) PromoteDelay(delay time.Duration) *Configuration { c.promoteDelay = -delay return c } - -func (c *Configuration) Size(bytes uint64) *Configuration { - c.size = bytes - return c -} - -func (c *Configuration) ItemsToPrune(count int) *Configuration { - c.itemsToPrune = count - return c -} diff --git a/item_test.go b/item_test.go new file mode 100644 index 0000000..9921745 --- /dev/null +++ b/item_test.go @@ -0,0 +1,14 @@ +package ccache + +import ( + "time" + "testing" + "github.com/karlseguin/gspec" +) + +func TestItemPromotability(t *testing.T) { + spec := gspec.New(t) + item := &Item{promoted: time.Now().Add(time.Second * -5)} + spec.Expect(item.shouldPromote(time.Second * -2)).ToEqual(true) + spec.Expect(item.shouldPromote(time.Second * -6)).ToEqual(false) +}