1 package org.shiftone.cache.decorator.soft; 2 3 4 5 import org.shiftone.cache.Cache; 6 import org.shiftone.cache.util.Log; 7 import org.shiftone.cache.util.reaper.ReapableCache; 8 9 import java.lang.ref.Reference ; 10 import java.lang.ref.ReferenceQueue ; 11 import java.lang.ref.SoftReference ; 12 13 14 31 public class SoftCache implements Cache, ReapableCache 32 { 33 34 private static final Log LOG = new Log(SoftCache.class); 35 36 private final ReferenceQueue referenceQueue = new ReferenceQueue (); 38 private final Cache cache; 39 40 public SoftCache(Cache cache) 41 { 42 43 if (cache instanceof SoftCache) 44 { 45 throw new UnsupportedOperationException ("SoftCache should not delegate to SoftCache"); 46 } 47 48 this.cache = cache; 49 50 } 52 53 54 public void addObject(Object userKey, Object cacheObject) 55 { 56 57 cache.addObject(userKey, new KeyReference(userKey, cacheObject, referenceQueue)); 59 } 60 61 62 66 public Object getObject(Object key) 67 { 68 69 Object result = null; 70 Reference ref = null; 71 72 ref = (Reference ) cache.getObject(key); 73 74 if (ref != null) 75 { 76 result = ref.get(); 77 78 if (result == null) 79 { 80 LOG.debug("reference found in cache but GC removed object"); 81 cache.remove(key); 82 } 83 } 84 85 return result; 86 } 87 88 89 public final void remove(Object key) 90 { 91 cache.remove(key); 92 } 93 94 95 public final int size() 96 { 97 return cache.size(); 98 } 99 100 101 public final void clear() 102 { 103 cache.clear(); 104 } 105 106 107 110 public synchronized void removeExpiredElements() 111 { 112 113 Reference ref = null; 114 Object key = null; 115 int removeCount = 0; 116 117 while ((ref = referenceQueue.poll()) != null) 118 { 119 key = ((KeyReference) ref).getKey(); 120 121 cache.remove(key); 122 123 removeCount++; 124 } 125 126 LOG.debug(this + " removeExpiredElements() removed - " + removeCount + " refs - " + size() + " left"); 127 } 128 129 130 public final String toString() 131 { 132 return "SoftCache->" + cache; 133 } 134 135 136 143 class KeyReference extends SoftReference 144 { 145 146 private Object key = null; 147 148 156 public KeyReference(Object key, Object cacheObject, ReferenceQueue referenceQueue) 157 { 158 159 super(cacheObject, referenceQueue); 160 161 this.key = key; 162 } 163 164 165 168 Object getKey() 169 { 170 return key; 171 } 172 } 173 } 174 | Popular Tags |