package ttlru
import "container/list"
type Cache struct {
MaxEntries int
ll *list.List
cache map[interface{}]*list.Element
}
func New(maxEntries int) *Cache {
return &Cache{
MaxEntries: maxEntries,
ll: list.New(),
cache: make(map[interface{}]*list.Element),
}
}
type entry struct {
key interface{}
value interface{}
}
func (c *Cache)Add(key,value interface{}) {
if c.cache == nil {
c.cache = make(map[interface{}]*list.Element)
c.ll = list.New()
}
//如果存在,则直接更新
if ee,ok := c.cache[key];ok {
c.cache[key] = ee
c.ll.MoveToFront(ee)
return
}
ele := c.ll.PushFront(&entry{
key: key,
value: value,
})
c.cache[key] = ele
if c.MaxEntries != 0 && len(c.cache) > c.MaxEntries{
c.removeElement(ele)
}
}
func (c *Cache)Get(key interface{}) (interface{},bool) {
if c.cache == nil{
return nil,false
}
if ele,hit := c.cache[key];hit{
return ele.Value.(*entry).value,true
}
return nil,false
}
func (c *Cache)Remove(key interface{}) {
if c.cache == nil{
return
}
if ele,hit := c.cache[key];hit{
c.removeElement(ele)
}
}
func (c *Cache) Clear() {
c.ll = nil
c.cache = nil
}
func (c *Cache) Len() int {
if c.cache == nil {
return 0
}
return c.ll.Len()
}
func (c *Cache)removeElement(e *list.Element) {
c.ll.Remove(e)
delete(c.cache,e.Value.(entry).key)
}
问题:线程非安全,没有加入过期时间
过期时间方案:set时设置过期时间,get时比较key是否过期,过期则删除
线程安全方案:map使用sync.Map(),链表使用读写锁加锁(通常来说,读多写少)