Soft cache storage is a cache storage that uses SoftReference objects to hold the objects it was passed, therefore allows the garbage collector to purge the cache when it determines that it wants to free up memory. This class is thread-safe to the extent that its underlying map is. The defau
| 76 | * @author Attila Szegedi |
| 77 | */ |
| 78 | public class SoftCacheStorage implements ConcurrentCacheStorage |
| 79 | { |
| 80 | private static final Method atomicRemove = getAtomicRemoveMethod(); |
| 81 | |
| 82 | private final ReferenceQueue queue = new ReferenceQueue(); |
| 83 | private final Map map; |
| 84 | private final boolean concurrent; |
| 85 | |
| 86 | public SoftCacheStorage() { |
| 87 | this(ConcurrentMapFactory.newMaybeConcurrentHashMap()); |
| 88 | } |
| 89 | |
| 90 | public boolean isConcurrent() { |
| 91 | return concurrent; |
| 92 | } |
| 93 | |
| 94 | public SoftCacheStorage(Map backingMap) { |
| 95 | map = backingMap; |
| 96 | this.concurrent = ConcurrentMapFactory.isConcurrent(map); |
| 97 | } |
| 98 | |
| 99 | public Object get(Object key) { |
| 100 | processQueue(); |
| 101 | Reference ref = (Reference)map.get(key); |
| 102 | return ref == null ? null : ref.get(); |
| 103 | } |
| 104 | |
| 105 | public void put(Object key, Object value) { |
| 106 | processQueue(); |
| 107 | map.put(key, new SoftValueReference(key, value, queue)); |
| 108 | } |
| 109 | |
| 110 | public void remove(Object key) { |
| 111 | processQueue(); |
| 112 | map.remove(key); |
| 113 | } |
| 114 | |
| 115 | public void clear() { |
| 116 | map.clear(); |
| 117 | processQueue(); |
| 118 | } |
| 119 | |
| 120 | private void processQueue() { |
| 121 | for(;;) { |
| 122 | SoftValueReference ref = (SoftValueReference)queue.poll(); |
| 123 | if(ref == null) { |
| 124 | return; |
| 125 | } |
| 126 | Object key = ref.getKey(); |
| 127 | if(concurrent) { |
| 128 | try { |
| 129 | atomicRemove.invoke(map, new Object[] { key, ref }); |
| 130 | } |
| 131 | catch(IllegalAccessException e) { |
| 132 | throw new UndeclaredThrowableException(e); |
| 133 | } |
| 134 | catch(InvocationTargetException e) { |
| 135 | throw new UndeclaredThrowableException(e); |
nothing calls this directly
no test coverage detected
searching dependent graphs…