From c6060554ee2379f6d78aee8b75c671a57d7bf0a5 Mon Sep 17 00:00:00 2001 From: Patrick Mylund Nielsen Date: Wed, 4 Jan 2012 08:07:50 +0100 Subject: [PATCH] Back to following weekly --- cache.go | 43 +++++++++++++++++++++---------------------- cache_test.go | 21 ++++++--------------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/cache.go b/cache.go index 2c495d6..04978df 100644 --- a/cache.go +++ b/cache.go @@ -2,7 +2,6 @@ package cache import ( "fmt" - "os" "reflect" "runtime" "sync" @@ -92,7 +91,7 @@ type Cache struct { } type cache struct { - DefaultExpiration int64 + DefaultExpiration time.Duration Items map[string]*Item mu *sync.Mutex janitor *janitor @@ -100,26 +99,26 @@ type cache struct { type Item struct { Object interface{} - Expiration *int64 + Expiration *time.Time } type janitor struct { - Interval int64 + Interval time.Duration stop chan bool } // Adds an item to the cache, replacing any existing item. If the duration is 0, the // cache's default expiration time is used. If it is -1, the item never expires. -func (c *cache) Set(k string, x interface{}, d int64) { +func (c *cache) Set(k string, x interface{}, d time.Duration) { c.mu.Lock() defer c.mu.Unlock() - var e *int64 + var e *time.Time if d == 0 { d = c.DefaultExpiration } if d > 0 { - t := time.Nanoseconds() + d + t := time.Now().Add(d) e = &t } c.Items[k] = &Item{ @@ -131,8 +130,8 @@ func (c *cache) Set(k string, x interface{}, d int64) { // TODO: Add and Replace aren't completely atomic // Adds an item to the cache only if an item doesn't already exist for the given key, -// or if the existing item has expired. Returns an os.Error if not. -func (c *cache) Add(k string, x interface{}, d int64) os.Error { +// or if the existing item has expired. Returns an error if not. +func (c *cache) Add(k string, x interface{}, d time.Duration) error { _, found := c.Get(k) if found { return fmt.Errorf("Item %s already exists", k) @@ -141,9 +140,9 @@ func (c *cache) Add(k string, x interface{}, d int64) os.Error { return nil } -// Sets a new value for the cache item only if it already exists. Returns an os.Error if +// Sets a new value for the cache item only if it already exists. Returns an error if // it does not. -func (c *cache) Replace(k string, x interface{}, d int64) os.Error { +func (c *cache) Replace(k string, x interface{}, d time.Duration) error { _, found := c.Get(k) if !found { return fmt.Errorf("Item %s doesn't exist", k) @@ -163,17 +162,17 @@ func (c *cache) Get(k string) (interface{}, bool) { return nil, false } if item.Expired() { - c.Items[k] = nil, false + delete(c.Items, k) return nil, false } return item.Object, true } // Increment an item of type int, int8, int16, int32, int64, uintptr, uint, uint8, -// uint32, uint64, float32 or float64 by n. Returns an os.Error if the item's value is +// uint32, uint64, float32 or float64 by n. Returns an error if the item's value is // not an integer, if it was not found, or if it is not possible to increment it by // n. Passing a negative number will cause the item to be decremented. -func (c *cache) IncrementFloat(k string, n float64) os.Error { +func (c *cache) IncrementFloat(k string, n float64) error { c.mu.Lock() defer c.mu.Unlock() @@ -217,18 +216,18 @@ func (c *cache) IncrementFloat(k string, n float64) os.Error { } // Increment an item of type int, int8, int16, int32, int64, uintptr, uint, uint8, -// uint32, or uint64, float32 or float64 by n. Returns an os.Error if the item's value +// uint32, or uint64, float32 or float64 by n. Returns an error if the item's value // is not an integer, if it was not found, or if it is not possible to increment it // by n. Passing a negative number will cause the item to be decremented. -func (c *cache) Increment(k string, n int64) os.Error { +func (c *cache) Increment(k string, n int64) error { return c.IncrementFloat(k, float64(n)) } // Decrement an item of type int, int8, int16, int32, int64, uintptr, uint, uint8, -// uint32, or uint64, float32 or float64 by n. Returns an os.Error if the item's value +// uint32, or uint64, float32 or float64 by n. Returns an error if the item's value // is not an integer, if it was not found, or if it is not possible to decrement it // by n. -func (c *cache) Decrement(k string, n int64) os.Error { +func (c *cache) Decrement(k string, n int64) error { return c.Increment(k, n*-1) } @@ -237,7 +236,7 @@ func (c *cache) Delete(k string) { c.mu.Lock() defer c.mu.Unlock() - c.Items[k] = nil, false + delete(c.Items, k) } // Deletes all expired items from the cache. @@ -247,7 +246,7 @@ func (c *cache) DeleteExpired() { for k, v := range c.Items { if v.Expired() { - c.Items[k] = nil, false + delete(c.Items, k) } } } @@ -265,7 +264,7 @@ func (i *Item) Expired() bool { if i.Expiration == nil { return false } - return *i.Expiration < time.Nanoseconds() + return i.Expiration.Before(time.Now()) } func (j *janitor) Run(c *cache) { @@ -294,7 +293,7 @@ func stopJanitor(c *Cache) { // expire and must be deleted manually. If the cleanup interval is less than one, // expired items are not deleted from the cache before their next lookup or before // calling DeleteExpired. -func New(de, ci int64) *Cache { +func New(de, ci time.Duration) *Cache { if de == 0 { de = -1 } diff --git a/cache_test.go b/cache_test.go index 38b2b00..bc9b6a4 100644 --- a/cache_test.go +++ b/cache_test.go @@ -5,15 +5,6 @@ import ( "time" ) -const ( - Nanosecond = 1 - Microsecond = 1000 * Nanosecond - Millisecond = 1000 * Microsecond - Second = 1000 * Millisecond - Minute = 60 * Second - Hour = 60 * Minute -) - func TestCache(t *testing.T) { tc := New(0, 0) @@ -70,19 +61,19 @@ func TestCache(t *testing.T) { func TestCacheTimes(t *testing.T) { var found bool - tc := New(50*Millisecond, 1*Millisecond) + tc := New(50*time.Millisecond, 1*time.Millisecond) tc.Set("a", 1, 0) tc.Set("b", 2, -1) - tc.Set("c", 3, 20*Millisecond) - tc.Set("d", 4, 70*Millisecond) + tc.Set("c", 3, 20*time.Millisecond) + tc.Set("d", 4, 70*time.Millisecond) - <-time.After(25 * Millisecond) + <-time.After(25 * time.Millisecond) _, found = tc.Get("c") if found { t.Error("Found c when it should have been automatically deleted") } - <-time.After(30 * Millisecond) + <-time.After(30 * time.Millisecond) _, found = tc.Get("a") if found { t.Error("Found a when it should have been automatically deleted") @@ -98,7 +89,7 @@ func TestCacheTimes(t *testing.T) { t.Error("Did not find d even though it was set to expire later than the default") } - <-time.After(20 * Millisecond) + <-time.After(20 * time.Millisecond) _, found = tc.Get("d") if found { t.Error("Found d when it should have been automatically deleted (later than the default)")