added non-threadsafe Clear (for tests), fixed Fetch

This commit is contained in:
Karl Seguin 2013-10-31 11:45:22 +08:00
parent ba89971ba8
commit 3fa767d9ff
2 changed files with 22 additions and 6 deletions

View file

@ -45,3 +45,9 @@ func (b *Bucket) getAndDelete(key string) *Item{
delete(b.lookup, key) delete(b.lookup, key)
return item return item
} }
func (b *Bucket) clear() {
b.Lock()
defer b.Unlock()
b.lookup = make(map[string]*Item)
}

View file

@ -18,7 +18,7 @@ type Cache struct {
func New(config *Configuration) *Cache { func New(config *Configuration) *Cache {
c := &Cache{ c := &Cache{
list: new(list.List), list: list.New(),
Configuration: config, Configuration: config,
bucketCount: uint32(config.buckets), bucketCount: uint32(config.buckets),
buckets: make([]*Bucket, config.buckets), buckets: make([]*Bucket, config.buckets),
@ -51,12 +51,14 @@ func (c *Cache) Set(key string, value interface{}, duration time.Duration) {
c.promote(item) c.promote(item)
} }
func (c *Cache) Fetch(key string, duration time.Duration, fetch func() interface{}) interface{} { func (c *Cache) Fetch(key string, duration time.Duration, fetch func() (interface{}, error)) (interface{}, error) {
item := c.Get(key) item := c.Get(key)
if item != nil { return item } if item != nil { return item, nil }
value := fetch() value, err := fetch()
c.Set(key, value, duration) if err == nil {
return value c.Set(key, value, duration)
}
return value, err
} }
func (c *Cache) Delete(key string) { func (c *Cache) Delete(key string) {
@ -66,6 +68,14 @@ func (c *Cache) Delete(key string) {
} }
} }
//this isn't thread safe. It's meant to be called from non-concurrent tests
func (c *Cache) Clear() {
for _, bucket := range c.buckets {
bucket.clear()
}
c.list = list.New()
}
func (c *Cache) deleteItem(bucket *Bucket, item *Item) { func (c *Cache) deleteItem(bucket *Bucket, item *Item) {
bucket.delete(item.key) //stop othe GETs from getting it bucket.delete(item.key) //stop othe GETs from getting it
c.deletables <- item c.deletables <- item