go实现LFU算法

package main
/*
算法:页面cache算法之LFU(Least Frequently Used),优先淘汰最少使用的数据
基于:如果一个数据最近被使用的次数很少,将来被使用的可能性也很小
特点:优先淘汰最少使用的数据
实现:最小堆+hashmap。最小堆按使用次数来排队,hashmap用来加速查找
插入/删除:O(logN),查找:O(1)
*/

import (
    "container/heap"
    "fmt"
    //"errors"
)

type Item struct {
    value       string
    priority    int
    index       int
}

type PriorityQueue []*Item

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
    return pq[i].priority < pq[j].priority
}

func (pq PriorityQueue) Swap(i, j int) {
    pq[i], pq[j] = pq[j], pq[i]
    pq[i].index = i
    pq[j].index = j
}

func (pq *PriorityQueue) Push(x interface{}) {
    n := len(*pq)
    item := x.(*Item)
    item.index = n
    *pq = append(*pq, item)
}

func (pq *PriorityQueue) Pop() interface{} {
    old := *pq
    n := len(old)
    item := old[n-1]
    item.index = -1 // for safety
    *pq = old[0 : n-1]
    return item
}

// update modifies the priority and value of an Item in the queue.
func (pq *PriorityQueue) update(item *Item, value string, priority int) {
    item.value = value
    item.priority = priority    
    heap.Fix(pq, item.index)
}

func minheap_test() {

    items := map[string]int{
        "banana": 3, "apple": 2, "pear": 4,
    }   
    // Create a priority queue, put the items in it, and
    // establish the priority queue (heap) invariants.
    pq := make(PriorityQueue, len(items))
    i := 0
    for value, priority := range items {
        pq[i] = &Item{
            value:    value,
            priority: priority,
            index:    i,
        }
        i++
    }
    heap.Init(&pq)

    // Insert a new item and then modify its priority.
    item := &Item{
        value:    "orange",
        priority: 1,
    }
    heap.Push(&pq, item)
    pq.update(item, item.value, 5)

    // Take the items out; they arrive in decreasing priority order.
    for pq.Len() > 0 {
        item := heap.Pop(&pq).(*Item)
        fmt.Printf("%.2d:%s\n", item.priority, item.value)
    }
}

type cache_lfu struct {
    minheap PriorityQueue
    kmap map[string] *Item
}

func (lfu* cache_lfu)init(size int) {
    lfu.minheap = make([]*Item, 0, size)
    heap.Init(&(lfu.minheap))
    lfu.kmap = make(map[string] *Item)
}

func (lfu* cache_lfu)set(val string) {
    if(len(lfu.minheap) == cap(lfu.minheap)) {
        item := heap.Pop(&(lfu.minheap)).(*Item)
        fmt.Printf("pop %s\n", item.value);
    }

    item := &Item{value:val, priority:0}

    heap.Push(&(lfu.minheap), item)
    heap.Fix(&(lfu.minheap), item.index)

    lfu.kmap[val] = item
}

func (lfu* cache_lfu)get(val string) {
    item,ok := lfu.kmap[val]
    if(ok) {
        item.priority += 1
        heap.Fix(&(lfu.minheap), item.index)
    }
}

func (lfu *cache_lfu)print() {
    for lfu.minheap.Len() > 0 {
        item := heap.Pop(&(lfu.minheap)).(*Item)
        fmt.Printf("%d:%s\n", item.priority, item.value)
    }   
}

func lfu_test() {
    var lfu cache_lfu
    lfu.init(5)

    items := [5]string {"banana","apple","pear", "mango", "watermelon"}

    for _,val := range items {
        lfu.set(val)
    }

    lfu.get("apple")
    lfu.get("apple")
    lfu.get("pear")
    lfu.print()

    for _,val := range items {
        lfu.set(val)
    }

    lfu.get("apple")
    lfu.get("apple")
    lfu.get("apple")
    lfu.get("apple")
    lfu.get("apple")
    lfu.get("pear")
    lfu.get("pear")
    lfu.get("pear")
    lfu.get("pear")
    lfu.get("banana")
    lfu.get("banana")
    lfu.get("banana")
    lfu.get("mango")
    lfu.get("mango")
    lfu.get("watermelon")

    // pop watermelon this time
    lfu.set("pipeapple")
    //lfu.print()
}
func main() {

    minheap_test()
    lfu_test()
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容