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()
}
go实现LFU算法
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 姓名:白国乐 学号:17021210898 专业:信号与信息处理 转载自:http://blog.csdn.net...
- 最近由于工作的需要,需要的实现一个go的Blowfish算法。其实go本身有一个加密算法库crypto,其中有Bl...
- PoW共识算法是一种基于算力的共识算法,我们需要在挖矿的过程当中找到其相应的解,从而获得“挖矿奖励”,但要找到这个...