• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

LRU算法的GO语言实现

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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)
}

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
use of internal package github.com/go-kratos/kratos/v2/internal/httputil not all ...发布时间:2022-07-10
下一篇:
66_Go基础_1_33指针发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap