1 29 package org.enhydra.barracuda.plankton.data; 30 31 import java.util.*; 33 import java.lang.ref.*; 34 35 public class SoftHashMap extends AbstractMap { 36 37 38 private final Map hash = new HashMap(); 39 40 private final int HARD_SIZE; 41 42 private final LinkedList hardCache = new LinkedList(); 43 44 private final ReferenceQueue queue = new ReferenceQueue(); 45 46 public SoftHashMap() { this(100); } 47 public SoftHashMap(int hardSize) { HARD_SIZE = hardSize; } 48 49 public Object get(Object key) { 50 Object result = null; 51 SoftReference soft_ref = (SoftReference)hash.get(key); 53 if (soft_ref != null) { 54 result = soft_ref.get(); 58 if (result == null) { 59 hash.remove(key); 62 } else { 63 hardCache.addFirst(result); 69 if (hardCache.size() > HARD_SIZE) { 70 hardCache.removeLast(); 72 } 73 } 74 } 75 return result; 76 } 77 78 81 private static class SoftValue extends SoftReference { 82 private final Object key; 89 private SoftValue(Object k, Object key, ReferenceQueue q) { 90 super(k, q); 91 this.key = key; 92 } 93 } 94 95 98 private void processQueue() { 99 SoftValue sv; 100 while ((sv = (SoftValue)queue.poll()) != null) { 101 hash.remove(sv.key); } 103 } 104 106 public Object put(Object key, Object value) { 107 processQueue(); return hash.put(key, new SoftValue(value, key, queue)); 109 } 110 public Object remove(Object key) { 111 processQueue(); return hash.remove(key); 113 } 114 public void clear() { 115 hardCache.clear(); 116 processQueue(); hash.clear(); 118 } 119 public int size() { 120 processQueue(); return hash.size(); 122 } 123 public Set entrySet() { 124 processQueue(); return hash.entrySet(); 126 } 127 } | Popular Tags |