Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: get the value but not update the expiration time (#57) #61

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,49 @@ func TestCacheKeepAlive(t *testing.T) {
}
}

func TestPeek(t *testing.T) {
// add an expiring item
table := Cache("TestPeek")
_ = table.Add(k, 250*time.Millisecond, v)
_ = table.Add(k+"_", 250*time.Millisecond, v)

// test peek item
time.Sleep(150 * time.Millisecond)
p, _ := table.Peek(k)
if p.Data() != v {
t.Error("Error peek item")
}

// test k is expired
time.Sleep(150 * time.Millisecond)
if table.Exists(k) {
t.Error("Error peek but expired time updated")
}

// test peek nil
_, err := table.Peek(k)
if err != ErrKeyNotFound {
t.Error("Error peek nil value but not return ErrKeyNotFound")
}

// test DataLoader
table.SetDataLoader(func(key interface{}, args ...interface{}) *CacheItem {
if key == k {
return NewCacheItem(key, 150*time.Millisecond, "new value")
}
return nil
})
p, _ = table.Peek(k)
if p.Data() != "new value" {
t.Error("Error peek DataLoader callback did not take effect")
}

_, err = table.Peek(k + "_")
if err != ErrKeyNotFoundOrLoadable {
t.Error("Error peek DataLoader err")
}
}

func TestDelete(t *testing.T) {
// add an item to the cache
table := Cache("testDelete")
Expand Down
7 changes: 7 additions & 0 deletions cacheitem.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ func (item *CacheItem) KeepAlive() {
item.accessCount++
}

// AddAccessCount only add one access count.
func (item *CacheItem) AddAccessCount() {
item.Lock()
defer item.Unlock()
item.accessCount++
}

// LifeSpan returns this item's expiration duration.
func (item *CacheItem) LifeSpan() time.Duration {
// immutable
Expand Down
27 changes: 27 additions & 0 deletions cachetable.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,33 @@ func (table *CacheTable) Value(key interface{}, args ...interface{}) (*CacheItem
return nil, ErrKeyNotFound
}

// Peek returns an item from the cache, but does not mark its active status, i.e. does not update the active time.
// You can also pass additional arguments to your DataLoader callback function.
func (table *CacheTable) Peek(key interface{}, args ...interface{}) (*CacheItem, error) {
table.RLock()
r, ok := table.items[key]
loadData := table.loadData
table.RUnlock()

if ok {
r.AddAccessCount()
return r, nil
}

// Item doesn't exist in cache. Try and fetch it with a data-loader.
if loadData != nil {
item := loadData(key, args...)
if item != nil {
table.Add(key, item.lifeSpan, item.data)
return item, nil
}

return nil, ErrKeyNotFoundOrLoadable
}

return nil, ErrKeyNotFound
}

// Flush deletes all items from this cache table.
func (table *CacheTable) Flush() {
table.Lock()
Expand Down