自己实现的缓存

最近比较无聊,就自己写了一个Cache,已经实现了大概的功能

一.Cache缓存接口类
public interface Cache extends java.lang.Comparable {

// 放入元素  
void put(CacheElement element) throws CacheException;

// 获取元素
CacheElement get(String key) throws CacheException;

// 重新刷新缓存
void refresh();

void list();

// 获取缓存的key
Set<String> getKeys();

void remove(String key);

// 清除缓存
void clear();

int getSize();

String getName();

void setName(String name);

String toString();

}


二。Storage 存取器接口,主要的实现类有 MemoryStorage,DiskStorage,MixStorage


public interface Storage<K, V> {

// 能够容纳的最大存储对象。
public int getMaxElementCnt();

public CachePolicy getCachePolicy();

// 存活时间,当存取器的对象超出等待时间,会自动从存取器中remove,
// 当是0时,表示对象可以永远等待,不会过期
public long getIdelSecond();

// 存活时间,当存取器的对象超出存活时间,会自动从存取器中remove
// 当是 0时,表示永远存活,不会过期
public long getLiveSecond();

// refresh缓存,将更存取器的对象访问时间和清除过期的对象
public void refresh();

public void put(CacheElement<K, V> element) throws CacheException;

public CacheElement<K, V> get(String key);

public CacheElement<K, V> remove(K key);

public abstract void removeAll();

// 根据 CachePolicy自动pickout出CacheElement
public CacheElement<K, V> pickout();

public abstract void dispose();

public abstract int getSize();

public boolean contain(String key);

// 获取缓存key的Set
public Set<K> getKeys();

// 获取缓存entry的Set
public Set<V> getEntry();

}

