昨天晚上花了一个多小时完成了我的大轮子的第二部分:缓存
今天中午利用休息时间写了测试用例,还算很顺利的,哈哈。
代码如下:
package com.jiehoo.core;
class CacheInfo {
String key;
long create;
long lastAccess;
long used;
CacheInfo(String key) {
this.key = key;
create = System.currentTimeMillis();
}
void touch() {
lastAccess = System.currentTimeMillis();
used++;
}
}
package com.jiehoo.core;
import java.util.Comparator;
public class FIFOComparator implements Comparator {
public int compare(Object o1, Object o2) {
CacheInfo info1 = (CacheInfo) o1;
CacheInfo info2 = (CacheInfo) o2;
if (info1.create < info2.create) {
return -1;
} else if (info1.create > info2.create) {
return 1;
} else {
return 0;
}
}
}
package com.jiehoo.core;
import java.util.Comparator;
public class LFUComparator implements Comparator {
public int compare(Object o1, Object o2) {
CacheInfo info1 = (CacheInfo) o1;
CacheInfo info2 = (CacheInfo) o2;
if (info1.used < info2.used) {
return -1;
} else if (info1.used > info2.used) {
return 1;
} else {
return 0;
}
}
}
package com.jiehoo.core;
import java.util.Comparator;
public class LRUComparator implements Comparator {
public int compare(Object o1, Object o2) {
CacheInfo info1 = (CacheInfo) o1;
CacheInfo info2 = (CacheInfo) o2;
if (info1.lastAccess < info2.lastAccess) {
return -1;
} else if (info1.lastAccess > info2.lastAccess) {
return 1;
} else {
return 0;
}
}
}
package com.jiehoo.core;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class CacheManager {
public static final int LFU = 0;
public static final int LRU = 1;
public static final int FIFO = 2;
public static final int UNLIMIT = 3;
public static final int DEFAULT_MAX_CAPACITY = 100;
private static final Map managers = new HashMap();
private static Comparator lfuComparator = new LFUComparator();
private static Comparator lruComparator = new LRUComparator();
private static Comparator fifoComparator = new FIFOComparator();
private int type;
private int maxCapacity;
private Map cache;
private List cacheInfos;
private Map keyMap;
private CacheManager(int type, int maxCapacity) {
this.type = type;
cache = new HashMap(maxCapacity);
keyMap = new HashMap(maxCapacity);
if (type == UNLIMIT) {
this.maxCapacity = Integer.MAX_VALUE;
} else {
this.maxCapacity = maxCapacity;
}
cacheInfos = new LinkedList();
}
public static synchronized CacheManager getCacheManager(String name) {
return getCacheManager(name, UNLIMIT, DEFAULT_MAX_CAPACITY);
}
public static synchronized CacheManager getCacheManager(String name, int type) {
return getCacheManager(name, type, DEFAULT_MAX_CAPACITY);
}
public static synchronized CacheManager getCacheManager(String name, int type, int maxCapacity) {
CacheManager cacheManager = (CacheManager) managers.get(name);
if (cacheManager == null) {
cacheManager = new CacheManager(type, maxCapacity);
managers.put(name, cacheManager);
}
return cacheManager;
}
public synchronized void put(String key, Object object) {
if (cache.size() >= maxCapacity) {
removeFirst();
}
Object old = cache.put(key, object);
if (old == null) {
CacheInfo cacheInfo = new CacheInfo(key);
cacheInfos.add(cacheInfo);
keyMap.put(key, cacheInfo);
}
}
private void removeFirst() {
switch (type) {
case LFU:
Collections.sort(cacheInfos, lfuComparator);
break;
case LRU:
Collections.sort(cacheInfos, lruComparator);
break;
case FIFO:
Collections.sort(cacheInfos, fifoComparator);
break;
}
CacheInfo cacheInfo = (CacheInfo) cacheInfos.get(0);
keyMap.remove(cacheInfo.key);
cache.remove(cacheInfo.key);
cacheInfos.remove(0);
}
public synchronized Object get(String key) {
Object result = cache.get(key);
if (result != null) {
CacheInfo cacheInfo = (CacheInfo) keyMap.get(key);
cacheInfo.touch();
}
return result;
}
}
测试用例:
package com.jiehoo.core;
import junit.framework.TestCase;
public class TestCacheManager extends TestCase {
public void testUnlimitCacheManager() {
CacheManager cacheManager = CacheManager.getCacheManager("UnlimitCacheManager", CacheManager.UNLIMIT);
for (int i = 0; i < CacheManager.DEFAULT_MAX_CAPACITY + 100; i++) {
cacheManager.put("key" + i, new Object());
}
assertNotNull(cacheManager.get("key0"));
}
public void testFIFOCacheManager() {
CacheManager cacheManager = CacheManager.getCacheManager("FIFOCacheManager", CacheManager.FIFO, 100);
for (int i = 0; i < 120; i++) {
cacheManager.put("key" + i, new Object());
}
assertNull(cacheManager.get("key0"));
assertNull(cacheManager.get("key19"));
assertNotNull(cacheManager.get("key20"));
assertNotNull(cacheManager.get("key119"));
}
public void testLRUCacheManager() throws Exception {
CacheManager cacheManager = CacheManager.getCacheManager("LRUCacheManager", CacheManager.LRU, 10);
for (int i = 0; i < 10; i++) {
cacheManager.put("key" + i, new Object());
}
for (int i = 0; i < 10; i++) {
cacheManager.get("key" + i);
Thread.sleep(10);
}
cacheManager.put("key11", new Object());
assertNull(cacheManager.get("key0"));
assertNotNull(cacheManager.get("key11"));
}
public void testLFUCacheManager() {
CacheManager cacheManager = CacheManager.getCacheManager("LFUCacheManager", CacheManager.LFU, 10);
for (int i = 0; i < 10; i++) {
cacheManager.put("key" + i, new Object());
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < i; j++) {
cacheManager.get("key" + i);
}
}
cacheManager.put("key11", new Object());
assertNull(cacheManager.get("key0"));
assertNotNull(cacheManager.get("key11"));
}
}
发表评论