001: package org.shiftone.cache.policy.lru;
002:
003: import org.shiftone.cache.util.*;
004: import org.shiftone.cache.util.reaper.ReapableCache;
005:
006: import java.util.Map;
007:
008: /**
009: * Class LruCache
010: *
011: *
012: * @author <a href="mailto:jeff@shiftone.org">Jeff Drost</a>
013: * @version $Revision: 1.7 $
014: */
015: class LruCache extends AbstractPolicyCache implements ReapableCache {
016:
017: private static final Log LOG = new Log(LruCache.class);
018: private final Map map;
019: private final LinkedList fifo;
020: private final LinkedList lru;
021:
022: LruCache(String name, long timeoutMilliSeconds, int maxSize) {
023:
024: super (name, timeoutMilliSeconds, maxSize);
025:
026: map = MapFactory.createMap(maxSize);
027: fifo = new LinkedList();
028: lru = new LinkedList();
029: }
030:
031: protected CacheNode findNodeByKey(Object key) {
032: return (LruNode) map.get(key);
033: }
034:
035: public int size() {
036: return map.size();
037: }
038:
039: protected void revalueNode(CacheNode node) {
040:
041: LruNode n = (LruNode) node;
042:
043: lru.moveToFirst(n.lruNode);
044: }
045:
046: protected void delete(CacheNode node) {
047:
048: LruNode n = (LruNode) node;
049:
050: fifo.remove(n.fifoNode);
051: lru.remove(n.lruNode);
052: map.remove(n.key);
053: }
054:
055: protected void removeLeastValuableNode() {
056:
057: LinkedListNode lln = null;
058: LruNode node = null;
059:
060: lln = lru.peekLast();
061: node = (LruNode) lln.getValue();
062:
063: delete(node);
064: }
065:
066: public void removeExpiredElements() {
067:
068: LinkedListNode lln = null;
069: LruNode node = null;
070:
071: while ((lln = fifo.peekLast()) != null) {
072: node = (LruNode) lln.getValue();
073:
074: if (node.isExpired()) {
075: delete(node);
076: } else {
077:
078: // not expired.. can stop now
079: break;
080: }
081: }
082: }
083:
084: protected CacheNode createNode(Object userKey, Object cacheObject) {
085:
086: LruNode node = new LruNode();
087:
088: node.key = userKey;
089: node.value = cacheObject;
090: node.fifoNode = fifo.addFirst(node);
091: node.lruNode = lru.addFirst(node);
092: node.timeoutTime = System.currentTimeMillis()
093: + getTimeoutMilliSeconds();
094:
095: map.put(userKey, node);
096:
097: return node;
098: }
099:
100: String dumpLruKeys() {
101:
102: String dump = null;
103: StringBuffer sb = new StringBuffer();
104: LinkedListNode node = lru.peekFirst();
105: LruNode current = null;
106:
107: while (node != null) {
108: current = (LruNode) node.getValue();
109:
110: sb.append(current.key);
111:
112: node = node.getNext();
113: }
114:
115: dump = sb.toString();
116:
117: LOG.debug("dumpLruKeys : " + dump);
118:
119: return dump;
120: }
121:
122: String dumpFifoKeys() {
123:
124: String dump = null;
125: StringBuffer sb = new StringBuffer();
126: LinkedListNode node = fifo.peekFirst();
127: LruNode current = null;
128:
129: while (node != null) {
130: current = (LruNode) node.getValue();
131:
132: sb.append(current.key);
133:
134: node = node.getNext();
135: }
136:
137: dump = sb.toString();
138:
139: LOG.debug("dumpFifoKeys : " + dump);
140:
141: return dump;
142: }
143: }
|