三。实现类MemoryStorage
// 内存取贮
public class MemoryStorage<K, V> implements Storage, CacheSerializable<K, V> {

private static final long serialVersionUID = 1L;

private int maxElementCnt;

private Map<K, CacheElement> map;

private long idelSecond;

private long liveSecond;

private CachePolicy policy;

private static Object lock = new Object();

public MemoryStorage(int maxElementCnt, long liveSecond, long idelSecond,
CachePolicy policy) {
this.maxElementCnt = maxElementCnt;
this.liveSecond = liveSecond;
this.idelSecond = idelSecond;
this.policy = policy;
this.init(policy);
}

public MemoryStorage(int maxElementCnt) {
this(maxElementCnt, 2, 2, CachePolicy.LFU);
}


public MemoryStorage() {
this(1000, 0, 0, CachePolicy.LRU);
}

public CachePolicy getCachePolicy() {
return policy;
}

public int getMaxElementCnt() {
return maxElementCnt;
}

public long getIdelSecond() {
return idelSecond;
}

public void setIdelSecond(long idelSecond) {
this.idelSecond = idelSecond;
}

public long getLiveSecond() {
return liveSecond;
}

public void setLiveSecond(long liveSecond) {
this.liveSecond = liveSecond;
}

public void setMaxElementCnt(int maxElementCnt) {
this.maxElementCnt = maxElementCnt;
}

private boolean isFull() {
return this.getMaxElementCnt() == this.getSize();
}

public void refresh() {
Set<K> keySet = this.map.keySet();
if (keySet == null || keySet.isEmpty())
return;
Iterator<K> it = keySet.iterator();
CacheElement element = null;
Collection<K> collections = new ArrayList<K>();
synchronized (lock) {
while (it.hasNext()) {
K next = it.next();
element = (CacheElement) this.map.get(next);
if (element.isExpired()) {
collections.add(next);
}
}
if (collections.size() > 0) {
for (K k : collections) {
this.map.remove(k);
}
}
long curTime = System.currentTimeMillis();
keySet = this.map.keySet();
if (keySet == null || keySet.isEmpty())
return;
it = keySet.iterator();
while (it.hasNext()) {
element = this.map.get(it.next());
element.setUpdateTime(curTime);
}
}

}

public void dispose() {
// TODO Auto-generated method stub

}

public CacheElement<K, V> get(String key) {
CacheElement<K, V> element = null;
synchronized (lock) {
if (this.map.containsKey(key)) {
element = this.map.get(key);
element.setUpdateTime(System.currentTimeMillis());
element.setHitCnt(element.getHitCnt() + 1L);
}
if (this.policy == CachePolicy.LFU) {
// 对元素按照 hitCnt重新排序

} else if (this.policy == CachePolicy.LRU) {

}
}
return element;
}

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

public void put(CacheElement element) throws CacheException {
synchronized (lock) {
if (this.isFull()) {
this.pickout();
}
if (element != null) {
element.setStorage(this);
this.map.put((K) element.getKey(), element);
}
}
}

public CacheElement<K, V> remove(Object key) {
synchronized (lock) {
if (map.containsKey(key)) {
return map.remove(key);
}
}
return null;
}

public void removeAll() {
if (this.map.size() == 0) {
return;
}
synchronized (lock) {
this.map.clear();
}
}

public boolean contain(String key) {
return this.map.containsKey(key);
}

public Set<K> getKeys() {
return this.map.keySet();
}

private void init(CachePolicy policy) {

switch (policy) {
case LFU:
this.map = new HashMap<K, CacheElement>();
break;

case FIFO:
this.map = new LinkedHashMap<K, CacheElement>();
break;

case LRU:
this.map = new LinkedHashMap<K, CacheElement>();
break;
}

}

// 剔除一个元素 
public CacheElement pickout() {
if (this.getSize() <= 0) {
return null;
}
CacheElement cache = null;
Set<K> set = null;
CacheElement[] caches = null;
Iterator<K> it = null;
int i = 0;
switch (policy) {
case LFU:
set = this.map.keySet();
caches = new CacheElement[set.size()];
it = set.iterator();
while (it.hasNext()) {
caches[i++] = this.map.get(it.next());
}
Arrays.sort(caches, new Comparator<CacheElement>() {
// 按 updateTime升序排列
public int compare(CacheElement o1, CacheElement o2) {
return (int) (o1.getHitCnt() - o2.getHitCnt());
}
});
cache = caches[0];
this.map.remove(caches[0].getKey());
break;

case FIFO:
it = this.map.keySet().iterator();
if (it.hasNext()) {
cache = this.map.remove(it.next());
}
break;
case LRU:
set = this.map.keySet();
caches = new CacheElement[set.size()];
it = set.iterator();
while (it.hasNext()) {
caches[i++] = this.map.get(it.next());
}
Arrays.sort(caches, new Comparator<CacheElement>() {
// 按 updateTime升序排列
public int compare(CacheElement o1, CacheElement o2) {
return (int) (o1.getUpdateTime() - o2.getUpdateTime());
}
});
cache = caches[0];
this.map.remove(cache.getKey());
break;
}
return cache;
}

public Set<V> getEntry() {
Set set = this.map.entrySet();
Iterator<Map.Entry> it = set.iterator();
Set<V> entrySet = new TreeSet<V>();
while (it.hasNext()) {
entrySet.add((V) it.next().getValue());
}
return entrySet;
}

}

四。创建Cache的工厂类,CacheManagerFactoryBean

public final class CacheManagerFactoryBean {

private CacheProvider provider;

private String factoryName;


public String getFactoryName() {
return factoryName;
}

public void setFactoryName(String factoryName) {
this.factoryName = factoryName;
}

public CacheProvider getProvider() {
return provider;
}

public void setProvider(CacheProvider provider) {
this.provider = provider;
}

public final Cache create(){
return this.create(null);
}


public final Cache create(Properties p){
return this.getProvider().buildCache(p);
}


}

