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

Add cache interface and describe use in tests in README #288

Closed
wants to merge 1 commit into from
Closed
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
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Ristretto is production-ready. See [Projects using Ristretto](#projects-using-ri
* [Metrics](#Config)
* [OnEvict](#Config)
* [KeyToHash](#Config)
* [Cost](#Config)
* [Cost](#Config)
* [Testing](#Testing)
* [Benchmarks](#Benchmarks)
* [Hit Ratios](#Hit-Ratios)
* [Search](#Search)
Expand All @@ -53,6 +54,7 @@ Ristretto is production-ready. See [Projects using Ristretto](#projects-using-ri
* [Projects using Ristretto](#projects-using-ristretto)
* [FAQ](#FAQ)


## Usage

### Example
Expand Down Expand Up @@ -135,6 +137,11 @@ To signal to Ristretto that you'd like to use this Cost function:
1. Set the Cost field to a non-nil function.
2. When calling Set for new items or item updates, use a `cost` of 0.

### Testing

If you wish to mock out the caching functionality for use in your tests, you should use the `CacheInterface` in your code.
This enables you to generate mocks using something like [mockery](https://github.com/vektra/mockery) or provide your own implementation.

## Benchmarks

The benchmarks can be found in https://github.com/dgraph-io/benchmarks/tree/master/cachebench/ristretto.
Expand Down
56 changes: 56 additions & 0 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,58 @@ type itemCallback func(*Item)

const itemSize = int64(unsafe.Sizeof(storeItem{}))

// CacheInterface exposes the common cache functions for the purpose of mocking
// in unit tests.
type CacheInterface interface {

// Get returns the value (if any) and a boolean representing whether the
// value was found or not. The value can be nil and the boolean can be true at
// the same time.
Get(key interface{}) (interface{}, bool)

// Set attempts to add the key-value item to the cache. If it returns false,
// then the Set was dropped and the key-value item isn't added to the cache. If
// it returns true, there's still a chance it could be dropped by the policy if
// its determined that the key-value item isn't worth keeping, but otherwise the
// item will be added and other items will be evicted in order to make room.
//
// To dynamically evaluate the items cost using the Config.Coster function, set
// the cost parameter to 0 and Coster will be ran when needed in order to find
// the items true cost.
Set(key, value interface{}, cost int64) bool

// SetWithTTL works like Set but adds a key-value pair to the cache that will expire
// after the specified TTL (time to live) has passed. A zero value means the value never
// expires, which is identical to calling Set. A negative value is a no-op and the value
// is discarded.
SetWithTTL(key, value interface{}, cost int64, ttl time.Duration) bool

// SetIfPresent is like Set, but only updates the value of an existing key. It
// does NOT add the key to cache if it's absent.
SetIfPresent(key, value interface{}, cost int64) bool

// Del deletes the key-value item from the cache if it exists.
Del(key interface{})

// GetTTL returns the TTL for the specified key and a bool that is true if the
// item was found and is not expired.
GetTTL(key interface{}) (time.Duration, bool)

// Close stops all goroutines and closes all channels.
Close()

// Clear empties the hashmap and zeroes all policy counters. Note that this is
// not an atomic operation (but that shouldn't be a problem as it's assumed that
// Set/Get calls won't be occurring until after this).
Clear()

// MaxCost returns the max cost of the cache.
MaxCost() int64

// UpdateMaxCost updates the maxCost of an existing cache.
UpdateMaxCost(maxCost int64)
}

// Cache is a thread-safe implementation of a hashmap with a TinyLFU admission
// policy and a Sampled LFU eviction policy. You can use the same Cache instance
// from as many goroutines as you want.
Expand Down Expand Up @@ -77,6 +129,10 @@ type Cache struct {
Metrics *Metrics
}

// Verify that Cache implements the CacheInterface.
// https://golang.org/doc/faq#guarantee_satisfies_interface
var _ CacheInterface = &Cache{}

// Config is passed to NewCache for creating new Cache instances.
type Config struct {
// NumCounters determines the number of counters (keys) to keep that hold
Expand Down