【golang项目-GeeCache】动手写分布式缓存 day1 - 实现LRU算法

索引

【go项目-geecache】动手写分布式缓存 - day1 - 实现LRU算法
【go项目-geecache】动手写分布式缓存 - day2 - 单机并发缓存
【go项目-geecache】动手写分布式缓存 - day3 - HTTP 服务端
【go项目-geecache】动手写分布式缓存 - day4 - 一致性哈希(hash)
【go项目-geecache】动手写分布式缓存 - day5 - 分布式节点
【go项目-geecache】动手写分布式缓存 - day6 - 防止缓存击穿
【go项目-geecache】动手写分布式缓存 - day7 - 使用 Protobuf 通信

介绍 LRU 内存淘汰算法

LRU(Least Recently Used) 最近最少使用 算法 ,系统认为如果这个数据最近使用过那么它被再次使用的概率会高,所以系统会先淘汰最久没被使用的数据

基本逻辑

在这里插入图片描述

-----------------------------------------------------------------------出自极客兔兔
k(绿色)为map,即实际中的缓存,当我们读取数据时就是先从这个查询和获取,复杂度为log 级别,非常快
n(红色)为双向链表,用来记录哪个数据是最晚出现的,使用双向链表的原因是为了快速让数据放在队首/队尾,当我们访问一个数据时,我们把这个数据放在链表队首,当我们需要淘汰内存时我们删除队尾的数据,这个数据就是最晚出现的

具体实现

实现数据结构
  1. 实现Cache,包含允许的最大缓存,当前的缓存,双向链表,map,回调函数
type Cache struct {
   
    maxBytes  int64                         // 允许的最大内存
    nbytes    int64                         // 已使用的内存
    ll        *list.List                    //双向链表
    cache     map[string]*list.Element      // map
    OnEvicted func(key string, value Value) //是某条记录被移除时的回调函数
}
  1. 实现双向链表的数据类型,便于删除双向链表时根据key删除map的值
type entry struct {
    // 代表双向链表的数据类型
    key   string
    value Value
}
  1. 为了存取数据的通用性,实现Len()获取元素个数
type Value interface {
     
	Len() int  
}
初始化缓存函数
func New(maxBytes int64, onEvicted func(string, Value)) *Cache {
    // 创建
    return &Cache{
   
        maxBytes:  maxBytes,
        ll:        list.New(),
        cache:     make(map[string]*list.Element),
        OnEvicted: onEvicted,
    }
}
实现查找功能

这个函数首先在缓存(map)中查询是否存在,如果存在就返回这个值,并且把这个值放在双向链表的首部,也标记成最新出现

func (c *Cache) Get(key string) (value Value, ok bool) {
    // 查找
    if ele, ok := c.cache[key]; ok {
   
        c.ll.MoveToFront(ele)    // 移动到队首
        kv := ele.Value.(*entry) // 找到值
        return kv.value, true
    }
    return
}

在这里写的时候 我对这段代码有疑惑

 kv := ele.Value.(*entry) // 找到值

错误的认为ele.Value.(T) 是 Value中的一个成员变量,但实际又不是
实际上这是接口类型的类型转换 Value.(Type) 是吧接口类型Value转换成Type类型

补充知识 :Go语言接口和类型之间的转换
类型断言

类型断言用于将接口类型转换为指定类型,其语法为:
value.(type) 或者 value.(T)

类型转换

类型转换用于将一个接口类型的值转换为另一个接口类型,其语法为:
T(value)

实现内存淘汰功能 即删除

内存删除就是移除最近最少访问的节点,就是删除队尾,然后修改当前缓存大小,使用回调函数通知系统

func (c *Cache) RemoveOldest() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值