From 162d4e27ca4b2a863b2f41a49a58b9259d4ccce3 Mon Sep 17 00:00:00 2001 From: Matthew Dale Date: Thu, 7 Jul 2016 15:32:49 -0700 Subject: [PATCH] Use nanosecond-resolution TTL instead of second-resolution. --- bucket.go | 2 +- cache.go | 2 +- item.go | 8 ++++---- item_test.go | 28 +++++++++++++++------------- layeredcache.go | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/bucket.go b/bucket.go index e330d24..d675351 100644 --- a/bucket.go +++ b/bucket.go @@ -17,7 +17,7 @@ func (b *bucket) get(key string) *Item { } func (b *bucket) set(key string, value interface{}, duration time.Duration) (*Item, *Item) { - expires := time.Now().Add(duration).Unix() + expires := time.Now().Add(duration).UnixNano() item := newItem(key, value, expires) b.Lock() defer b.Unlock() diff --git a/cache.go b/cache.go index 81cbfde..998d1db 100644 --- a/cache.go +++ b/cache.go @@ -47,7 +47,7 @@ func (c *Cache) Get(key string) *Item { if item == nil { return nil } - if item.expires > time.Now().Unix() { + if item.expires > time.Now().UnixNano() { c.promote(item) } return item diff --git a/item.go b/item.go index 1c35ae7..bb7c04f 100644 --- a/item.go +++ b/item.go @@ -85,19 +85,19 @@ func (i *Item) Release() { func (i *Item) Expired() bool { expires := atomic.LoadInt64(&i.expires) - return expires < time.Now().Unix() + return expires < time.Now().UnixNano() } func (i *Item) TTL() time.Duration { expires := atomic.LoadInt64(&i.expires) - return time.Second * time.Duration(expires-time.Now().Unix()) + return time.Nanosecond * time.Duration(expires-time.Now().UnixNano()) } func (i *Item) Expires() time.Time { expires := atomic.LoadInt64(&i.expires) - return time.Unix(expires, 0) + return time.Unix(0, expires) } func (i *Item) Extend(duration time.Duration) { - atomic.StoreInt64(&i.expires, time.Now().Add(duration).Unix()) + atomic.StoreInt64(&i.expires, time.Now().Add(duration).UnixNano()) } diff --git a/item_test.go b/item_test.go index a62ab3d..9311c9b 100644 --- a/item_test.go +++ b/item_test.go @@ -1,9 +1,11 @@ package ccache import ( - . "github.com/karlseguin/expect" + "math" "testing" "time" + + . "github.com/karlseguin/expect" ) type ItemTests struct{} @@ -19,29 +21,29 @@ func (_ *ItemTests) Promotability() { } func (_ *ItemTests) Expired() { - now := time.Now().Unix() - item1 := &Item{expires: now + 1} - item2 := &Item{expires: now - 1} + now := time.Now().UnixNano() + item1 := &Item{expires: now + (10 * int64(time.Millisecond))} + item2 := &Item{expires: now - (10 * int64(time.Millisecond))} Expect(item1.Expired()).To.Equal(false) Expect(item2.Expired()).To.Equal(true) } func (_ *ItemTests) TTL() { - now := time.Now().Unix() - item1 := &Item{expires: now + 10} - item2 := &Item{expires: now - 10} - Expect(item1.TTL()).To.Equal(time.Second * 10) - Expect(item2.TTL()).To.Equal(time.Second * -10) + now := time.Now().UnixNano() + item1 := &Item{expires: now + int64(time.Second)} + item2 := &Item{expires: now - int64(time.Second)} + Expect(int(math.Ceil(item1.TTL().Seconds()))).To.Equal(1) + Expect(int(math.Ceil(item2.TTL().Seconds()))).To.Equal(-1) } func (_ *ItemTests) Expires() { - now := time.Now().Unix() - item := &Item{expires: now + 10} - Expect(item.Expires().Unix()).To.Equal(now + 10) + now := time.Now().UnixNano() + item := &Item{expires: now + (10)} + Expect(item.Expires().UnixNano()).To.Equal(now + 10) } func (_ *ItemTests) Extend() { - item := &Item{expires: time.Now().Unix() + 10} + item := &Item{expires: time.Now().UnixNano() + 10} item.Extend(time.Minute * 2) Expect(item.Expires().Unix()).To.Equal(time.Now().Unix() + 120) } diff --git a/layeredcache.go b/layeredcache.go index 902489d..70a2852 100644 --- a/layeredcache.go +++ b/layeredcache.go @@ -58,7 +58,7 @@ func (c *LayeredCache) Get(primary, secondary string) *Item { if item == nil { return nil } - if item.expires > time.Now().Unix() { + if item.expires > time.Now().UnixNano() { c.promote(item) } return item