哎,这让人抠脑壳的 LFU。 (下)

简介: 哎,这让人抠脑壳的 LFU。 (下)

比如下面这个例子:

image.png


假设最小访问频次就是 5,而 5 对应了 3 个 Node 对象。

此时,我要访问 value=b 的对象,那么该对象就会从 key=5 的 value 中移走。

然后频次加一,即 5+1=6。

加入到 key=6 的 value 集合中,变成下面这个样子:

image.png

也就是说我们得支持任意 node 的快速删除。

我们可以针对上面的需求,自定义一个双向链表。

但是在 Java 集合类中,有一个满足上面说的有序且支持快速删除的条件的集合。

那就是 LinkedHashSet。

所以,HashMap<freq,集合>,就是HashMap<freq,LinkedHashSet>。

总结一下。

我们需要两个 HashMap,分别是 HashMap<key,Node> 和 HashMap<freq,LinkedHashSet>。

然后还需要维护一个最小访问频次,minFreq。

哦,对了,还得来一个参数记录缓存支持的最大容量,capacity。

没了。

有的小伙伴肯定要问了:你倒是给我一份代码啊?

image.png


这些分析出来了,代码自己慢慢就撸出来了。

思路清晰后再去写代码,就算面试的时候没有写出 bug free 的代码,也基本上八九不离十了。


Dubbo 中的 LFU 算法


Dubbo 在 2.7.7 版本之后支持了 LFU 算法:

image.png

其源码的位置是:org.apache.dubbo.common.utils.LFUCache


image.png

代码不长,总共就 200 多行,和我们上面说的 LFU 实现起来还有点不一样。

你可以看到它甚至没有维护 minFreq。

但是这些都不重要,打个断点调试一下很快就能分析出来作者的代码思路。

重要的是,我在看 Dubbo 的 LFU 算法的时候发现了一个 bug。

不是指这个 LFU 算法实现上的 bug,算法实现我看了是没有问题的。

bug 是 Dubbo 虽然加入了 LFU 缓存算法的实现,但是作为使用者,却不能使用。

问题出在哪里呢?

我带你瞅一眼。

源码里面告诉我这样配置一下就可以使用 lfu 的缓存策略:

image.png

但是,当我这样配置,发起调用之后,是这样的:

image.png

可以看到当前请求的缓存策略确实是 lfu。

但是会抛出一个错误:

image.png

No such extension org.apache.dubbo.cache.CacheFactory by name lfu

没有 lfu 这个策略。

这不是玩我吗?

image.png

再看一下具体的原因。

org.apache.dubbo.common.extension.ExtensionLoader#getExtensionClasses处只获取到了 4 个缓存策略,并没有我们想要的 LFU:

image.png

所以,在这里抛出了异常:

image.png

为什么没有找到我们想要的 LFU 呢?

那就的看你熟不熟悉 SPI 了。

在 SPI 文件中,确实没有 lfu 的配置:

image.png

这就是 bug。

所以怎么解决呢?

非常简单,加上就完事了。

image.png

害,一不小心又给 Dubbo 贡献了一行源码。

image.png


最后说一句(求关注)


才疏学浅,难免会有纰漏,如果你发现了错误的地方,可以在后台提出来,我对其加以修改。

感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。

我是 why,一个主要写代码,经常写文章,偶尔拍视频的程序猿。

目录
相关文章
|
7月前
|
存储 缓存 算法
LRU(Least Recently Used)算法原理
LRU(Least Recently Used)算法原理
119 0
|
8月前
|
缓存 算法 Java
淘汰算法
【4月更文挑战第21天】这篇内容介绍了两种主流的淘汰算法:LRU(Least Recently Used)和LFU(Least Frequently Used)。LRU基于最近最少使用原则,当缓存满时,淘汰最近最久未使用的键。实现上通常使用链表和Java的LinkedHashMap。而LFU根据访问次数淘汰最不常使用的对象,可以按访问频率排序并选择淘汰。LFU的变种可能关注一定时间窗口内的访问次数,实现上更复杂。
54 1
|
8月前
|
算法 测试技术 C++
【状态压缩】【动态规划】【C++算法】691贴纸拼词
【状态压缩】【动态规划】【C++算法】691贴纸拼词
|
存储 NoSQL 算法
【LFU】一文让你弄清 Redis LFU 页面置换算法
【LFU】一文让你弄清 Redis LFU 页面置换算法
129 1
|
存储 缓存 算法
【算法】LFU及其优化
【算法】LFU及其优化
195 0
|
存储 缓存 算法
实现一个LRU真的好难呐
实现一个LRU真的好难呐
103 0
|
Java
红黑树(上)调色篇
红黑树是配合二叉树的一种实现,主要要满足以下性质: 1.根节点必须为黑色 2.父子不能同为红色 3.从任何节点出发,到达叶节点经过的黑色节点数量一致 对每个新插入的节点存在以下情况: 1.没有爸爸: 那么它自己变为黑色,做根节点。
95 0
|
机器学习/深度学习 存储 算法
自适应共振网络理论-2|学习笔记
快速学习自适应共振网络理论-2
自适应共振网络理论-2|学习笔记
|
机器学习/深度学习 缓存 算法
面试高频算法详解-LRU
面试高频算法详解-LRU
面试高频算法详解-LRU
|
缓存 算法 C++
哎,这让人抠脑壳的 LFU。 (上)
哎,这让人抠脑壳的 LFU。 (上)
130 0
哎,这让人抠脑壳的 LFU。 (上)