Use nanosecond-resolution TTL instead of second-resolution.

This commit is contained in:
Matthew Dale 2016-07-07 15:32:49 -07:00
parent ddcff8e624
commit 162d4e27ca
5 changed files with 22 additions and 20 deletions

View file

@ -17,7 +17,7 @@ func (b *bucket) get(key string) *Item {
} }
func (b *bucket) set(key string, value interface{}, duration time.Duration) (*Item, *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) item := newItem(key, value, expires)
b.Lock() b.Lock()
defer b.Unlock() defer b.Unlock()

View file

@ -47,7 +47,7 @@ func (c *Cache) Get(key string) *Item {
if item == nil { if item == nil {
return nil return nil
} }
if item.expires > time.Now().Unix() { if item.expires > time.Now().UnixNano() {
c.promote(item) c.promote(item)
} }
return item return item

View file

@ -85,19 +85,19 @@ func (i *Item) Release() {
func (i *Item) Expired() bool { func (i *Item) Expired() bool {
expires := atomic.LoadInt64(&i.expires) expires := atomic.LoadInt64(&i.expires)
return expires < time.Now().Unix() return expires < time.Now().UnixNano()
} }
func (i *Item) TTL() time.Duration { func (i *Item) TTL() time.Duration {
expires := atomic.LoadInt64(&i.expires) 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 { func (i *Item) Expires() time.Time {
expires := atomic.LoadInt64(&i.expires) expires := atomic.LoadInt64(&i.expires)
return time.Unix(expires, 0) return time.Unix(0, expires)
} }
func (i *Item) Extend(duration time.Duration) { 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())
} }

View file

@ -1,9 +1,11 @@
package ccache package ccache
import ( import (
. "github.com/karlseguin/expect" "math"
"testing" "testing"
"time" "time"
. "github.com/karlseguin/expect"
) )
type ItemTests struct{} type ItemTests struct{}
@ -19,29 +21,29 @@ func (_ *ItemTests) Promotability() {
} }
func (_ *ItemTests) Expired() { func (_ *ItemTests) Expired() {
now := time.Now().Unix() now := time.Now().UnixNano()
item1 := &Item{expires: now + 1} item1 := &Item{expires: now + (10 * int64(time.Millisecond))}
item2 := &Item{expires: now - 1} item2 := &Item{expires: now - (10 * int64(time.Millisecond))}
Expect(item1.Expired()).To.Equal(false) Expect(item1.Expired()).To.Equal(false)
Expect(item2.Expired()).To.Equal(true) Expect(item2.Expired()).To.Equal(true)
} }
func (_ *ItemTests) TTL() { func (_ *ItemTests) TTL() {
now := time.Now().Unix() now := time.Now().UnixNano()
item1 := &Item{expires: now + 10} item1 := &Item{expires: now + int64(time.Second)}
item2 := &Item{expires: now - 10} item2 := &Item{expires: now - int64(time.Second)}
Expect(item1.TTL()).To.Equal(time.Second * 10) Expect(int(math.Ceil(item1.TTL().Seconds()))).To.Equal(1)
Expect(item2.TTL()).To.Equal(time.Second * -10) Expect(int(math.Ceil(item2.TTL().Seconds()))).To.Equal(-1)
} }
func (_ *ItemTests) Expires() { func (_ *ItemTests) Expires() {
now := time.Now().Unix() now := time.Now().UnixNano()
item := &Item{expires: now + 10} item := &Item{expires: now + (10)}
Expect(item.Expires().Unix()).To.Equal(now + 10) Expect(item.Expires().UnixNano()).To.Equal(now + 10)
} }
func (_ *ItemTests) Extend() { func (_ *ItemTests) Extend() {
item := &Item{expires: time.Now().Unix() + 10} item := &Item{expires: time.Now().UnixNano() + 10}
item.Extend(time.Minute * 2) item.Extend(time.Minute * 2)
Expect(item.Expires().Unix()).To.Equal(time.Now().Unix() + 120) Expect(item.Expires().Unix()).To.Equal(time.Now().Unix() + 120)
} }

View file

@ -58,7 +58,7 @@ func (c *LayeredCache) Get(primary, secondary string) *Item {
if item == nil { if item == nil {
return nil return nil
} }
if item.expires > time.Now().Unix() { if item.expires > time.Now().UnixNano() {
c.promote(item) c.promote(item)
} }
return item return item