LRU 缓存算法

Posted by Yinode on Friday, September 6, 2019

TOC

缓存的主要目的就是提高访问速度,当我们需要从某个容器中获取一个元素的时候,将会优先从缓存中获取,如果缓存中正好存在,那么我们就可以直接取走这个元素,并且称之为成功命中。

所以缓存算法的主要目的就是定制一种策略,让命中率能够最大化。更好的利用计算机中不同存储介质速度不同的特性。

主要的缓存算法有两种 LRU 最久未用淘汰 以及 LFU 最少使用淘汰

LRU 一段时间内 上一次命中时间最长的元素将被淘汰

LFU 一段时间内 命中次数最少的元素将被淘汰

这个算法比较简单,我这里就直接上代码了

实现


package  tech.yinode.demo;

  

import  java.util.*;

  

import  tech.yinode.demo.Print;

  

class  Storage  {

static  class  Cache  {

static  class  CacheItem  {

public  String  key;

public  int  count;

public  String  val;

  

CacheItem(String  key, int  count, String  val)  {

this.key  = key;

this.count  = count;

this.val  = val;

}

}

  

private  PriorityQueue<CacheItem>  LFUQueue  =  new  PriorityQueue<CacheItem>(11,  new  Comparator<CacheItem>() {

@Override

public  int compare(CacheItem  o1, CacheItem  o2)  {

return  o1.count  -  o2.count;

}

});

private  HashMap<String,  CacheItem>  cacheSpace  =  new  HashMap<String,  CacheItem>();

private  int  cacheMaxSize  =  2;

  

public  void put(String  key, String  val)  {

//缓存空间不足 需要先进行清除

if (cacheSpace.size() > cacheMaxSize) {

Print.println("缓存空间不足 删除频率最低的元素");

CacheItem  item  =  LFUQueue.poll();

cacheSpace.remove(item.key);

}

CacheItem  newItem  =  new  CacheItem(key, 0, val);

LFUQueue.add(newItem);

cacheSpace.put(key, newItem);

}

  

public  String get(String  key)  {

CacheItem  item  =  cacheSpace.get(key);

  

// 命中失败

if (item ==  null) {

Print.println(key +  ": 命中失败");

return  null;

}

  

Print.println(key +  ": 命中成功");

  

// 更新该元素的访问频率

LFUQueue.remove(item);

item.count++;

LFUQueue.add(item);

  

return  item.val;

}

}

  

// 高速缓存

private  Cache  cache  =  new  Cache();

// 模拟磁盘

private  HashMap<String,  String>  disk  =  new  HashMap<String,  String>();

  

public  void put(String  key, String  val)  {

disk.put(key, val);

cache.put(key, val);

}

  

public  String get(String  key)  {

String  cacheValue  =  cache.get(key);

// 命中失败

if (cacheValue ==  null) {

return  disk.get(key);

}

return cacheValue;

}

}

  

class  Index  {

  

public  static  void main(String[] args)  throws  Exception  {

Storage  data  =  new  Storage();

data.put("a", "1");

data.get("a");

data.get("a");

data.get("a");

data.put("b", "1");

data.get("b");

data.put("c", "1");

data.put("d", "1");

try {

data.get("a");

data.get("b");

data.get("c");

data.get("d");

} catch (NullPointerException  e) {

Print.println("404");

}

}

}