README
¶
GCache
Cache library for golang. It supports expirable Cache, LFU, LRU and ARC.
Features
-
Supports expirable Cache, LFU, LRU and ARC.
-
Goroutine safe.
-
Supports event handlers which evict, purge, and add entry. (Optional)
-
Automatically load cache if it doesn't exists. (Optional)
Install
$ go get github.com/bluele/gcache
Example
Manually set a key-value pair.
package main
import (
"github.com/bluele/gcache"
"fmt"
)
func main() {
gc := gcache.New(20).
LRU().
Build()
gc.Set("key", "ok")
value, err := gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
}
Get: ok
Manually set a key-value pair, with an expiration time.
package main
import (
"github.com/bluele/gcache"
"fmt"
"time"
)
func main() {
gc := gcache.New(20).
LRU().
Build()
gc.SetWithExpire("key", "ok", time.Second*10)
value, _ := gc.Get("key")
fmt.Println("Get:", value)
// Wait for value to expire
time.Sleep(time.Second*10)
value, err = gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
}
Get: ok
// 10 seconds later, new attempt:
panic: ErrKeyNotFound
Automatically load value
package main
import (
"github.com/bluele/gcache"
"fmt"
)
func main() {
gc := gcache.New(20).
LRU().
LoaderFunc(func(key interface{}) (interface{}, error) {
return "ok", nil
}).
Build()
value, err := gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
}
Get: ok
Automatically load value with expiration
package main
import (
"fmt"
"time"
"github.com/bluele/gcache"
)
func main() {
var evictCounter, loaderCounter, purgeCounter int
gc := gcache.New(20).
LRU().
LoaderExpireFunc(func(key interface{}) (interface{}, *time.Duration, error) {
loaderCounter++
expire := 1 * time.Second
return "ok", &expire, nil
}).
EvictedFunc(func(key, value interface{}) {
evictCounter++
fmt.Println("evicted key:", key)
}).
PurgeVisitorFunc(func(key, value interface{}) {
purgeCounter++
fmt.Println("purged key:", key)
}).
Build()
value, err := gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
time.Sleep(1 * time.Second)
value, err = gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
gc.Purge()
if loaderCounter != evictCounter+purgeCounter {
panic("bad")
}
}
Get: ok
evicted key: key
Get: ok
purged key: key
Cache Algorithm
- Least-Frequently Used (LFU)
Discards the least frequently used items first.
func main() {
// size: 10
gc := gcache.New(10).
LFU().
Build()
gc.Set("key", "value")
}
- Least Recently Used (LRU)
Discards the least recently used items first.
func main() {
// size: 10
gc := gcache.New(10).
LRU().
Build()
gc.Set("key", "value")
}
- Adaptive Replacement Cache (ARC)
Constantly balances between LRU and LFU, to improve the combined result.
detail: http://en.wikipedia.org/wiki/Adaptive_replacement_cache
func main() {
// size: 10
gc := gcache.New(10).
ARC().
Build()
gc.Set("key", "value")
}
- SimpleCache (Default)
SimpleCache has no clear priority for evict cache. It depends on key-value map order.
func main() {
// size: 10
gc := gcache.New(10).Build()
gc.Set("key", "value")
v, err := gc.Get("key")
if err != nil {
panic(err)
}
}
Loading Cache
If specified LoaderFunc
, values are automatically loaded by the cache, and are stored in the cache until either evicted or manually invalidated.
func main() {
gc := gcache.New(10).
LRU().
LoaderFunc(func(key interface{}) (interface{}, error) {
return "value", nil
}).
Build()
v, _ := gc.Get("key")
// output: "value"
fmt.Println(v)
}
GCache coordinates cache fills such that only one load in one process of an entire replicated set of processes populates the cache, then multiplexes the loaded value to all callers.
Expirable cache
func main() {
// LRU cache, size: 10, expiration: after a hour
gc := gcache.New(10).
LRU().
Expiration(time.Hour).
Build()
}
Event handlers
Evicted handler
Event handler for evict the entry.
func main() {
gc := gcache.New(2).
EvictedFunc(func(key, value interface{}) {
fmt.Println("evicted key:", key)
}).
Build()
for i := 0; i < 3; i++ {
gc.Set(i, i*i)
}
}
evicted key: 0
Added handler
Event handler for add the entry.
func main() {
gc := gcache.New(2).
AddedFunc(func(key, value interface{}) {
fmt.Println("added key:", key)
}).
Build()
for i := 0; i < 3; i++ {
gc.Set(i, i*i)
}
}
added key: 0
added key: 1
added key: 2
Author
Jun Kimura
Documentation
¶
Index ¶
- Constants
- Variables
- type ARC
- func (c *ARC) Get(key interface{}) (interface{}, error)
- func (c *ARC) GetALL(checkExpired bool) map[interface{}]interface{}
- func (c *ARC) GetIFPresent(key interface{}) (interface{}, error)
- func (c *ARC) Has(key interface{}) bool
- func (c *ARC) Keys(checkExpired bool) []interface{}
- func (c *ARC) Len(checkExpired bool) int
- func (c *ARC) Purge()
- func (c *ARC) Remove(key interface{}) bool
- func (c *ARC) Set(key, value interface{}) error
- func (c *ARC) SetWithExpire(key, value interface{}, expiration time.Duration) error
- type AddedFunc
- type Cache
- type CacheBuilder
- func (cb *CacheBuilder) ARC() *CacheBuilder
- func (cb *CacheBuilder) AddedFunc(addedFunc AddedFunc) *CacheBuilder
- func (cb *CacheBuilder) Build() Cache
- func (cb *CacheBuilder) Clock(clock Clock) *CacheBuilder
- func (cb *CacheBuilder) DeserializeFunc(deserializeFunc DeserializeFunc) *CacheBuilder
- func (cb *CacheBuilder) EvictType(tp string) *CacheBuilder
- func (cb *CacheBuilder) EvictedFunc(evictedFunc EvictedFunc) *CacheBuilder
- func (cb *CacheBuilder) Expiration(expiration time.Duration) *CacheBuilder
- func (cb *CacheBuilder) LFU() *CacheBuilder
- func (cb *CacheBuilder) LRU() *CacheBuilder
- func (cb *CacheBuilder) LoaderExpireFunc(loaderExpireFunc LoaderExpireFunc) *CacheBuilder
- func (cb *CacheBuilder) LoaderFunc(loaderFunc LoaderFunc) *CacheBuilder
- func (cb *CacheBuilder) PurgeVisitorFunc(purgeVisitorFunc PurgeVisitorFunc) *CacheBuilder
- func (cb *CacheBuilder) SerializeFunc(serializeFunc SerializeFunc) *CacheBuilder
- func (cb *CacheBuilder) Simple() *CacheBuilder
- type Clock
- type DeserializeFunc
- type EvictedFunc
- type FakeClock
- type Group
- type LFU
- func (c *LFU) Get(key interface{}) (interface{}, error)
- func (c *LFU) GetALL(checkExpired bool) map[interface{}]interface{}
- func (c *LFU) GetIFPresent(key interface{}) (interface{}, error)
- func (c *LFU) Has(key interface{}) bool
- func (c *LFU) Keys(checkExpired bool) []interface{}
- func (c *LFU) Len(checkExpired bool) int
- func (c *LFU) Purge()
- func (c *LFU) Remove(key interface{}) bool
- func (c *LFU) Set(key, value interface{}) error
- func (c *LFU) SetWithExpire(key, value interface{}, expiration time.Duration) error
- type LRU
- func (c *LRU) Get(key interface{}) (interface{}, error)
- func (c *LRU) GetALL(checkExpired bool) map[interface{}]interface{}
- func (c *LRU) GetIFPresent(key interface{}) (interface{}, error)
- func (c *LRU) Has(key interface{}) bool
- func (c *LRU) Keys(checkExpired bool) []interface{}
- func (c *LRU) Len(checkExpired bool) int
- func (c *LRU) Purge()
- func (c *LRU) Remove(key interface{}) bool
- func (c *LRU) Set(key, value interface{}) error
- func (c *LRU) SetWithExpire(key, value interface{}, expiration time.Duration) error
- type LoaderExpireFunc
- type LoaderFunc
- type PurgeVisitorFunc
- type RealClock
- type SerializeFunc
- type SimpleCache
- func (c *SimpleCache) Get(key interface{}) (interface{}, error)
- func (c *SimpleCache) GetALL(checkExpired bool) map[interface{}]interface{}
- func (c *SimpleCache) GetIFPresent(key interface{}) (interface{}, error)
- func (c *SimpleCache) Has(key interface{}) bool
- func (c *SimpleCache) Keys(checkExpired bool) []interface{}
- func (c *SimpleCache) Len(checkExpired bool) int
- func (c *SimpleCache) Purge()
- func (c *SimpleCache) Remove(key interface{}) bool
- func (c *SimpleCache) Set(key, value interface{}) error
- func (c *SimpleCache) SetWithExpire(key, value interface{}, expiration time.Duration) error
Constants ¶
const ( TYPE_SIMPLE = "simple" TYPE_LRU = "lru" TYPE_LFU = "lfu" TYPE_ARC = "arc" )
Variables ¶
var KeyNotFoundError = errors.New("Key not found.")
Functions ¶
This section is empty.
Types ¶
type ARC ¶
type ARC struct {
// contains filtered or unexported fields
}
Constantly balances between LRU and LFU, to improve the combined result.
func (*ARC) Get ¶
Get a value from cache pool using key if it exists. If not exists and it has LoaderFunc, it will generate the value using you have specified LoaderFunc method returns value.
func (*ARC) GetIFPresent ¶
GetIFPresent gets a value from cache pool using key if it exists. If it dose not exists key, returns KeyNotFoundError. And send a request which refresh value for specified key if cache object has LoaderFunc.
type Cache ¶
type Cache interface { Set(key, value any) error SetWithExpire(key, value any, expiration time.Duration) error Get(key any) (any, error) GetIFPresent(key any) (any, error) GetALL(checkExpired bool) map[any]any Remove(key any) bool Purge() Keys(checkExpired bool) []any Len(checkExpired bool) int Has(key any) bool // contains filtered or unexported methods }
type CacheBuilder ¶
type CacheBuilder struct {
// contains filtered or unexported fields
}
func New ¶
func New(size int) *CacheBuilder
func (*CacheBuilder) ARC ¶
func (cb *CacheBuilder) ARC() *CacheBuilder
func (*CacheBuilder) AddedFunc ¶
func (cb *CacheBuilder) AddedFunc(addedFunc AddedFunc) *CacheBuilder
func (*CacheBuilder) Build ¶
func (cb *CacheBuilder) Build() Cache
func (*CacheBuilder) Clock ¶
func (cb *CacheBuilder) Clock(clock Clock) *CacheBuilder
func (*CacheBuilder) DeserializeFunc ¶
func (cb *CacheBuilder) DeserializeFunc(deserializeFunc DeserializeFunc) *CacheBuilder
func (*CacheBuilder) EvictType ¶
func (cb *CacheBuilder) EvictType(tp string) *CacheBuilder
func (*CacheBuilder) EvictedFunc ¶
func (cb *CacheBuilder) EvictedFunc(evictedFunc EvictedFunc) *CacheBuilder
func (*CacheBuilder) Expiration ¶
func (cb *CacheBuilder) Expiration(expiration time.Duration) *CacheBuilder
func (*CacheBuilder) LFU ¶
func (cb *CacheBuilder) LFU() *CacheBuilder
func (*CacheBuilder) LRU ¶
func (cb *CacheBuilder) LRU() *CacheBuilder
func (*CacheBuilder) LoaderExpireFunc ¶
func (cb *CacheBuilder) LoaderExpireFunc(loaderExpireFunc LoaderExpireFunc) *CacheBuilder
Set a loader function with expiration. loaderExpireFunc: create a new value with this function if cached value is expired. If nil returned instead of time.Duration from loaderExpireFunc than value will never expire.
func (*CacheBuilder) LoaderFunc ¶
func (cb *CacheBuilder) LoaderFunc(loaderFunc LoaderFunc) *CacheBuilder
Set a loader function. loaderFunc: create a new value with this function if cached value is expired.
func (*CacheBuilder) PurgeVisitorFunc ¶
func (cb *CacheBuilder) PurgeVisitorFunc(purgeVisitorFunc PurgeVisitorFunc) *CacheBuilder
func (*CacheBuilder) SerializeFunc ¶
func (cb *CacheBuilder) SerializeFunc(serializeFunc SerializeFunc) *CacheBuilder
func (*CacheBuilder) Simple ¶
func (cb *CacheBuilder) Simple() *CacheBuilder
type EvictedFunc ¶
type FakeClock ¶
func NewFakeClock ¶
func NewFakeClock() FakeClock
type Group ¶
type Group struct {
// contains filtered or unexported fields
}
Group represents a class of work and forms a namespace in which units of work can be executed with duplicate suppression.
func (*Group) Do ¶
func (g *Group) Do(key interface{}, fn func() (interface{}, error), isWait bool) (interface{}, bool, error)
Do executes and returns the results of the given function, making sure that only one execution is in-flight for a given key at a time. If a duplicate comes in, the duplicate caller waits for the original to complete and receives the same results.
type LFU ¶ added in v0.3.3
type LFU struct {
// contains filtered or unexported fields
}
Discards the least frequently used items first.
func (*LFU) Get ¶ added in v0.3.3
Get a value from cache pool using key if it exists. If it dose not exists key and has LoaderFunc, generate a value using `LoaderFunc` method returns value.
func (*LFU) GetIFPresent ¶ added in v0.3.3
GetIFPresent gets a value from cache pool using key if it exists. If it dose not exists key, returns KeyNotFoundError. And send a request which refresh value for specified key if cache object has LoaderFunc.
type LRU ¶ added in v0.3.3
type LRU struct {
// contains filtered or unexported fields
}
Discards the least recently used items first.
func (*LRU) Get ¶ added in v0.3.3
Get a value from cache pool using key if it exists. If it dose not exists key and has LoaderFunc, generate a value using `LoaderFunc` method returns value.
func (*LRU) GetIFPresent ¶ added in v0.3.3
GetIFPresent gets a value from cache pool using key if it exists. If it dose not exists key, returns KeyNotFoundError. And send a request which refresh value for specified key if cache object has LoaderFunc.
type LoaderFunc ¶
type PurgeVisitorFunc ¶
type SimpleCache ¶
type SimpleCache struct {
// contains filtered or unexported fields
}
SimpleCache has no clear priority for evict cache. It depends on key-value map order.
func (*SimpleCache) Get ¶
func (c *SimpleCache) Get(key interface{}) (interface{}, error)
Get a value from cache pool using key if it exists. If it dose not exists key and has LoaderFunc, generate a value using `LoaderFunc` method returns value.
func (*SimpleCache) GetALL ¶
func (c *SimpleCache) GetALL(checkExpired bool) map[interface{}]interface{}
GetALL returns all key-value pairs in the cache.
func (*SimpleCache) GetIFPresent ¶
func (c *SimpleCache) GetIFPresent(key interface{}) (interface{}, error)
GetIFPresent gets a value from cache pool using key if it exists. If it dose not exists key, returns KeyNotFoundError. And send a request which refresh value for specified key if cache object has LoaderFunc.
func (*SimpleCache) Has ¶
func (c *SimpleCache) Has(key interface{}) bool
Has checks if key exists in cache
func (*SimpleCache) Keys ¶
func (c *SimpleCache) Keys(checkExpired bool) []interface{}
Keys returns a slice of the keys in the cache.
func (*SimpleCache) Len ¶
func (c *SimpleCache) Len(checkExpired bool) int
Len returns the number of items in the cache.
func (*SimpleCache) Remove ¶
func (c *SimpleCache) Remove(key interface{}) bool
Remove removes the provided key from the cache.
func (*SimpleCache) Set ¶
func (c *SimpleCache) Set(key, value interface{}) error
Set a new key-value pair
func (*SimpleCache) SetWithExpire ¶
func (c *SimpleCache) SetWithExpire(key, value interface{}, expiration time.Duration) error
Set a new key-value pair with an expiration time