Go语言实现LRU算法

LRU 通常使用hash map + doubly linked list实现。在Golange中很简单,使用List保存数据,Map来做快速访问即可.

具体实现了下面几个函数:

func NewLRUCache(cap int)(*LRUCache)
func (lru *LRUCache)Set(k,v interface{})(error)
func (lru *LRUCache)Get(k interface{})(v interface{},ret bool,err error)
func (lru *LRUCache)Remove(k interface{})(bool)

演示:

package main

//LRU Cache
//author:Xiong Chuan Liang
//date:2015-2-3

import (
	"fmt"
	"github.com/xcltapestry/xclpkg/algorithm"
)

func main(){

	lru := algorithm.NewLRUCache(3)

	lru.Set(10,"value1")
	lru.Set(20,"value2")
	lru.Set(30,"value3")
	lru.Set(10,"value4")
	lru.Set(50,"value5")

	fmt.Println("LRU Size:",lru.Size())
	v,ret,_ := lru.Get(30)
	if ret  {
		fmt.Println("Get(30) : ",v)
	}

	if lru.Remove(30) {
		fmt.Println("Remove(30) : true ")
	}else{
		fmt.Println("Remove(30) : false ")
	}
	fmt.Println("LRU Size:",lru.Size())
}

运行结果:

LRU Size: 3
Get(30) :  value3
Remove(30) : true
LRU Size: 2

具体的 实现源码:

package algorithm

//LRU Cache
//author:Xiong Chuan Liang
//date:2015-2-3
//"github.com/xcltapestry/xclpkg/algorithm"  

import (
	"container/list"
	"errors"
)

type CacheNode struct {
	Key,Value interface{}
}

func (cnode *CacheNode)NewCacheNode(k,v interface{})*CacheNode{
	return &CacheNode{k,v}
}

type LRUCache struct {
	Capacity int
	dlist *list.List
	cacheMap map[interface{}]*list.Element
}

func NewLRUCache(cap int)(*LRUCache){
	return &LRUCache{
				Capacity:cap,
				dlist: list.New(),
				cacheMap: make(map[interface{}]*list.Element)}
}

func (lru *LRUCache)Size()(int){
	return lru.dlist.Len()
}

func (lru *LRUCache)Set(k,v interface{})(error){

	if lru.dlist == nil {
		return errors.New("LRUCache结构体未初始化.")
	}

	if pElement,ok := lru.cacheMap[k]; ok {
		lru.dlist.MoveToFront(pElement)
		pElement.Value.(*CacheNode).Value = v
		return nil
	}

	newElement := lru.dlist.PushFront( &CacheNode{k,v} )
	lru.cacheMap[k] = newElement

	if lru.dlist.Len() > lru.Capacity {
		//移掉最后一个
		lastElement := lru.dlist.Back()
		if lastElement == nil {
			return nil
		}
		cacheNode := lastElement.Value.(*CacheNode)
		delete(lru.cacheMap,cacheNode.Key)
		lru.dlist.Remove(lastElement)
	}
	return nil
}

func (lru *LRUCache)Get(k interface{})(v interface{},ret bool,err error){

	if lru.cacheMap == nil {
		return v,false,errors.New("LRUCache结构体未初始化.")
	}

	if pElement,ok := lru.cacheMap[k]; ok {
		lru.dlist.MoveToFront(pElement)
		return pElement.Value.(*CacheNode).Value,true,nil
	}
	return v,false,nil
}

func (lru *LRUCache)Remove(k interface{})(bool){

	if lru.cacheMap == nil {
		return false
	}

	if pElement,ok := lru.cacheMap[k]; ok {
		cacheNode := pElement.Value.(*CacheNode)
		delete(lru.cacheMap,cacheNode.Key)
		lru.dlist.Remove(pElement)
		return true
	}
	return false
}

附注:

1.key记录在map

2.对于set/get添加或命中的元素移到链表头

3.如总个数大于Cache容量(cap),则将最末的元素移除.

MAIL: [email protected]

