`
cjf068
  • 浏览: 34427 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

简单LRU缓存实现

 
阅读更多
链表保存键值,由于没有权值策略,简单的将当前访问过的节点放到链表头部,则存在如下问题:

在周期性访问中,某个周期中存在一部分数据仅仅只访问了一次,则最终导致缓存中的数据都是无效的数据,而将频繁访问的数据排除了。在实际应用中,这种简单策略不适用。

TestCode

public class LRUCacheTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		LRUCache cache = new LRUCache(10);
		
		for(int i=0;i<100;i++)
		{
			cache.put(i+"", "hello_"+i);
//			System.out.println(cache.size());
		}
		cache.printFrontTrace();
		System.out.println();
		cache.printBackwardTrace();
		System.out.println("\n-------------");
		cache.remove("90");
		cache.printFrontTrace();
		System.out.println();
		cache.printBackwardTrace();
		

		System.out.println("\n"+cache.get("92"));
		System.out.println("\n-------------");
		
		cache.printFrontTrace();
		
		System.out.println("\n"+cache.get("91"));//get tail
		System.out.println("\n-------------");
		cache.printFrontTrace();
		
		System.out.println("\n"+cache.get("91"));//get head
		System.out.println("\n-------------");
		cache.printFrontTrace();
		
		cache.remove("91");//remove head
		System.out.println("\n-------------");
		cache.printFrontTrace();
//		
		cache.remove("93");//remove tail
		System.out.println("\n-------------");
		cache.printFrontTrace();
		
		
		for(int i=0;i<100;i++)//remove all
		{
			cache.remove(i+"");
//			System.out.println(cache.size());
		}
		System.out.println("\n-------------now size = "+cache.size());
		cache.printFrontTrace();
	}

}



LRU缓存类,采用双向链表保存键,Hash保存值
package org.jf.alg.lru;

import java.util.HashMap;
import java.util.Map;

/**
 * 
 * LRU 简单实现
 * 双向链表+HashMap
 * @author chenjf
 *
 */
public class LRUCache 
{

	private KeyNode head;//key值的链表头 (包含数据)
	private KeyNode tail;//key值的链表尾 (包含数据)
	private int capacity;
	private int size;

	
	private Map<Object,CacheObject> map = new HashMap<Object,CacheObject>();
	
	
	
	public LRUCache(int capacity)
	{
		this.capacity=capacity;
	}
	
	
	
	public void put(Object key,Object value)
	{
		if(value==null)
			return;
		Object obj = this.get(key);
		if(obj!=null)
		 return;
		
	
		KeyNode node = new KeyNode(key);
		CacheObject cache_obj = new CacheObject(node,value);
		map.put(key, cache_obj);
		if(head==null)
		{
			head = node;
			tail = node;
			size++;
		}else
		{
			head.previous  = node;
			node.next = head;
			head = node;
			size++;
			if(size>capacity)
			{
				remove(tail.key);
			}
			
		}
		
		
	}
	
	public Object remove(Object key)
	{
		Object data = null;
		Object obj = map.remove(key);
		if(obj!=null)
		{
			CacheObject cache_obj = (CacheObject)obj;
			KeyNode node = cache_obj.keyNode;
			if(size==1)
			{
				head = null;
				tail = null;
			}else
			{
				if(node.equals(head))
				{
					if(head.next!=null)//not tail
						head.next.previous = null;
				    head = head.next;
				    node.next = null;
					
				}else if(node.equals(tail))
				{
					tail = node.previous;
					if(tail!=null)
					{
						tail.next = null;
					}
					node.previous = null;
				}else// not head and tail
				{
					node.previous.next=node.next;
					node.next.previous=node.previous;
					node.previous=null;
					node.next=null;
				}

			}
			data = cache_obj.data;
			size--;
		}
		
		return data;
	}
	
	public Object get(Object key)
	{
		
		Object data = null;
		Object obj = map.get(key);
		if(obj!=null)
		{
			CacheObject cache_obj = (CacheObject)obj;
		
			KeyNode node = cache_obj.keyNode;
			if(!node.equals(head))//if node is head, nothing to do
			{

					node.previous.next = node.next;
					if(node.next!=null)
						node.next.previous = node.previous;
					else// node is tail
						tail = node.previous;
					node.next = head;
					head.previous = node;
					node.previous = null;
					head = node;

				
				
			}
			data = cache_obj.data;
		}
		
		return data;
	}
	
	public void clear()
	{
		head = null;
		tail = null;
		size = 0;
		map.clear();
	}
	
	public int size()
	{
		return this.size;
	}
	
	public int getCapacity()
	{
		return this.capacity;
	}
	
	/**
	 * 
	 * for debug
	 */
	
	public void printFrontTrace()
	{
		
		//print front  from head to tail
		if(head!=null)
		{
			KeyNode node = head;
			while(node!=null)
			{
				System.out.print("-->"+node.key+"["+map.get(node.key).data+"]");
				node=node.next;
			}
		}
		
	}
	
	public void printBackwardTrace()
	{
		if(tail!=null)
		{
			KeyNode node = tail;
			while(node!=null)
			{
				System.out.print("<--"+node.key+"["+map.get(node.key).data+"]");
				node=node.previous;
			}
		}
	}
	
/****************************inner class from object store**************************************/
	
	class KeyNode 
	{

		KeyNode previous;
		KeyNode next;
		Object key;
		
		 public KeyNode(Object key)
		 {
			this.key = key; 
		 }

	}

	   
	class CacheObject
	{
		public CacheObject(KeyNode node,Object data)
		{
			keyNode = node;
			this.data = data;
		}
		KeyNode keyNode;
		Object data;

	}
}



分享到:
评论

相关推荐

    Go-一个简单高效用于go的LRU缓存包

    在Go语言中,有许多库可以帮助开发者实现LRU缓存,其中"Go-一个简单高效用于go的LRU缓存包"就是一个这样的工具。这个包为Go程序员提供了简单、高效的LRU缓存接口,便于在应用程序中管理和优化数据存储。 在Go语言中...

    Java实现简单LRU缓存算法

    这里的LRUCache类维护了一个双向链表和一个哈希表,用于实现LRU算法。具体实现细节如下: - get方法:首先在哈希表中查找对应的键值对,如果不存在,则返回-1;如果存在,则将对应的节点从双向链表中删除,并将其...

    quicklru简单的最近最少使用LRU缓存

    标题中的"quicklru简单的最近最少使用LRU缓存"指的是一种轻量级的LRU实现,旨在提供高效且易于使用的缓存解决方案。它可能是一个小型库,专为JavaScript环境设计,用于存储和检索数据,同时保持较低的内存占用。 ...

    Java实现简单LRU缓存机制的方法

    Java实现简单LRU缓存机制的方法 Java实现简单LRU缓存机制的方法是指通过Java语言实现的一种缓存机制,该机制可以根据最近最少使用的原则淘汰缓存中的数据。缓存机制的实现主要是通过哈希表和双向链表来实现的。 ...

    详解Java实现LRU缓存

    使用 LinkedHashMap 实现 LRU 缓存是最简单的方法,因为 LinkedHashMap 自身已经实现了顺序存储,默认情况下是按照元素的添加顺序存储,也可以启用按照访问顺序存储,即最近读取的数据放在最前面,最早读取的数据...

    06丨链表(上):如何实现LRU缓存淘汰算法?1

    今天我们将讨论如何使用链表来实现LRU缓存淘汰算法。 首先,让我们来讨论缓存的概念。缓存是一种提高数据读取性能的技术,它广泛应用于CPU缓存、数据库缓存、浏览器缓存等领域。当缓存被用满时,需要淘汰一些数据以...

    缓存淘汰算法之LRU

    LRU 算法的实现简单,但命中时需要遍历链表,找到命中的数据块索引,然后需要将数据移到头部。 4. LRU-K 算法 LRU-K 算法是为了解决 LRU 算法“缓存污染”的问题,其核心思想是将“最近使用过 1 次”的判断标准...

    swift-SPTPersistentCache一个LRU缓存管理框架

    **Swift-SPTPersistentCache:一个高效且灵活的LRU缓存管理框架** 在iOS和macOS应用开发中,缓存管理是性能优化的关键部分。它能够帮助减少网络请求,提高用户体验,尤其是在处理大量数据或者频繁访问同一资源时。`...

    LRU算法LRU算法LRU算法LRU算法

    在缓存或者数据库管理系统中,LRU算法被广泛应用,因为它的实现简单且效果良好。 LRU算法的核心思想是:当内存满时,最近最少使用的数据会被优先淘汰。也就是说,如果一个数据最近被访问过,那么它在未来被访问的...

    LRU_缓存策略_LRU_缓存_源码.rar

    在Python中,可以使用`functools.lru_cache`装饰器实现LRU缓存,或者自定义双向链表和哈希表实现。 在实际应用中,LRU缓存策略常用于数据库的查询缓存、Web服务器的动态页面缓存、编程语言解释器的符号表等场景。...

    java-leetcode题解之第146题LRU缓存.zip

    以下是简单的LRU缓存实现: ```java import java.util.HashMap; import java.util.LinkedList; import java.util.Map; public class LRUCache, V&gt; implements LRUCache, V&gt; { private int capacity; private Map...

    06丨链表(上):如何实现LRU缓存淘汰算法?.pdf

    链表(上):如何实现 LRU 缓存淘汰算法? 链表是一种基础的数据结构,学习链表有什么用呢?为了回答这个问题,我们来讨论一个经典的链表应用场景,那就是 LRU 缓存淘汰算法。缓存是一种提高数据读取性能的技术,在...

    LRU算法 java实现

    以下是一个简单的LRU缓存实现的Java代码框架: ```java class LRUCache, V&gt; { private int capacity; private HashMap, Node&gt; map; private DoublyLinkedList&lt;Node&gt; list; public LRUCache(int capacity) { ...

    lru-cache:带最小堆的 LRU 缓存实现

    描述:这个项目有点像实验,涉及 3 种不同的 LRU 缓存实现。 一个使用最小堆(通常用于优先级队列)而不是 OrderedDict,第二个使用集合包中的内置 OrderedDict,最后一个使用我自己的 OrderedDict 的简单实现。 ...

    LRU 缓存机制(java代码).docx

    下面详细介绍如何使用 Java 实现一个简单的 LRU 缓存机制。 ##### 1. 定义双向链表节点类 `Node` ```java class Node { int key; int value; Node prev; Node next; public Node(int key, int value) { ...

    php-lrucache:PHP中的LRU缓存实现

    PHP LRU缓存实现介绍WTF 是 LRU 缓存吗? LRU 代表最近最少使用。 它是一种缓存类型,通常具有固定容量并丢弃最旧的条目。 如果您需要控制缓存内存使用,这将特别有用。 如果您想了解有关 LRU Cache 的更多详细信息...

    node-lru-native, 面向 node.js的高性能LRU缓存.zip

    node-lru-native, 面向 node.js的高性能LRU缓存 node-lru-native这是 node.js 内存缓存的简单实现,支持 LRU ( least-recently-used ) 备份和 TTL expirations 。它是作为与( 精彩) node-lru-cache库的替代

    LRU算法实现1

    例如,以下是一个简单的LRU缓存实现,使用`LinkedHashMap`的继承方式: ```java public class LRUCache2, V&gt; extends LinkedHashMap, V&gt; { private final int MAX_CACHE_SIZE; public LRUCache2(int cacheSize) ...

    arraylru一个真正非常快的数组项LRU缓存

    总之,`array-lru`是一个适用于JavaScript开发的高效数组型LRU缓存库,它的简单API和高性能特性使其成为优化小型缓存需求的理想选择。开发者可以根据具体项目需求,灵活地使用和定制这个库,提升应用程序的运行效率...

    Nodejs基于LRU算法实现的缓存处理操作示例.docx

    以下代码段展示了如何在Node.js中实现一个简单的LRU缓存: ```javascript function CacheLRU(capacity) { this.capacity = capacity || Number.MAX_VALUE; this.data = {}; // 存储缓存值 this.hash = {}; // ...

Global site tag (gtag.js) - Google Analytics