switched from gspec -> expect
This commit is contained in:
parent
a81a0f665c
commit
967200d7bc
5 changed files with 77 additions and 64 deletions
|
@ -1,46 +1,51 @@
|
|||
package ccache
|
||||
|
||||
import (
|
||||
"github.com/karlseguin/gspec"
|
||||
. "github.com/karlseguin/expect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestGetMissFromBucket(t *testing.T) {
|
||||
bucket := testBucket()
|
||||
gspec.New(t).Expect(bucket.get("invalid")).ToBeNil()
|
||||
type BucketTests struct {
|
||||
}
|
||||
|
||||
func TestGetHitFromBucket(t *testing.T) {
|
||||
func Tests_Bucket(t *testing.T) {
|
||||
Expectify(new(BucketTests), t)
|
||||
}
|
||||
|
||||
func (b *BucketTests) GetMissFromBucket() {
|
||||
bucket := testBucket()
|
||||
Expect(bucket.get("invalid")).To.Equal(nil)
|
||||
}
|
||||
|
||||
func (b *BucketTests) GetHitFromBucket() {
|
||||
bucket := testBucket()
|
||||
item := bucket.get("power")
|
||||
assertValue(t, item, "9000")
|
||||
assertValue(item, "9000")
|
||||
}
|
||||
|
||||
func TestDeleteItemFromBucket(t *testing.T) {
|
||||
func (b *BucketTests) DeleteItemFromBucket() {
|
||||
bucket := testBucket()
|
||||
bucket.delete("power")
|
||||
gspec.New(t).Expect(bucket.get("power")).ToBeNil()
|
||||
Expect(bucket.get("power")).To.Equal(nil)
|
||||
}
|
||||
|
||||
func TestSetsANewBucketItem(t *testing.T) {
|
||||
spec := gspec.New(t)
|
||||
func (b *BucketTests) SetsANewBucketItem() {
|
||||
bucket := testBucket()
|
||||
item, new := bucket.set("spice", TestValue("flow"), time.Minute)
|
||||
assertValue(t, item, "flow")
|
||||
assertValue(item, "flow")
|
||||
item = bucket.get("spice")
|
||||
assertValue(t, item, "flow")
|
||||
spec.Expect(new).ToEqual(true)
|
||||
assertValue(item, "flow")
|
||||
Expect(new).To.Equal(true)
|
||||
}
|
||||
|
||||
func TestSetsAnExistingItem(t *testing.T) {
|
||||
spec := gspec.New(t)
|
||||
func (b *BucketTests) SetsAnExistingItem() {
|
||||
bucket := testBucket()
|
||||
item, new := bucket.set("power", TestValue("9002"), time.Minute)
|
||||
assertValue(t, item, "9002")
|
||||
assertValue(item, "9002")
|
||||
item = bucket.get("power")
|
||||
assertValue(t, item, "9002")
|
||||
spec.Expect(new).ToEqual(false)
|
||||
assertValue(item, "9002")
|
||||
Expect(new).To.Equal(false)
|
||||
}
|
||||
|
||||
func testBucket() *Bucket {
|
||||
|
@ -52,9 +57,9 @@ func testBucket() *Bucket {
|
|||
return b
|
||||
}
|
||||
|
||||
func assertValue(t *testing.T, item *Item, expected string) {
|
||||
func assertValue(item *Item, expected string) {
|
||||
value := item.value.(TestValue)
|
||||
gspec.New(t).Expect(value).ToEqual(TestValue(expected))
|
||||
Expect(value).To.Equal(TestValue(expected))
|
||||
}
|
||||
|
||||
type TestValue string
|
||||
|
|
7
cache.go
7
cache.go
|
@ -26,7 +26,7 @@ func New(config *Configuration) *Cache {
|
|||
deletables: make(chan *Item, config.deleteBuffer),
|
||||
promotables: make(chan *Item, config.promoteBuffer),
|
||||
}
|
||||
for i := 0; i < config.buckets; i++ {
|
||||
for i := 0; i < int(config.buckets); i++ {
|
||||
c.buckets[i] = &Bucket{
|
||||
lookup: make(map[string]*Item),
|
||||
}
|
||||
|
@ -109,8 +109,7 @@ func (c *Cache) deleteItem(bucket *Bucket, item *Item) {
|
|||
func (c *Cache) bucket(key string) *Bucket {
|
||||
h := fnv.New32a()
|
||||
h.Write([]byte(key))
|
||||
index := h.Sum32() % c.bucketCount
|
||||
return c.buckets[index]
|
||||
return c.buckets[h.Sum32()%c.bucketCount]
|
||||
}
|
||||
|
||||
func (c *Cache) conditionalPromote(item *Item) {
|
||||
|
@ -128,7 +127,7 @@ func (c *Cache) worker() {
|
|||
for {
|
||||
select {
|
||||
case item := <-c.promotables:
|
||||
if c.doPromote(item) && c.list.Len() > c.maxItems {
|
||||
if c.doPromote(item) && uint64(c.list.Len()) > c.maxItems {
|
||||
c.gc()
|
||||
}
|
||||
case item := <-c.deletables:
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
package ccache
|
||||
|
||||
import (
|
||||
"github.com/karlseguin/gspec"
|
||||
. "github.com/karlseguin/expect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCacheGCsTheOldestItems(t *testing.T) {
|
||||
spec := gspec.New(t)
|
||||
type CacheTests struct{}
|
||||
|
||||
func Test_Cache(t *testing.T) {
|
||||
Expectify(new(CacheTests), t)
|
||||
}
|
||||
|
||||
func (c *CacheTests) GCsTheOldestItems() {
|
||||
cache := New(Configure().ItemsToPrune(10))
|
||||
for i := 0; i < 500; i++ {
|
||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||
}
|
||||
//let the items get promoted (and added to our list)
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
cache.gc()
|
||||
spec.Expect(cache.Get("9")).ToBeNil()
|
||||
spec.Expect(cache.Get("10").(int)).ToEqual(10)
|
||||
Expect(cache.Get("9")).To.Equal(nil)
|
||||
Expect(cache.Get("10").(int)).To.Equal(10)
|
||||
}
|
||||
|
||||
func TestCachePromotedItemsDontGetPruned(t *testing.T) {
|
||||
spec := gspec.New(t)
|
||||
func (c *CacheTests) PromotedItemsDontGetPruned() {
|
||||
cache := New(Configure().ItemsToPrune(10).GetsPerPromote(1))
|
||||
for i := 0; i < 500; i++ {
|
||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||
|
@ -28,13 +34,12 @@ func TestCachePromotedItemsDontGetPruned(t *testing.T) {
|
|||
cache.Get("9")
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
cache.gc()
|
||||
spec.Expect(cache.Get("9").(int)).ToEqual(9)
|
||||
spec.Expect(cache.Get("10")).ToBeNil()
|
||||
spec.Expect(cache.Get("11").(int)).ToEqual(11)
|
||||
Expect(cache.Get("9").(int)).To.Equal(9)
|
||||
Expect(cache.Get("10")).To.Equal(nil)
|
||||
Expect(cache.Get("11").(int)).To.Equal(11)
|
||||
}
|
||||
|
||||
func TestCacheTrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
||||
spec := gspec.New(t)
|
||||
func (c *CacheTests) TrackerDoesNotCleanupHeldInstance() {
|
||||
cache := New(Configure().ItemsToPrune(10).Track())
|
||||
for i := 0; i < 10; i++ {
|
||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||
|
@ -42,21 +47,20 @@ func TestCacheTrackerDoesNotCleanupHeldInstance(t *testing.T) {
|
|||
item := cache.TrackingGet("0")
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
cache.gc()
|
||||
spec.Expect(cache.Get("0").(int)).ToEqual(0)
|
||||
spec.Expect(cache.Get("1")).ToBeNil()
|
||||
Expect(cache.Get("0").(int)).To.Equal(0)
|
||||
Expect(cache.Get("1")).To.Equal(nil)
|
||||
item.Release()
|
||||
cache.gc()
|
||||
spec.Expect(cache.Get("0")).ToBeNil()
|
||||
Expect(cache.Get("0")).To.Equal(nil)
|
||||
}
|
||||
|
||||
func TestCacheRemovesOldestItemWhenFull(t *testing.T) {
|
||||
spec := gspec.New(t)
|
||||
func (c *CacheTests) RemovesOldestItemWhenFull() {
|
||||
cache := New(Configure().MaxItems(5).ItemsToPrune(1))
|
||||
for i := 0; i < 7; i++ {
|
||||
cache.Set(strconv.Itoa(i), i, time.Minute)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
spec.Expect(cache.Get("0")).ToBeNil()
|
||||
spec.Expect(cache.Get("1")).ToBeNil()
|
||||
spec.Expect(cache.Get("2").(int)).ToEqual(2)
|
||||
Expect(cache.Get("0")).To.Equal(nil)
|
||||
Expect(cache.Get("1")).To.Equal(nil)
|
||||
Expect(cache.Get("2").(int)).To.Equal(2)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package ccache
|
||||
|
||||
type Configuration struct {
|
||||
maxItems int
|
||||
maxItems uint64
|
||||
buckets int
|
||||
itemsToPrune int
|
||||
deleteBuffer int
|
||||
|
@ -22,9 +22,9 @@ func Configure() *Configuration {
|
|||
}
|
||||
}
|
||||
|
||||
// The size, in bytes, of the data to cache
|
||||
// The max number of items to store in the cache
|
||||
// [5000]
|
||||
func (c *Configuration) MaxItems(max int) *Configuration {
|
||||
func (c *Configuration) MaxItems(max uint64) *Configuration {
|
||||
c.maxItems = max
|
||||
return c
|
||||
}
|
||||
|
@ -32,39 +32,39 @@ func (c *Configuration) MaxItems(max int) *Configuration {
|
|||
// Keys are hashed into % bucket count to provide greater concurrency (every set
|
||||
// requires a write lock on the bucket)
|
||||
// [64]
|
||||
func (c *Configuration) Buckets(count int) *Configuration {
|
||||
c.buckets = count
|
||||
func (c *Configuration) Buckets(count uint32) *Configuration {
|
||||
c.buckets = int(count)
|
||||
return c
|
||||
}
|
||||
|
||||
// The number of items to prune when memory is low
|
||||
// [500]
|
||||
func (c *Configuration) ItemsToPrune(count int) *Configuration {
|
||||
c.itemsToPrune = count
|
||||
func (c *Configuration) ItemsToPrune(count uint32) *Configuration {
|
||||
c.itemsToPrune = int(count)
|
||||
return c
|
||||
}
|
||||
|
||||
// The size of the queue for items which should be promoted. If the queue fills
|
||||
// up, promotions are skipped
|
||||
// [1024]
|
||||
func (c *Configuration) PromoteBuffer(size int) *Configuration {
|
||||
c.promoteBuffer = size
|
||||
func (c *Configuration) PromoteBuffer(size uint32) *Configuration {
|
||||
c.promoteBuffer = int(size)
|
||||
return c
|
||||
}
|
||||
|
||||
// The size of the queue for items which should be deleted. If the queue fills
|
||||
// up, calls to Delete() will block
|
||||
func (c *Configuration) DeleteBuffer(size int) *Configuration {
|
||||
c.deleteBuffer = size
|
||||
func (c *Configuration) DeleteBuffer(size uint32) *Configuration {
|
||||
c.deleteBuffer = int(size)
|
||||
return c
|
||||
}
|
||||
|
||||
// Give a large cache with a high read / write ratio, it's usually unecessary
|
||||
// to promote an item on every Get. GetsPerPromote specifies the number of Gets
|
||||
// a key must have before being promoted
|
||||
// [10]
|
||||
func (c *Configuration) GetsPerPromote(count int) *Configuration {
|
||||
c.getsPerPromote = int32(count)
|
||||
// [3]
|
||||
func (c *Configuration) GetsPerPromote(count int32) *Configuration {
|
||||
c.getsPerPromote = count
|
||||
return c
|
||||
}
|
||||
|
||||
|
|
17
item_test.go
17
item_test.go
|
@ -1,13 +1,18 @@
|
|||
package ccache
|
||||
|
||||
import (
|
||||
"github.com/karlseguin/gspec"
|
||||
. "github.com/karlseguin/expect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestItemPromotability(t *testing.T) {
|
||||
spec := gspec.New(t)
|
||||
item := &Item{promotions: 4}
|
||||
spec.Expect(item.shouldPromote(5)).ToEqual(true)
|
||||
spec.Expect(item.shouldPromote(5)).ToEqual(false)
|
||||
type ItemTests struct{}
|
||||
|
||||
func Test_Item(t *testing.T) {
|
||||
Expectify(new(ItemTests), t)
|
||||
}
|
||||
|
||||
func (i *ItemTests) Promotability() {
|
||||
item := &Item{promotions: 4}
|
||||
Expect(item.shouldPromote(5)).To.Equal(true)
|
||||
Expect(item.shouldPromote(5)).To.Equal(false)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue