Go实现LRU算法

LRU是什么?

  LRU是内存淘汰策略,LRU (Least recently used:最近最少使用)算法在缓存写满的时候,会根据所有数据的访问记录,淘汰掉未来被访问几率最低的数据。也就是说该算法认为,最近被访问过的数据,在将来被访问的几率最大。

那LRU使用什么实现的呢?双链表的话,那查询的时间复杂度不就是O(n)了,那应该怎么办,于是可以用双链表加Map的方式进行插入和查询,在插入的时候,把key,value 存到map中,那么这样查询的时候时间复杂读不就是O(n)了

假如现在我设定的内存就能存放5个数据块,现在进行插入

  下面一次性插入五个数据块,此时,如果再有元素想插入应该怎么办?

  如果内存被读满,那么他就会淘汰链表的最后一个元素,如果读取链表中的元素,他就会加载到链表的头部

代码的具体实现

代码和双链表的思想一样,只不过加入了一个hashmap

go 复制代码
package main

import (
	"fmt"
)

// LruNode创建双链表的节点
type LruNode struct {
	next, prev *LruNode
	Value      any
	Key        string
	list       *LRU
}
type LRU struct {
	Length   uint
	maxBytes uint
	Cache    map[string]*LruNode
	root     LruNode
}

func NewLRU() *LRU {
	return new(LRU).Init()
}
func (l *LRU) Init() *LRU {
	l.root.next = &l.root
	l.maxBytes = 5
	l.root.prev = &l.root
	l.Cache = make(map[string]*LruNode)
	l.Length = 0
	return l
}

// FrontBack 前插
func (l *LRU) FrontBack(k string, v any) {
	if node, ok := l.Cache[k]; !ok {
		nodeNow := &LruNode{Value: v, Key: k}
		l.Cache[k] = nodeNow
		l.insert(nodeNow, &l.root)
		if l.Length+1 > l.maxBytes {
			delete(l.Cache, l.root.prev.Key)
			l.delete(l.root.prev)
		}
	} else {
		delete(l.Cache, k)
		nodeNow := &LruNode{Value: v, Key: k}
		l.Cache[k] = node
		l.insert(nodeNow, &l.root)
	}

}

// GetValue 查找k,v
func (l *LRU) GetValue(k string) (val any, ok bool) {
	if node, ok := l.Cache[k]; ok {
		l.delete(node)
		l.insert(node, &l.root)
		return node.Value, ok
	}
	return nil, ok
}
func (l *LRU) insert(node, root *LruNode) {
	node.prev = root
	node.next = root.next
	node.prev.next = node
	node.next.prev = node
	l.Length++
	node.list = l
}
func (l *LRU) delete(node *LruNode) {
	node.prev.next = node.next
	node.next.prev = node.prev
	l.Length--
}

// PrintlnDList 打印双链表的所有元素
func (l *LRU) PrintlnDList1() {
	if l.Length == 0 {
	}
	prev := l.root.next
	index := 0
	for prev.Value != nil {
		fmt.Printf("下标index: %d 元素 Element: %d\n", index, prev.Value)
		prev = prev.next
		index++
	}
	return
}
func main() {
	a := NewLRU()
	a.FrontBack("1", 1)
	a.FrontBack("2", 2)
	a.FrontBack("3", 3)
	a.FrontBack("4", 4)
	a.FrontBack("5", 5)
	a.FrontBack("5", 5)
	a.FrontBack("6", 6)
	a.FrontBack("7", 7)
	a.GetValue("4")
	a.PrintlnDList1()
}
相关推荐
Navigator_Z30 分钟前
LeetCode //C++ - 1226. The Dining Philosophers
c语言·算法·leetcode
源代码•宸37 分钟前
前置准备:定时微服务背景和现状
开发语言·经验分享·后端·微服务·云原生·架构·golang
FOORIR37 分钟前
3D视觉+AI客流系统怎么做:从Sensor Pipeline到数据事件引擎
算法
2601_9673387138 分钟前
C#上位机开发零基础入门到精通全套视频
开发语言·c#
小白学大数据1 小时前
超简单:用 Python 让 Excel 飞起来:用 openpyxl 把重复报表整理交给脚本
开发语言·数据库·python·excel
旧梦95272 小时前
Java SortedMap 接口详解:从入门到实战
java·开发语言
莫陌尛.2 小时前
Java_this构造方法
java·开发语言
Persistent的粽子!2 小时前
C++:类与对象(二)
开发语言·c++
Dreams°1232 小时前
【Java后端+Vue前后端分离:内网正常、公网访问异常|5个高频经典踩坑完整复盘】
java·开发语言·vue.js
Omics Pro2 小时前
Arc研究所Cell|全新虚拟细胞官方基准评测框架
大数据·人工智能·深度学习·算法·机器学习