go语言lru实现

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(),链表使用读写锁加锁(通常来说,读多写少)

上一篇:Java架构师之路!别再说自己不会JVM虚拟机了


下一篇:高级Redis应用进阶课 一站式Redis解决方案