BLOG:http://blog.csdn.net/xcl168

时间: 2024-10-08 09:45:20

Go语言实现LRU算法的相关文章

C语言实现FIFO算法与LRU算法

在操作系统中,当程序在运行过程中,若其所要访问的页面不再内存中而需要把他们调入内存,但内存已无空闲空间时,为了保证该进程能正常运行,系统必须从内存调出一页程序或数据送磁盘的兑换区中.但哪一个页面调出,须根据一定的算法确定.通常,把选择换出页面的算法称为页面置换算法(Page-Replacement Algorithms).置换算法的好坏将直接影响到系统的性能. 1) 先进先出(FIFO)页面置换算法 该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰.该算法实现简单,只需

缓存淘汰算法--LRU算法

1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高". 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部: 3. 当链表满的时候,将链表尾部的数据丢弃. 1.3. 分析 [命中率] 当存在热点数据时,LRU的效率很好,但偶发性的

redis的LRU算法(一)

最近加班比较累,完全不想写作了.. 刚看到一篇有趣的文章,是redis的作者antirez对redis的LRU算法的回顾.LRU算法是Least Recently Used的意思,将最近最少使用的资源丢掉.Redis经常被用作cache,如果能够将不常用的key移除,尽量保留常用的,那内存的利用率就相当高了.当然,LRU也有弱点,考虑下面一种情况: ~~~~~A~~~~~A~~~~~A~~~~A~~~~~A~~~~~A~~| ~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~

LRU算法 - LRU Cache

这个是比较经典的LRU(Least recently used,最近最少使用)算法,算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 一般应用在缓存替换策略中.其中的”使用”包括访问get和更新set. LRU算法 LRU是Least Recently Used 近期最少使用算法.内存管理的一种页面置换算法,对于在内存中但又不用的数据快(内存块)叫做LRU,Oracle会根据那些数据属于LRU而将其移出内存而腾出空间来加载另外的数据,一

LRU算法的Python实现

LRU:least recently used,最近最少使用算法.它的使用场景是:在有限的空间中存储对象时,当空间满时,会一定的原则删除原有的对象,常用的原则(算法)有LRU,FIFO,LFU等.在计算机的Cache硬件,以及主存到虚拟内存的页面置换,还有Redis缓存系统中都用到了该算法.我在一次面试和一个笔试时,都遇到过这个问题. LRU的算法是比较简单的,当对key进行访问时(一般有查询,更新,增加,在get()和set()两个方法中实现即可)时,将该key放到队列的最前端(或最后端)就行

关于LRU算法(转载)

原文地址: http://flychao88.iteye.com/blog/1977653 http://blog.csdn.net/cjfeii/article/details/47259519 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高". 1.2.实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部: 2. 每当缓存命

Android 图像压缩,和LRU算法使用的推荐链接

近两日,看的关于这些方面的一些教程数十篇,最好的当属google原版的教程了.国内有不少文章是翻译这个链接的. 需要注意的一点是:Android的SDK中的LRU算法在V4包和Util包中各有一个,推荐使用V4包中的. 在此,推荐两个链接: https://developer.android.com/intl/ru/training/displaying-bitmaps/process-bitmap.html http://android-developers.blogspot.jp/2010/

探究redis和memcached的 LRU算法--------redis的LRU的实现

一直对这redis和memcached的两个开源缓存系统的LRU算法感兴趣.今天就打算总结一下这两个LRU算法的实现和区别. 首先要知道什么是LRU算法:LRU是Least Recently Used 近期最少使用算法.相关的资料网上一大堆.http://en.wikipedia.org/wiki/Cache_algorithms#LRU   redis的六种策略 rewriteConfigEnumOption(state,"maxmemory-policy",server.maxme

Android探索之图片缓存<Lru算法>(二)

前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发生的概率呢?之前我们一直在使用SoftReference软引用,SoftReference是一种现在已经不再推荐使用的方式,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用变得不再可靠,所以今天我们来认识一种新的缓存处理算法