package cache import ( "time" ) 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) Contains(Key) bool Get(Key) (Value, bool) Remove(Key) } // InterfaceCacher external cache interface. type InterfaceCacher interface { Add(interface{}, interface{}) Get(interface{}) (interface{}, bool) Contains(interface{}) bool Remove(interface{}) } type cache struct { cache InterfaceCacher } func New(c InterfaceCacher) Cacher { return &cache{cache: c} } func (c *cache) Add(key Key, value Value) { c.cache.Add(key.Key(), value) } func (c *cache) 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 *cache) Contains(key Key) bool { _, ok := c.Get(key) return ok } func (c *cache) Remove(key Key) { c.cache.Remove(key.Key()) }