golang--lru算法实现

package lru

import "container/list"

// Cache is an LRU cache. It is not safe for concurrent access.
type Cache struct {
    // MaxEntries is the maximum number of cache entries before
    // an item is evicted. Zero means no limit.
    MaxEntries int

    //当有元素被剔除的时候,执行这个回调函数
    OnEvicted func(key Key, value interface{})

    ll    *list.List //双向链表
    cache map[interface{}]*list.Element
}

// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators
type Key interface{}

type entry struct {
    key   Key
    value interface{}
}

// New creates a new Cache.
// 如果maxEntries为0, 则cache没有长度限制
// that eviction is done by the caller.
func New(maxEntries int) *Cache {
    return &Cache{
        MaxEntries: maxEntries,
        ll:         list.New(),
        cache:      make(map[interface{}]*list.Element),
    }
}

// 如果已经存在key值,则将这个key移动到前边
func (c *Cache) Add(key 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.ll.MoveToFront(ee)//移动到前边
        ee.Value.(*entry).value = value
        return
    }
    ele := c.ll.PushFront(&entry{key, value})
    c.cache[key] = ele
    if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries { //如果超过了限制,则移除最老的元素
        c.RemoveOldest()
    }
}

// Get looks up a key's value from the cache.
func (c *Cache) Get(key Key) (value interface{}, ok bool) {
    if c.cache == nil {
        return
    }
    if ele, hit := c.cache[key]; hit {
        c.ll.MoveToFront(ele)
        return ele.Value.(*entry).value, true
    }
    return
}

// Remove removes the provided key from the cache.
func (c *Cache) Remove(key Key) {
    if c.cache == nil {
        return
    }
    if ele, hit := c.cache[key]; hit {
        c.removeElement(ele)
    }
}

// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() {
    if c.cache == nil {
        return
    }
    ele := c.ll.Back()
    if ele != nil {
        c.removeElement(ele)
    }
}

func (c *Cache) removeElement(e *list.Element) {
    c.ll.Remove(e)
    kv := e.Value.(*entry)
    delete(c.cache, kv.key)
    if c.OnEvicted != nil {
        c.OnEvicted(kv.key, kv.value)
    }
}

// Len returns the number of items in the cache.
func (c *Cache) Len() int {
    if c.cache == nil {
        return 0
    }
    return c.ll.Len()
}

// Clear purges all stored items from the cache.
func (c *Cache) Clear() {
    if c.OnEvicted != nil {
        for _, e := range c.cache {
            kv := e.Value.(*entry)
            c.OnEvicted(kv.key, kv.value)
        }
    }
    c.ll = nil
    c.cache = nil
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值