LRUCache

MyLRUCache 缓存类

package org.jf.alg.lru;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


/**
* 限定容量二叉堆+HashMap实现LRU
*
* @author junfeng.chen
*
*/
public class MyLRUCache {

private Map<Object,ValueEntry> container = Collections.synchronizedMap( new HashMap<Object,ValueEntry>());

private List<Object> visistList = Collections.synchronizedList(new LinkedList<Object>());//key值的访问历史

private KeyVisitCounter[] heap_array ;

private int increaseStep = 500 ;

private int initSize = 2000;

//访问记录列表 每次访问元素,将其访问记录放入列表,并有后台线程处理
private long reset_interval = 2000*60;//刷新时间默认为2分钟

private int capacity = 100000;

private int size = 0;

private boolean bln_started = false;

private PerlocateThread perlocateThd ;

public MyLRUCache()
{
init();
}

public MyLRUCache(int capacity)
{
this.capacity = capacity;
init();
}

/**
*
* @param capacity 最大容量
* @param time_cycle 计数时间周期
*/
public MyLRUCache(int capacity,int time_cycle)
{
this.capacity = capacity;
this.reset_interval = time_cycle;
init();
}

public void start()
{
this.perlocateThd = new PerlocateThread();
perlocateThd.start();
this.bln_started = true;
}

public void stop()
{
if(perlocateThd != null)
perlocateThd.exit();
this.bln_started = false;
this.heap_array = new KeyVisitCounter[this.initSize+1];
this.visistList.clear();
this.container.clear();
}
private void init()
{
this.heap_array = new KeyVisitCounter[this.initSize+1];
}

public void resetCount()
{
for(KeyVisitCounter counter:heap_array)
{
if(counter != null)
counter.reSet();
else
break;
}
}


// public void remove(Object key)
// {
// not support remove explicity
// }
//
public Object get(Object key)
{
assertStatus();
ValueEntry valueEntry = this.container.get(key);
if(valueEntry != null)
{
//在堆中查找当前key,并对其count加1
visistList.add(key);
return valueEntry.getData();
}
return null;
}

public void put(Object key,Object value)
{
assertStatus();
ValueEntry entry = new ValueEntry(value);
this.visistList.add(key);
this.container.put(key, entry);//实际上 保存的元素可能比capacity多
}

public int getSize()
{
return this.size;
}


/***********************some help methods****************************************************/

private void assertStatus()
{
if(!this.bln_started)
throw new RuntimeException("Illegle Cache Staus,not started");
}

/**
*
* @param key
* @return 该key值对应的索引
*/
private int perlocateUp(Object key/* , ValueEntry entry*/)
{
int indx = -1;
ValueEntry entry = container.get(key);
if(entry.getKeyIndx()==-1)
{
if(size<this.capacity&&size==this.heap_array.length-1)
{
int step = this.capacity - this.size;
step = step<=this.increaseStep?step:increaseStep;
KeyVisitCounter []newArray = new KeyVisitCounter[heap_array.length+step];
System.arraycopy(heap_array, 1, newArray,1, size);
heap_array = newArray;
}

KeyVisitCounter key_counter = new KeyVisitCounter(key);
key_counter.visit();//缓存已满时,防止最后一个元素总是被删除 刚插入的元素给予特殊待遇
//新加入一个记录值
if(this.size==this.capacity)//heap满
{
if(heap_array[size].compareTo(key_counter)<=0)
{
heap_array[size] = key_counter;
indx = size;
}//else indx = -1

}else
{
heap_array[size+1] = key_counter;
indx = size+1;
size++;
}
entry.setKeyIndex(indx);
}
else
{
indx = entry.getKeyIndx();
}

if(indx == -1)//
return -1;

//fix up heap_array to ensure it's heap character
int parent = indx/2;
KeyVisitCounter counter = this.heap_array[indx];
counter.visit();
while(parent!=0)
{
if(this.heap_array[indx].compareTo(this.heap_array[parent])>0)
{
KeyVisitCounter tmp = heap_array[indx];
heap_array[indx] = heap_array[parent];
heap_array[parent] = tmp;
indx = parent;


//设置key对应的索引
this.container.get(heap_array[indx].getKey()).setKeyIndex(indx);
this.container.get(heap_array[parent].getKey()).setKeyIndex(parent);

parent = indx/2;
}else
{
break;
}
}

return indx;
}



private class PerlocateThread extends Thread
{
boolean run = true;
public void run()
{
int count = 200;
long last_reset_time = System.currentTimeMillis();
while(run)
{
while(count>0&&visistList.size()>0)
{
Object key = visistList.remove(0);
int indx = perlocateUp(key);
if(indx == -1)
container.remove(key);
}

if(System.currentTimeMillis() - last_reset_time >reset_interval)
{
resetCount();
last_reset_time = System.currentTimeMillis();
}
try {
this.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}

public void exit()
{
run = false;
}

}
}


访问次数记录类

package org.jf.alg.lru;

public class KeyVisitCounter implements Comparable{

private Object key;
private int count;

public KeyVisitCounter(Object key)
{
this.key = key;
}

public void visit()
{
count++;
}

public void visit(int times)
{
this.count += times ;
}

public int getVisitTimes()
{
return count;
}

public Object getKey()
{
return this.key;
}

public void reSet()
{
this.count = 0;
}

@Override
public int compareTo(Object o)
{

if(!(o instanceof KeyVisitCounter))
return 1;
KeyVisitCounter counter = (KeyVisitCounter) o;
if(this.count > counter.count)
return 1;
if(this.count == counter.count)
return 0;
return -1;

}
}




package org.jf.alg.lru;

public class ValueEntry {

private int keyIndx = -1;//key在heap数组中的下标
private Object data;

public ValueEntry(Object data)
{
this.data = data;
}

public Object getData()
{
return this.data;
}

public void setKeyIndex(int indx)
{
this.keyIndx = indx;
}

public int getKeyIndx()
{
return this.keyIndx;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值