`
lengrenhanbing
  • 浏览: 48076 次
  • 性别: Icon_minigender_1
  • 来自: 泰安
社区版块
存档分类
最新评论

有关缓存,缓存算法,缓存框架:part 5 [转]

 
阅读更多

上一节中我们实现了随机缓存算法和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。

在下面一节中,我们将扯扯缓存框架,他们使用的缓存算法,并且做一些比较。


分享到:
评论

相关推荐

    算法导论(part1)

    目前,市面上有关计算机算法的书很多,有些叙述严谨但不全面,另外一些则是容量很大但不够严谨。本书将叙述的严谨性以及内容的深度和广度有机地结合了起来。第1版推出后,即在世界范围内受到了广泛的欢迎,被各高等...

    算法导论(part2)

    目前,市面上有关计算机算法的书很多,有些叙述严谨但不全面,另外一些则是容量很大但不够严谨。本书将叙述的严谨性以及内容的深度和广度有机地结合了起来。第1版推出后,即在世界范围内受到了广泛的欢迎,被各高等...

    数据结构与算法C++语言描述part1

    优化程序性能通常包括减少时间复杂度和空间复杂度,理解缓存行为、使用适当的数据结构和算法等。C++提供了各种工具和库来测量和改进代码性能,如分析器、计时器等。 “03 数据描述”涉及到如何在计算机内存中表示...

    Algorithm-Matrix-Multiply-Part1.zip

    5. **缓存优化**:通过合理安排矩阵访问模式,减少缓存未命中的次数,提高数据读取效率。比如,使用 Blocked Matrix Multiplication,使数据在内存层次结构内重用,减少内存带宽的需求。 6. **GPU加速**:现代GPU...

    TCP-IP详解卷二:实现part2

    目 录 译者序 前言 第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详解卷二:实现part1

    目 录 译者序 前言 第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详解卷2:实现.part1

    《TCP-IP详解》共3卷,其他卷请到我空间下载,第2卷共分两个part,请下载完两个part后在解压。本书完整而详细地介绍了TCP/IP协议是如何实现的。书中给出了约500个图例,15 000行实际操作的C代码,采用举例教学的方法...

    TCP-IP详解卷2:实现.part2

    《TCP-IP详解》共3卷,其他卷请到我空间下载,第2卷共分两个part,请下载完两个part后在解压。本书完整而详细地介绍了TCP/IP协议是如何实现的。书中给出了约500个图例,15 000行实际操作的C代码,采用举例教学的方法...

    深入理解Linux(Understanding the linux kernel)-part2

    这一章详细讲解了页面替换算法、交换空间的管理以及Swapper进程的作用。 第十一章-内核同步:在多任务环境下,内核同步至关重要,以防止数据竞争和死锁。本章主要探讨了信号量、互斥锁、读写锁、自旋锁、条件变量等...

    网络游戏-SS7网络中的负载分摊.zip

    首先,SS7网络是一种基于消息传递的通信协议栈,由多个层次组成,包括MTP(Message Transfer Part)、SCCP(Signalling Connection Control Part)和TCAP(Transaction Capabilities Application Part)等。...

    代码优化:有效使用内存.part3

    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...

    代码优化:有效使用内存.part1

    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...

    代码优化:有效使用内存.part2

    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(共三部分).rar

    综上所述,卡内基梅隆大学SSD5课程Part3的解答应涵盖数据结构中的核心概念和算法,包括排序、树结构、图论、动态规划、线性数据结构以及哈希表等。深入理解和熟练运用这些知识,对于任何从事软件开发的人来说,都是...

    mobicom2010的论文集合part_3

    3. "p245-bernardi.pdf":Bernardi等作者可能在论文中讨论了无线传感器网络(WSN)的相关问题,如网络路由、数据聚合或是节能算法,他们的研究可能有助于改善WSN的可靠性和寿命。 4. "p233-kokku.pdf":Kokku等人的...

    Lucene+nutch开发自己的搜索引擎 part2

    5. **评分机制(Scoring)**:Lucene通过TF-IDF算法和其他相关性计算方法,为搜索结果排序,最相关的文档优先展示。 6. **内存缓存与磁盘存储**:Lucene优化了内存和磁盘的使用,允许快速读取索引,同时保持索引的...

    Android.3D游戏开发技术宝典:OpenGL.ES.2.0【part2】

    7. **碰撞检测**:游戏中的对象交互往往需要碰撞检测,这部分可能涵盖了简单的几何碰撞检测算法,如轴对齐包围盒(AABB)和射线碰撞检测。 8. **动画与运动**:介绍如何实现3D对象的平移、旋转和缩放,以及更复杂的...

Global site tag (gtag.js) - Google Analytics