上一节中我们实现了随机缓存算法和FIFO缓存算法。现在,我们会继续实现另外两个著名的缓存算法:LFU和LRU。再一次说明,这些代码只是作为演示使用,如果你想在应用程序中使用,你还需要加上额外的工作。
看看LFU缓存算法的实现
public synchronized Object getElement(Object key) {
Object obj;
obj = table.get(key);
if (obj != null) {
CacheElement element = (CacheElement) obj;
element.setHitCount(element.getHitCount() + 1);
return element.getObjectValue();
}
return null;
}
public final synchronized void addElement(Object key, Object value) {
Object obj;
obj = table.get(key);
if (obj != null) {
CacheElement element;
// Just replace the value.
element = (CacheElement) obj;
element.setObjectValue(value);
element.setObjectKey(key);
return;
}
if (!isFull()) {
index = numEntries;
++numEntries;
} else {
CacheElement element = removeLfuElement();
index = element.getIndex();
table.remove(element.getObjectKey());
}
cache[index].setObjectValue(value);
cache[index].setObjectKey(key);
cache[index].setIndex(index);
table.put(key, cache[index]);
}
public CacheElement removeLfuElement() {
CacheElement[] elements = getElementsFromTable();
CacheElement leastElement = leastHit(elements);
return leastElement;
}
public static CacheElement leastHit(CacheElement[] elements) {
CacheElement lowestElement = null;
for (int i = 0; i < elements.length; i++) {
CacheElement element = elements[i];
if (lowestElement == null) {
lowestElement = element;
} else {
if (element.getHitCount() < lowestElement.getHitCount()) {
lowestElement = element;
}
}
}
return lowestElement;
}
最重点的代码,就应该是 leastHit 这个方法,这段代码就是把 hitCount 最低的元素找出来,然后删除,给新进的缓存元素留位置。
看看LRU缓存算法实现
private void moveToFront(int index) {
int nextIndex, prevIndex;
if(head != index) {
nextIndex = next[index];
prevIndex = prev[index];
// Only the head has a prev entry that is an invalid index so
// we don't check.
next[prevIndex] = nextIndex;
// Make sure index is valid. If it isn't, we're at the tail
// and don't set prev[next].
if(nextIndex >= 0)
prev[nextIndex] = prevIndex;
else
tail = prevIndex;
prev[index] = -1;
next[index] = head;
prev[head] = index;
head = index;
}
}
public final synchronized void addElement(Object key, Object value) {
int index;
Object obj;
obj = table.get(key);
if(obj != null) {
CacheElement entry;
// Just replace the value, but move it to the front.
entry = (CacheElement)obj;
entry.setObjectValue(value);
entry.setObjectKey(key);
moveToFront(entry.getIndex());
return;
}
// If we haven't filled the cache yet, place in next available spot
// and move to front.
if(!isFull()) {
if(_numEntries > 0) {
prev[_numEntries] = tail;
next[_numEntries] = -1;
moveToFront(numEntries);
}
++numEntries;
} else {
// We replace the tail of the list.
table.remove(cache[tail].getObjectKey());
moveToFront(tail);
}
cache[head].setObjectValue(value);
cache[head].setObjectKey(key);
table.put(key, cache[head]);
}
这段代码的逻辑如 LRU算法 的描述一样,把再次用到的缓存提取到最前面,而每次删除的都是最后面的元素。
结论
我们已经看到 LFU缓存算法 和 LRU缓存算法的实现方式,至于如何实现,采用数组还是 LinkedHashMap,都由你决定,不够我一般是小的缓存容量用数组,大的用LinkedHashMap。
在下面一节中,我们将扯扯缓存框架,他们使用的缓存算法,并且做一些比较。
相关推荐
目前,市面上有关计算机算法的书很多,有些叙述严谨但不全面,另外一些则是容量很大但不够严谨。本书将叙述的严谨性以及内容的深度和广度有机地结合了起来。第1版推出后,即在世界范围内受到了广泛的欢迎,被各高等...
目前,市面上有关计算机算法的书很多,有些叙述严谨但不全面,另外一些则是容量很大但不够严谨。本书将叙述的严谨性以及内容的深度和广度有机地结合了起来。第1版推出后,即在世界范围内受到了广泛的欢迎,被各高等...
优化程序性能通常包括减少时间复杂度和空间复杂度,理解缓存行为、使用适当的数据结构和算法等。C++提供了各种工具和库来测量和改进代码性能,如分析器、计时器等。 “03 数据描述”涉及到如何在计算机内存中表示...
5. **缓存优化**:通过合理安排矩阵访问模式,减少缓存未命中的次数,提高数据读取效率。比如,使用 Blocked Matrix Multiplication,使数据在内存层次结构内重用,减少内存带宽的需求。 6. **GPU加速**:现代GPU...
目 录 译者序 前言 第1章 概述 1 1.1 引言 1 1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 ...16.11.5 接收缓存的组织:没有报文边界 408 16.11.6 控制信息和带外数据 409 16.12 soreceive代码 410 16.13 select系统...
目 录 译者序 前言 第1章 概述 1 1.1 引言 1 1.2 源代码表示 1 1.2.1 将拥塞窗口设置为1 1 ...16.11.5 接收缓存的组织:没有报文边界 408 16.11.6 控制信息和带外数据 409 16.12 soreceive代码 410 16.13 select系统...
《TCP-IP详解》共3卷,其他卷请到我空间下载,第2卷共分两个part,请下载完两个part后在解压。本书完整而详细地介绍了TCP/IP协议是如何实现的。书中给出了约500个图例,15 000行实际操作的C代码,采用举例教学的方法...
《TCP-IP详解》共3卷,其他卷请到我空间下载,第2卷共分两个part,请下载完两个part后在解压。本书完整而详细地介绍了TCP/IP协议是如何实现的。书中给出了约500个图例,15 000行实际操作的C代码,采用举例教学的方法...
这一章详细讲解了页面替换算法、交换空间的管理以及Swapper进程的作用。 第十一章-内核同步:在多任务环境下,内核同步至关重要,以防止数据竞争和死锁。本章主要探讨了信号量、互斥锁、读写锁、自旋锁、条件变量等...
首先,SS7网络是一种基于消息传递的通信协议栈,由多个层次组成,包括MTP(Message Transfer Part)、SCCP(Signalling Connection Control Part)和TCAP(Transaction Capabilities Application Part)等。...
2.7.18块处理算法的优化 2.7.19大型数组排序的优化 2.8RAM测试问题 第3章高速缓存子系统 3.1SRAM的工作原理 3.1.1历史概况 3.1.2内核 3.1.3触发器的设计 3.1.4逻辑非元件(取反器)的设计 3.1.5SRAM阵列的设计 3.1.6...
2.7.18块处理算法的优化 2.7.19大型数组排序的优化 2.8RAM测试问题 第3章高速缓存子系统 3.1SRAM的工作原理 3.1.1历史概况 3.1.2内核 3.1.3触发器的设计 3.1.4逻辑非元件(取反器)的设计 3.1.5SRAM阵列的设计 3.1.6...
2.7.18块处理算法的优化 2.7.19大型数组排序的优化 2.8RAM测试问题 第3章高速缓存子系统 3.1SRAM的工作原理 3.1.1历史概况 3.1.2内核 3.1.3触发器的设计 3.1.4逻辑非元件(取反器)的设计 3.1.5SRAM阵列的设计 3.1.6...
综上所述,卡内基梅隆大学SSD5课程Part3的解答应涵盖数据结构中的核心概念和算法,包括排序、树结构、图论、动态规划、线性数据结构以及哈希表等。深入理解和熟练运用这些知识,对于任何从事软件开发的人来说,都是...
3. "p245-bernardi.pdf":Bernardi等作者可能在论文中讨论了无线传感器网络(WSN)的相关问题,如网络路由、数据聚合或是节能算法,他们的研究可能有助于改善WSN的可靠性和寿命。 4. "p233-kokku.pdf":Kokku等人的...
5. **评分机制(Scoring)**:Lucene通过TF-IDF算法和其他相关性计算方法,为搜索结果排序,最相关的文档优先展示。 6. **内存缓存与磁盘存储**:Lucene优化了内存和磁盘的使用,允许快速读取索引,同时保持索引的...
7. **碰撞检测**:游戏中的对象交互往往需要碰撞检测,这部分可能涵盖了简单的几何碰撞检测算法,如轴对齐包围盒(AABB)和射线碰撞检测。 8. **动画与运动**:介绍如何实现3D对象的平移、旋转和缩放,以及更复杂的...