func (c *Cache) TTL() time.Duration {
	return c.ttl
}
TTL returns entries default TTL.
package internal
import (
	"context"
	"time"
)
type Collection interface {
	Move(*Entry)
	Add(*Entry)
	Remove(*Entry)
	Discard() *Entry
	Len() int
	Init()
}
type Entry struct {
	Key     interface{}
	Value   interface{}
	Element interface{}
	Exp     time.Time
	timer   *time.Timer
	cancel  context.CancelFunc
}
func (e *Entry) startTimer(d time.Duration, f func(key, value interface{})) {
	ctx, cancel := context.WithCancel(context.TODO())
	e.cancel = cancel
	e.timer = time.AfterFunc(d, func() {
		if ctx.Err() != nil {
			return
		}
		f(e.Key, e.Value)
	})
}
func (e *Entry) stopTimer() {
	if e.timer == nil {
		return
	}
	e.timer.Stop()
	e.cancel()
}
type Cache struct {
	coll      Collection
	entries   map[interface{}]*Entry
	onEvicted func(key, value interface{})
	onExpired func(key, value interface{})
	ttl       time.Duration
	capacity  int
}
func (c *Cache) Load(key interface{}) (interface{}, bool) {
	return c.get(key, false)
}
func (c *Cache) Peek(key interface{}) (interface{}, bool) {
	return c.get(key, true)
}
func (c *Cache) get(key interface{}, peek bool) (v interface{}, found bool) {
	e, ok := c.entries[key]
	if !ok {
		return
	}
	if !e.Exp.IsZero() && time.Now().UTC().After(e.Exp) {
		c.evict(e)
		return
	}
	if !peek {
		c.coll.Move(e)
	}
	return e.Value, ok
}
func (c *Cache) Expiry(key interface{}) (t time.Time, ok bool) {
	ok = c.Contains(key)
	if ok {
		t = c.entries[key].Exp
	}
	return t, ok
}
func (c *Cache) Store(key, value interface{}) {
	c.StoreWithTTL(key, value, c.ttl)
}
func (c *Cache) StoreWithTTL(key, value interface{}, ttl time.Duration) {
	if e, ok := c.entries[key]; ok {
		c.removeEntry(e)
	}
	e := &Entry{Key: key, Value: value}
	if ttl > 0 {
		if c.onExpired != nil {
			e.startTimer(ttl, c.onExpired)
		}
		e.Exp = time.Now().UTC().Add(ttl)
	}
	c.entries[key] = e
	if c.capacity != 0 && c.Len() >= c.capacity {
		c.Discard()
	}
	c.coll.Add(e)
}
func (c *Cache) Update(key, value interface{}) {
	if c.Contains(key) {
		c.entries[key].Value = value
	}
}
func (c *Cache) Purge() {
	defer c.coll.Init()
	if c.onEvicted == nil {
		c.entries = make(map[interface{}]*Entry)
		return
	}
	for _, e := range c.entries {
		c.evict(e)
	}
}
func (c *Cache) Resize(size int) int {
	c.capacity = size
	diff := c.Len() - size
	if diff < 0 {
		diff = 0
	}
	for i := 0; i < diff; i++ {
		c.Discard()
	}
	return diff
}
func (c *Cache) DelSilently(key interface{}) {
	if e, ok := c.entries[key]; ok {
		c.removeEntry(e)
	}
}
func (c *Cache) Delete(key interface{}) {
	if e, ok := c.entries[key]; ok {
		c.evict(e)
	}
}
func (c *Cache) Contains(key interface{}) (ok bool) {
	_, ok = c.Peek(key)
	return
}
func (c *Cache) Keys() (keys []interface{}) {
	for k := range c.entries {
		keys = append(keys, k)
	}
	return
}
func (c *Cache) Len() int {
	return c.coll.Len()
}
func (c *Cache) Discard() (key, value interface{}) {
	if e := c.coll.Discard(); e != nil {
		c.evict(e)
		return e.Key, e.Value
	}
	return
}
func (c *Cache) removeEntry(e *Entry) {
	c.coll.Remove(e)
	e.stopTimer()
	delete(c.entries, e.Key)
}
func (c *Cache) evict(e *Entry) {
	c.removeEntry(e)
	if c.onEvicted != nil {
		go c.onEvicted(e.Key, e.Value)
	}
}