initial tests

This commit is contained in:
Karl Seguin 2013-10-19 20:36:33 +08:00
parent 97bc65dc6a
commit b3cbd19186
5 changed files with 97 additions and 17 deletions

View file

@ -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)

66
bucket_test.go Normal file
View file

@ -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()
}

View file

@ -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)
}
}

View file

@ -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
}

14
item_test.go Normal file
View file

@ -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)
}