Golang 實(shí)現(xiàn)LRU算法

緩存文件置換機(jī)制計(jì)算機(jī)處理緩存存儲(chǔ)器的一種機(jī)制。

計(jì)算機(jī)存儲(chǔ)器空間的大小固定,無(wú)法容納服務(wù)器上所有的文件,所以當(dāng)有新的文件要被置換入緩存時(shí),必須根據(jù)一定的原則來(lái)取代掉適當(dāng)?shù)奈募4嗽瓌t即所謂緩存文件置換機(jī)制。

緩存文件置換方法有:

  • 先進(jìn)先出算法(FIFO):最先進(jìn)入的內(nèi)容作為替換對(duì)象
  • 最近最少使用算法(LFU):最近最少使用的內(nèi)容作為替換對(duì)象
  • 最久未使用算法(LRU):最久沒(méi)有訪問(wèn)的內(nèi)容作為替換對(duì)象
  • 非最近使用算法(NMRU):在最近沒(méi)有使用的內(nèi)容中隨機(jī)選擇一個(gè)作為替換對(duì)象
type Lru struct {
    max   int
    l     *list.List
    Call  func(key interface{}, value interface{})
    cache map[interface{}]*list.Element
    mu    *sync.Mutex
}

type Node struct {
    Key interface{}
    Val interface{}
}

func NewLru(len int) *Lru {
    return &Lru{
        max:   len,
        l:     list.New(),
        cache: make(map[interface{}]*list.Element),
        mu:    new(sync.Mutex),
    }
}

func (l *Lru) Add(key interface{}, val interface{}) error {
    if l.l == nil {
        return errors.New("not init NewLru")
    }
    l.mu.Lock()
    defer l.mu.Unlock()
    if e, ok := l.cache[key]; ok { //以及存在
        e.Value.(*Node).Val = val
        l.l.MoveToFront(e)
        return nil
    }
    ele := l.l.PushFront(&Node{
        Key: key,
        Val: val,
    })
    l.cache[key] = ele
    if l.max != 0 && l.l.Len() > l.max {
        if e := l.l.Back(); e != nil {
            l.l.Remove(e)
            node := e.Value.(*Node)
            delete(l.cache, node.Key)
            if l.Call != nil {
                l.Call(node.Key, node.Val)
            }
        }
    }
    return nil
}

func (l *Lru) Get(key interface{}) (val interface{}, ok bool) {
    if l.cache == nil {
        return
    }
    l.mu.Lock()
    defer l.mu.Unlock()
    if ele, ok := l.cache[key]; ok {
        l.l.MoveToFront(ele)
        return ele.Value.(*Node).Val, true
    }
    return
}

func (l *Lru) GetAll() []*Node {
    l.mu.Lock()
    defer l.mu.Unlock()
    var data []*Node
    for _, v := range l.cache {
        data = append(data, v.Value.(*Node))
    }
    return data
}

func (l *Lru) Del(key interface{}) {
    if l.cache == nil {
        return
    }
    l.mu.Lock()
    defer l.mu.Unlock()
    if ele, ok := l.cache[key]; ok {
        delete(l.cache, ele)
        if e := l.l.Back(); e != nil {
            l.l.Remove(e)
            delete(l.cache, key)
            if l.Call != nil {
                node := e.Value.(*Node)
                l.Call(node.Key, node.Val)
            }
        }
    }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,667評(píng)論 1 32
  • 1.內(nèi)存的頁(yè)面置換算法 (1)最佳置換算法(OPT)(理想置換算法):從主存中移出永遠(yuǎn)不再需要的頁(yè)面;如無(wú)這樣的...
    杰倫哎呦哎呦閱讀 3,596評(píng)論 1 9
  • Python語(yǔ)言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個(gè)如下例子,分析運(yùn)行結(jié)果: 代碼一: a = 1 def...
    時(shí)光清淺03閱讀 569評(píng)論 0 0
  • Python語(yǔ)言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個(gè)如下例子,分析運(yùn)行結(jié)果: 代碼一: a = 1 def...
    伊森H閱讀 3,177評(píng)論 0 15
  • 8.1虛擬存儲(chǔ)的需求背景 虛擬內(nèi)存是非連續(xù)內(nèi)存分配的一個(gè)延續(xù),非連續(xù)內(nèi)存分配在存儲(chǔ)空間內(nèi)可以連續(xù)也可以不連續(xù)。虛擬...
    龜龜51閱讀 6,287評(píng)論 2 6

友情鏈接更多精彩內(nèi)容