五。默认的缓存类实现 DefaultCacheProvider

 
public class DefaultCacheProvider implements CacheProvider {

private String providerName;

private Set<Cache> cacheSet;

private Properties defaultCacheProperties;

private CacheSet cachSet;

private static boolean register = false;

public CacheSet getCachSet() {
return cachSet;
}

public void setCachSet(CacheSet cachSet) {
this.cachSet = cachSet;
}

public DefaultCacheProvider(){
if( register != true) {
CacheProviderManager.getInstance().register(
this.getClass().getName()+"-"+this.getProviderName(),this);
register = true;
}
}

public Properties getDefaultCacheProperties() {
return defaultCacheProperties;
}

public void setDefaultCacheProperties(Properties defaultCacheProperties) {
this.defaultCacheProperties = defaultCacheProperties;
}



public String getProviderName() {
return providerName;
}

public void setProviderName(String providerName) {
this.providerName = providerName;
}


public Cache buildCache(Properties selfPro) {
if( this.defaultCacheProperties == null ) {
throw new CacheException("请先配置defaultCacheProperties属性");
}
CacheSet cacheSet = new CacheSet(defaultCacheProperties,selfPro);
Cache cache = new DefaultCacheImpl(cacheSet);
this.getCaches().add(cache);
return cache;
}



public Set<Cache> getCaches() {
synchronized(this) {
if( cacheSet == null) {
cacheSet = new TreeSet<Cache>();
}
}
return cacheSet;
}


}
六。cache.xml的spring配置文件
[code="java"]<bean id="defaultCacheProvider" class="com.cache.DefaultCacheProvider" >
<property name="providerName" value ="defaultProvider"> </property>
<property name="defaultCacheProperties">
<props>
<!-- cache的名字 -->
<prop key="cache.name">defaultcache</prop>
<!-- -->
<prop key="cache.cache_policy">LFU</prop>
<!-- memory,disk,mix 默认值是 memory -->
<prop key="cache.cache_storage">memory</prop>
<!-- 最大存储的最大元素的值 -->
<prop key="cache.max_element_count">1000</prop>
<!-- 等待时间 ,单位秒,0秒表示可以无限等待 -->
<prop key="cache.idel_seconds">1000</prop>
<!-- 存活时间 ,单位秒,0秒表示可以永远存活-->
<prop key="cache.live_seconds">1000</prop>
</props>
</property>
</bean>

<bean id="cacheFactory" class="com.cache.CacheManagerFactoryBean">
<property name="factoryName" value="defaultCacheFactory" />
<property name="provider">
<ref bean="defaultCacheProvider" />
</property>
</bean>

<bean id="cache1" class="com.cache.Cache" factory-bean="cacheFactory" factory-method="create" >
<constructor-arg>
<props>
<prop key="cache.name">mycache</prop>
<prop key="cache.cache_policy">LFU</prop>
<prop key="cache.cache_storage">memory</prop>
<prop key="cache.max_element_count">1000</prop>
<prop key="cache.idel_seconds">1</prop>
<prop key="cache.live_seconds">2</prop>
</props>
</constructor-arg>
</bean>

<bean id="cache2" class="com.cache.Cache" factory-bean="cacheFactory" factory-method="create" >
</bean>

七。测试用例
public class CacheTest {

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

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"com/cache/cache.xml"});
Cache cache1 = (Cache) context.getBean("cache1");
System.out.println("cache1.name = " + cache1.getName());
/* */
CacheElement<String,Integer> element = null;
for(int i = 1 ; i <=4; i++){
element = new CacheElement<String,Integer>("key"+i,i);
cache1.put(element);
}
cache1.list();
Cache cache2 = (Cache) context.getBean("cache2");
CacheElement<String,Integer> element2 = null;
for(int i =5 ; i <=10; i++){
element2 = new CacheElement<String,Integer>("key"+i,i);
cache2.put(element2);
}
cache2.list();
System.out.println("key1="+cache1.get("key1").getObjectValue());
System.out.println("key8="+cache2.get("key8").getObjectValue());

}


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值