1 10 11 package com.triactive.jdo.util; 12 13 import java.lang.ref.Reference ; 14 import java.lang.ref.ReferenceQueue ; 15 import java.util.ArrayList ; 16 import java.util.Iterator ; 17 import java.util.Map ; 18 import java.util.HashMap ; 19 import java.util.Set ; 20 import java.util.Collection ; 21 import java.util.Collections ; 22 import org.apache.log4j.Category; 23 24 25 37 38 public abstract class ReferenceValueMap implements Map , Cloneable 39 { 40 private static final Category LOG = Category.getInstance(ReferenceValueMap.class); 41 42 private HashMap map; 43 private ReferenceQueue reaped = new ReferenceQueue (); 44 private long lastLogTime = 0; 45 private int hits = 0; 46 private int misses = 0; 47 private int cleared = 0; 48 49 50 public ReferenceValueMap() 51 { 52 map = new HashMap (); 53 } 54 55 56 public ReferenceValueMap(int initialCapacity) 57 { 58 map = new HashMap (initialCapacity); 59 } 60 61 62 public ReferenceValueMap(int initialCapacity, float loadFactor) 63 { 64 map = new HashMap (initialCapacity, loadFactor); 65 } 66 67 68 public ReferenceValueMap(Map m) 69 { 70 map = new HashMap (); 71 putAll(m); 72 } 73 74 75 public Object clone() 76 { 77 reap(); 78 79 ReferenceValueMap rvm = null; 80 81 try { rvm = (ReferenceValueMap)super.clone(); } catch (CloneNotSupportedException e) {} 82 83 rvm.map = (HashMap )map.clone(); 84 rvm.map.clear(); 85 rvm.reaped = new ReferenceQueue (); 86 rvm.putAll(entrySet()); 87 88 return rvm; 89 } 90 91 92 96 97 public interface ValueReference 98 { 99 103 104 Object getKey(); 105 } 106 107 108 118 119 protected abstract ValueReference newValueReference(Object key, Object value, ReferenceQueue queue); 120 121 122 public Object put(Object key, Object value) 123 { 124 reap(); 125 return map.put(key, newValueReference(key, value, reaped)); 126 } 127 128 public void putAll(Map m) 129 { 130 putAll(m.entrySet()); 131 } 132 133 private void putAll(Set entrySet) 134 { 135 Iterator i = entrySet.iterator(); 136 137 while (i.hasNext()) 138 { 139 Map.Entry entry = (Map.Entry )i.next(); 140 put(entry.getKey(), entry.getValue()); 141 } 142 } 143 144 public Object get(Object key) 145 { 146 reap(); 147 Reference ref = (Reference )map.get(key); 148 149 Object value = ref == null ? null : ref.get(); 150 151 if (value == null) 152 ++misses; 153 else 154 ++hits; 155 156 if (LOG.isDebugEnabled()) 157 { 158 if ((System.currentTimeMillis() - lastLogTime) > 1000) 159 { 160 LOG.debug(getClass().getName() + "(" + System.identityHashCode(this) + ") size = " + size() + ", hits = " + hits + ", misses = " + misses + ", cleared = " + cleared); 161 lastLogTime = System.currentTimeMillis(); 162 } 163 } 164 165 return value; 166 } 167 168 public void clear() 169 { 170 reap(); 171 map.clear(); 172 } 173 174 public int size() 175 { 176 reap(); 177 return map.size(); 178 } 179 180 public boolean containsKey(Object obj) 181 { 182 reap(); 183 return map.containsKey(obj); 184 } 185 186 public boolean containsValue(Object obj) 187 { 188 reap(); 189 190 if (obj != null) 191 { 192 Iterator i = map.values().iterator(); 193 194 while (i.hasNext()) 195 { 196 Reference ref = (Reference )i.next(); 197 198 if (obj.equals(ref.get())) 199 return true; 200 } 201 } 202 203 return false; 204 } 205 206 public boolean isEmpty() 207 { 208 reap(); 209 return map.isEmpty(); 210 } 211 212 public Set keySet() 213 { 214 reap(); 215 return map.keySet(); 216 } 217 218 public Collection values() 219 { 220 reap(); 221 222 Collection c = map.values(); 223 Iterator i = c.iterator(); 224 ArrayList l = new ArrayList (c.size()); 225 226 while (i.hasNext()) 227 { 228 Reference ref = (Reference )i.next(); 229 Object obj = ref.get(); 230 231 if (obj != null) 232 l.add(obj); 233 } 234 235 return Collections.unmodifiableList(l); 236 } 237 238 public Set entrySet() 239 { 240 reap(); 241 242 Set s = map.entrySet(); 243 Iterator i = s.iterator(); 244 HashMap m = new HashMap (s.size()); 245 246 while (i.hasNext()) 247 { 248 Map.Entry entry = (Map.Entry )i.next(); 249 Reference ref = (Reference )entry.getValue(); 250 Object obj = ref.get(); 251 252 if (obj != null) 253 m.put(entry.getKey(), obj); 254 } 255 256 return Collections.unmodifiableSet(m.entrySet()); 257 } 258 259 public Object remove(Object key) 260 { 261 reap(); 262 return map.remove(key); 263 } 264 265 public int hashCode() 266 { 267 reap(); 268 return map.hashCode(); 269 } 270 271 public boolean equals(Object o) 272 { 273 reap(); 274 return map.equals(o); 275 } 276 277 public void reap() 278 { 279 ValueReference ref; 280 281 while ((ref = (ValueReference)reaped.poll()) != null) 282 { 283 map.remove(ref.getKey()); 284 ++cleared; 285 } 286 } 287 } 288 | Popular Tags |