go语言实现LRU缓存

go语言实现LRU Cache

题目描述

设计和构建一个"最近最少使用"缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。

它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。

写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

详细代码

go 复制代码
type LRUCache struct {
	capacity   int
	m          map[int]*Node
	head, tail *Node
}

type Node struct {
	Key       int
	Value     int
	Pre, Next *Node
}

func Constructor(capacity int) LRUCache {
	head, tail := &Node{}, &Node{}
	head.Next = tail
	tail.Pre = head
	return LRUCache{
		capacity: capacity,
		m:        map[int]*Node{},
		head:     head,
		tail:     tail,
	}
}

func (this *LRUCache) Get(key int) int {
	// 存在,放到头
	if v, ok := this.m[key]; ok {
		this.moveToHead(v)
		return v.Value
	}
	// 不存在,返回-1
	return -1
}

func (this *LRUCache) Put(key int, value int) {
	// 已经存在了
	if v, ok := this.m[key];ok{
		v.Value = value
		this.moveToHead(v)
		return 
	}
	if this.capacity==len(this.m){
		rmKey := this.removeTail()
		delete(this.m ,rmKey)
	}
	newNode := &Node{Key: key, Value: value}
	this.m[key] = newNode
	this.addToHead(newNode)
}

func (this *LRUCache) moveToHead(node *Node) {
	this.deleteNode(node)
	this.addToHead(node)
}

func (this *LRUCache) deleteNode(node *Node) {
	node.Pre.Next = node.Next
	node.Next.Pre = node.Pre
}

func (this *LRUCache) addToHead(node *Node) {
	// 先让node位于现存第一位元素之前
	this.head.Next.Pre = node
	// 通过node的next指针让原始第一位元素放到第二位
	node.Next = this.head.Next
	// 捆绑node和head的关系
	this.head.Next = node
	node.Pre = this.head
}

func (this *LRUCache)removeTail()int{
	node := this.tail.Pre
    this.deleteNode(node)
    return node.Key
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * obj := Constructor(capacity);
 * param_1 := obj.Get(key);
 * obj.Put(key,value);
 */
相关推荐
江晓鱼未暖11 小时前
十七、Redis 核心原理与架构详解
大数据·数据库·数据仓库·redis·缓存·架构
小罗水11 小时前
第13章 Redis 缓存、幂等锁与任务状态
数据库·redis·缓存
热心市民lcj11 小时前
Spring Boot 整合 Caffeine 本地缓存实战
spring boot·后端·缓存
zx11545013 小时前
【热点 Key 探测与加长缓存 TTL 实战】
缓存
geovindu13 小时前
go:loghelper
开发语言·后端·golang
会编程的土豆15 小时前
GoWeb 处理请求详解:请求行、请求头、请求参数与给客户端响应
开发语言·http·golang
toooooop81 天前
如何用 ss + ps 精准定位本机 Redis 的“隐形”消费者?
linux·数据库·redis·缓存
软萌萌的11 天前
C#中的多级缓存架构设计与实现深度解析
缓存·c#·wpf
醉城夜风~1 天前
HTML表单域学习博客:表单标签、输入框、按钮详解
android·java·缓存
肥胖小羊1 天前
企业微信应用的 Token 缓存策略与分布式锁高可用设计
分布式·缓存·企业微信