From 98d5fc413156ba779dc93fbf202e724734cb32e8 Mon Sep 17 00:00:00 2001 From: Douglas Daniels Date: Wed, 10 Feb 2016 11:30:20 -0600 Subject: [PATCH] Add GetWithExpiration(k) (interface{}, time.Time, bool) --- cache.go | 22 ++++++++++++++++++++++ cache_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/cache.go b/cache.go index 3562543..2b274dc 100644 --- a/cache.go +++ b/cache.go @@ -143,6 +143,28 @@ func (c *cache) get(k string) (interface{}, bool) { return item.Object, true } +// GetWithExpiration gets an item from the cache +// Returns the item or nil, the expiration time and a bool indicating +// whether the key was found. +func (c *cache) GetWithExpiration(k string) (Item, time.Time, bool) { + c.mu.RLock() + // "Inlining" of get and Expired + item, found := c.items[k] + if !found { + c.mu.RUnlock() + return Item{}, time.Time{}, false + } + if item.Expiration > 0 { + if time.Now().UnixNano() > item.Expiration { + c.mu.RUnlock() + return Item{}, time.Time{}, false + } + } + expiration := time.Unix(0, item.Expiration) + c.mu.RUnlock() + return item, expiration, true +} + // Increment an item of type int, int8, int16, int32, int64, uintptr, uint, // uint8, 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 diff --git a/cache_test.go b/cache_test.go index 6e81693..cd26ab7 100644 --- a/cache_test.go +++ b/cache_test.go @@ -77,6 +77,19 @@ func TestCacheTimes(t *testing.T) { tc.Set("c", 3, 20*time.Millisecond) tc.Set("d", 4, 70*time.Millisecond) + _, expiration, found := tc.GetWithExpiration("c") + if !found { + t.Error("a Item was not found while getting c") + } + + if found && expiration.IsZero() { + t.Error("an Item was found but had no expiration") + } + expirationThreshold := time.Now().Add(25 * time.Second) + if !expiration.IsZero() && expiration.After(expirationThreshold) { + t.Errorf("a item.Object expiration expected to be before %s but was %s", expirationThreshold, expiration) + } + <-time.After(25 * time.Millisecond) _, found = tc.Get("c") if found { @@ -1425,6 +1438,19 @@ func TestSerializeUnserializable(t *testing.T) { } } +func TestItems(t *testing.T) { + tc := New(DefaultExpiration, 0) + + tc.Set("a", 1, DefaultExpiration) + items := tc.Items() + + tc.Set("b", "b", DefaultExpiration) + + if tc.ItemCount() != len(items) { + t.Errorf("Error items copy expected length %d but was %d", tc.ItemCount(), len(items)) + } +} + func BenchmarkCacheGetExpiring(b *testing.B) { benchmarkCacheGet(b, 5*time.Minute) }