78 lines
1.3 KiB
Go
78 lines
1.3 KiB
Go
package cache
|
|
|
|
import (
|
|
"time"
|
|
|
|
lru "github.com/hashicorp/golang-lru"
|
|
)
|
|
|
|
type Key interface {
|
|
Key() interface{}
|
|
}
|
|
type Value interface {
|
|
Stale() bool
|
|
Value() interface{}
|
|
}
|
|
type item struct {
|
|
key interface{}
|
|
value interface{}
|
|
expireOn time.Time
|
|
}
|
|
|
|
func NewItem(key, value interface{}, expires time.Duration) *item {
|
|
return &item{
|
|
key: key,
|
|
value: value,
|
|
expireOn: time.Now().Add(expires),
|
|
}
|
|
}
|
|
func (e *item) Stale() bool {
|
|
if e == nil || e.value == nil {
|
|
return true
|
|
}
|
|
|
|
return time.Now().After(e.expireOn)
|
|
}
|
|
func (s *item) Value() interface{} {
|
|
return s.value
|
|
}
|
|
|
|
type Cacher interface {
|
|
Add(Key, Value)
|
|
Has(Key) bool
|
|
Get(Key) (Value, bool)
|
|
Remove(Key)
|
|
}
|
|
|
|
type arcCache struct {
|
|
cache *lru.ARCCache
|
|
}
|
|
|
|
func NewARC(size int) (Cacher, error) {
|
|
arc, err := lru.NewARC(size)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &arcCache{cache: arc}, nil
|
|
}
|
|
func (c *arcCache) Add(key Key, value Value) {
|
|
c.cache.Add(key.Key(), value)
|
|
}
|
|
func (c *arcCache) Get(key Key) (Value, bool) {
|
|
if v, ok := c.cache.Get(key.Key()); ok {
|
|
if value, ok := v.(Value); ok && !value.Stale() {
|
|
return value, true
|
|
}
|
|
c.cache.Remove(key.Key())
|
|
}
|
|
return nil, false
|
|
}
|
|
func (c *arcCache) Has(key Key) bool {
|
|
_, ok := c.Get(key)
|
|
return ok
|
|
}
|
|
func (c *arcCache) Remove(key Key) {
|
|
c.cache.Remove(key.Key())
|
|
}
|