| 1 8 package org.ozoneDB.core.storage; 9 10 import java.lang.ref.Reference ; 11 import java.lang.ref.ReferenceQueue ; 12 import java.lang.ref.SoftReference ; 13 import java.util.Collection ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.LinkedHashMap ; 18 import java.util.LinkedList ; 19 import java.util.Map ; 20 import java.util.Map.Entry; 21 import java.util.Properties ; 22 import java.util.Set ; 23 24 29 public abstract class AbstractReferenceCache implements Cache, PropertyConfigurable { 30 31 37 protected interface KeyedReference { 38 39 public void clear(); 40 41 public boolean enqueue(); 42 43 public Object get(); 44 45 public boolean isEnqueued(); 46 47 public Object getKey(); 48 49 } 50 51 58 private class ReferenceHandler extends Thread { 59 60 ReferenceHandler() { 61 super(Thread.currentThread().getThreadGroup(), "stale reference remover"); 62 setDaemon(true); 63 setPriority(Thread.MAX_PRIORITY - 1); 64 } 65 66 public void run() { 67 for(;;) { 68 try { 69 KeyedReference ref = (KeyedReference) getReferenceQueue().remove(); 70 Set keys = new HashSet (); 71 keys.add(ref.getKey()); 72 73 while ((ref = (KeyedReference) getReferenceQueue().poll()) != null) { 80 keys.add(ref.getKey()); 81 } 82 synchronized(AbstractReferenceCache.this) { 83 getMap().keySet().removeAll(keys); 84 } 85 } catch (InterruptedException ignore) { 86 } 87 } 88 } 89 90 } 92 private ReferenceQueue referenceQueue; 93 private ReferenceHandler referenceHandler; 94 95 private String prefix; 96 97 100 private Map map; 101 102 public AbstractReferenceCache(Properties properties, String prefix) { 103 this.prefix = prefix; 104 map = new LinkedHashMap (); 105 referenceQueue = new ReferenceQueue (); 106 referenceHandler = new ReferenceHandler(); 107 referenceHandler.start(); 108 } 109 110 protected abstract KeyedReference createKeyedReference(Object key, Object value, ReferenceQueue referenceQueue); 111 112 public synchronized Object get(Object key) { 113 KeyedReference ref = (KeyedReference) getMap().get(key); 114 return ref == null ? null : ref.get(); 115 } 116 117 public synchronized void put(Object key, Object value) { 118 KeyedReference ref = createKeyedReference(key, value, getReferenceQueue()); 119 getMap().put(key, ref); 120 } 121 122 public synchronized Object remove(Object key) { 123 KeyedReference ref = (KeyedReference) getMap().remove(key); 124 return ref == null ? null : ref.get(); 125 } 126 127 public synchronized Map copyToMap() { 128 Map result = new HashMap (); 129 for (Iterator i = getMap().entrySet().iterator(); i.hasNext(); ) { 130 Entry entry = (Entry) i.next(); 131 KeyedReference ref = (KeyedReference) entry.getValue(); 132 Object value = ref.get(); 133 if (value != null) { 134 result.put(entry.getKey(), value); 135 } 136 } 137 return result; 138 } 139 140 private Map getMap() { 142 return map; 143 } 144 145 private ReferenceQueue getReferenceQueue() { 147 return referenceQueue; 148 } 149 150 public synchronized int size() { 151 return getMap().size(); 152 } 153 154 public String getPrefix() { 155 return prefix; 156 } 157 158 public Collection getPropertyInfos() { 159 return new LinkedList (); 160 } 161 162 163 protected AbstractReferenceCache() { 165 } 166 167 } 168 | Popular Tags |