001: package org.shiftone.cache.util;
002:
003: import java.lang.ref.Reference;
004: import java.lang.ref.ReferenceQueue;
005: import java.lang.ref.WeakReference;
006: import java.util.*;
007:
008: /**
009: * @version $Revision: 1.5 $
010: * @author <a href="mailto:jeff@shiftone.org">Jeff Drost</a>
011: */
012: public class WeakMap implements Map {
013:
014: private static final Log LOG = new Log(WeakMap.class);
015: private ReferenceQueue referenceQueue = new ReferenceQueue();
016: private Map referenceMap = new TreeMap();
017:
018: public Object put(Object key, Object value) {
019:
020: purge();
021:
022: return referenceMap
023: .put(key, new KeyedWeakReference(key, value));
024: }
025:
026: public void putAll(Map map) {
027:
028: Set set = map.entrySet();
029: Iterator iterator = set.iterator();
030:
031: while (iterator.hasNext()) {
032: Map.Entry entry = (Map.Entry) iterator.next();
033:
034: put(entry.getKey(), entry.getValue());
035: }
036: }
037:
038: public Object get(Object key) {
039:
040: purge();
041:
042: Reference ref = (Reference) referenceMap.get(key);
043:
044: return (ref != null) ? ref.get() : null;
045: }
046:
047: public void clear() {
048: purge();
049: referenceMap.clear();
050: }
051:
052: public Object remove(Object key) {
053:
054: purge();
055:
056: return referenceMap.remove(key);
057: }
058:
059: public Set keySet() {
060:
061: purge();
062:
063: return referenceMap.keySet();
064: }
065:
066: public boolean containsKey(Object key) {
067:
068: purge();
069:
070: return referenceMap.containsKey(key);
071: }
072:
073: public int size() {
074:
075: purge();
076:
077: return referenceMap.size();
078: }
079:
080: public boolean isEmpty() {
081:
082: purge();
083:
084: return referenceMap.isEmpty();
085: }
086:
087: public void purge() {
088:
089: KeyedWeakReference ref;
090:
091: while ((ref = (KeyedWeakReference) referenceQueue.poll()) != null) {
092: LOG.info("referenceQueue purge : " + ref.getKey()
093: + " ; size=" + size());
094: referenceMap.remove(ref.getKey());
095: }
096: }
097:
098: public boolean containsValue(Object value) {
099: throw new UnsupportedOperationException("containsValue");
100: }
101:
102: public Collection values() {
103: throw new UnsupportedOperationException("values");
104: }
105:
106: public Set entrySet() {
107: throw new UnsupportedOperationException("entrySet");
108: }
109:
110: class KeyedWeakReference extends WeakReference {
111:
112: private final Object key;
113:
114: public KeyedWeakReference(Object key, Object referent) {
115:
116: super (referent, referenceQueue);
117:
118: this .key = key;
119: }
120:
121: public Object getKey() {
122: return key;
123: }
124: }
125: }
|