LRU算法的GO语言实现

LRU算法原理,图片来自https://mp.weixin.qq.com/s/h_Ns5HY27NmL_odCYLgx_Q

1.假设我们使用哈希链表来缓存用户信息,目前缓存了4个用户,这4个用户是按照时间顺序依次从链表右端插入的

2.此时,业务方访问用户5,由于哈希链表中没有用户5的数据,我们从数据库中读取出来,插入到缓存当中。这时候,链表中最右端是最新访问到的用户5,最左端是最近最少访问的用户1。

3.接下来,业务方访问用户2,哈希链表中存在用户2的数据,我们怎么做呢?我们把用户2从它的前驱节点和后继节点之间移除,重新插入到链表最右端。这时候,链表中最右端变成了最新访问到的用户2,最左端仍然是最近最少访问的用户1

4.接下来,业务方请求修改用户4的信息。同样道理,我们把用户4从原来的位置移动到链表最右侧,并把用户信息的值更新。这时候,链表中最右端是最新访问到的用户4,最左端仍然是最近最少访问的用户1。

5.后来业务方换口味了,访问用户6,用户6在缓存里没有,需要插入到哈希链表。假设这时候缓存容量已经达到上限,必须先删除最近最少访问的数据,那么位于哈希链表最左端的用户1就会被删除掉,然后再把用户6插入到最右端。

 

GO程序实现:

/*
@Time : 18-11-5 上午10:41 
@Author : xbx
@File : lru
@Software: GoLand
*/
package main

import "fmt"

type Node struct {
	Key string
	Value string
	pre *Node
	next *Node
}

func (n *Node)Init(key string, value string){
	n.Key = key
	n.Value = value
}

var head *Node
var end *Node

var limit int



type LRUCache struct {
	limit int
	HashMap map[string]*Node
}

func GetLRUCache(limit int) *LRUCache{
	lruCache := LRUCache{limit:limit}
	lruCache.HashMap = make(map[string]*Node, limit)
	return &lruCache
}

func (l *LRUCache)get(key string) string{
	if v,ok:= l.HashMap[key];ok {
		l.refreshNode(v)
		return v.Value
	}else {
		return ""
	}
}

func (l *LRUCache)put(key , value string) {
	if v,ok := l.HashMap[key];!ok{
		if(len(l.HashMap) >= l.limit){
			oldKey := l.removeNode(head)
			delete(l.HashMap, oldKey)
		}
		node := Node{Key:key, Value:value}
		l.addNode(&node)
		l.HashMap[key] = &node
	}else {
		v.Value = value
		l.refreshNode(v)
	}
}


func (l *LRUCache) refreshNode(node *Node){
	if (node == end) {
		return
	}
	l.removeNode(node)
	l.addNode(node)
}

func (l *LRUCache) removeNode(node *Node) string{
	if (node == end ) {
		end = end.pre
	}else if(node == head){
		head = head.next
	}else {
		node.pre.next = node.next
		node.next.pre = node.pre
	}
	return node.Key
}


func (l *LRUCache) addNode(node *Node){
	if (end != nil){
		end.next = node
		node.pre = end
		node.next = nil
	}
	end = node
	if (head == nil) {
		head = node
	}
}

func main(){
	lruCache := GetLRUCache(5)
	lruCache.put("001", "用户1信息")
	lruCache.put("002", "用户1信息")
	lruCache.put("003", "用户1信息")
	lruCache.put("004", "用户1信息")
	lruCache.put("005", "用户1信息")
	lruCache.get("002")
	lruCache.put("004", "用户2信息更新")
	lruCache.put("006", "用户6信息更新")
	fmt.Println(lruCache.get("001"))


	fmt.Println(lruCache.get("006"))
	fmt.Print(lruCache.HashMap)
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值