@Override public void run() { try { for (WeakReference<SoftCache<?, ?>> cr : cacheQueue) { SoftCache<?, ?> c = cr.get(); if (c != null) { c.cleanup(); } else { cacheQueue.remove(cr); } } } catch (Throwable e) { log.error("Cleanup task has failed.", e); } } };
/** * If the specified key is not already associated with a value, associate it with the given value. This is equivalent to * * @param key * @param value * @return The value that was in the cache, null if none was there before */ public synchronized V putIfAbsent(K key, V value) { if (!containsKey(key)) { return put(key, value); } else { return get(key); } }
public SoftCache(int initialSize) { cacheEntries = createCache(initialSize); setName("SoftCache"); SoftCache.registerForCleanup(this); }
/** Adds an object to the cache. * @param key * @param value */ @Override public synchronized V put(K key, V value) { mbean.puts.incrementAndGet(); CacheEntry<V> entry = newSoftCacheEntry(key, value); CacheEntry<V> oldEntry = cacheEntries.put(key, entry); return safeValue(oldEntry); }
/** * Iterates through the cache and cleans up any cache references that have * been collected by the garbage collector. */ public final void cleanup() { mbean.cleanups.incrementAndGet(); if(log.isTraceEnabled()) { log.trace("cleanup() called on {} of size: {}", getName(), cacheEntries.size()); } int i = 0; Reference<? extends V> ref = referenceQueue.poll(); while (ref != null) { i++; assert ref.get() == null : "Referent should be null by the time the Reference is added to the queue"; removeReference(ref); ref = referenceQueue.poll(); } if(log.isTraceEnabled()) { log.trace("cleanup() finished on {}. {} keys were cleaned up. ", getName(), i); } }
@Override public synchronized boolean containsKey(K key) { V val = get(key); return (val != null); }
public synchronized void putAll(Map<? extends K, ? extends V> map) { for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { put(entry.getKey(), entry.getValue()); } }
public synchronized void putAllIfAbsent(Map<? extends K, ? extends V> map) { for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { putIfAbsent(entry.getKey(), entry.getValue()); } }
public void putAllIfAbsent(Map<? extends K, ? extends V> map, long loadTimeInMillis) { mbean.loadTimeForMisses.addAndGet(loadTimeInMillis); putAllIfAbsent(map); }
@Override public synchronized String toString() { return "SoftCache named " + getName() + ": " + cacheEntries.values().toString(); }
/** Adds an object to the cache. * @param key * @param value */ @Override public synchronized V put(K key, V value) { mbean.puts.incrementAndGet(); CacheEntry<V> entry = newSoftCacheEntry(key, value); CacheEntry<V> oldEntry = cacheEntries.put(key, entry); return safeValue(oldEntry); }
/** * Iterates through the cache and cleans up any cache references that have * been collected by the garbage collector. */ public final void cleanup() { mbean.cleanups.incrementAndGet(); if(log.isTraceEnabled()) { log.trace("cleanup() called on {} of size: {}", getName(), cacheEntries.size()); } int i = 0; Reference<? extends V> ref = referenceQueue.poll(); while (ref != null) { i++; assert ref.get() == null : "Referent should be null by the time the Reference is added to the queue"; removeReference(ref); ref = referenceQueue.poll(); } if(log.isTraceEnabled()) { log.trace("cleanup() finished on {}. {} keys were cleaned up. ", getName(), i); } }
/** This convenience method filters a request by removing all items in the request which * are in the cache and returning the corresponding values. * * Synchronization note: this method is not synchronized on the cache. Thus, if replacements * are performed during a canonicalization, it is undefined which object is returned. Similarly, * this function is not synchronized on the request collection, so if synchronization is required, * it must be performed externally. * * @param request The list of items to be fetched from the backing store. This collection must * be modifiable. */ public Collection<V> filter(Collection<K> request) { Collection<V> rv = new ArrayList<V>(); for (Iterator<K> iter = request.iterator(); iter.hasNext();) { K key = iter.next(); V val = get(key); if (val != null) { rv.add(val); iter.remove(); } } return rv; }
public synchronized void putAll(Map<? extends K, ? extends V> map) { for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { put(entry.getKey(), entry.getValue()); } }
public synchronized void putAllIfAbsent(Map<? extends K, ? extends V> map) { for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { putIfAbsent(entry.getKey(), entry.getValue()); } }
public void putAllIfAbsent(Map<? extends K, ? extends V> map, long loadTimeInMillis) { mbean.loadTimeForMisses.addAndGet(loadTimeInMillis); putAllIfAbsent(map); }
@Override public synchronized String toString() { return "SoftCache named " + getName() + ": " + cacheEntries.values().toString(); }
public SoftCache(int initialSize) { cacheEntries = createCache(initialSize); setName("SoftCache"); SoftCache.registerForCleanup(this); }
/** * If the specified key is not already associated with a value, associate it with the given value. This is equivalent to * * @param key * @param value * @return The value that was in the cache, null if none was there before */ public synchronized V putIfAbsent(K key, V value) { if (!containsKey(key)) { return put(key, value); } else { return get(key); } }
/** This convenience method takes a map of items returned from the backing store and replaces * references loaded from the backing store with items in the cache. * * A call to canonicalize will typically be followed by a putAll on the returnVal, so that * future requests to the cache will return the new items loaded. * * Synchronization note: this method is not synchronized on the cache. Thus, if replacements * are performed during a canonicalization, it is undefined which object is returned. Similarly, * this function is not synchronized on the returnVal map, so if synchronization is required, it * must be performed externally. * * @param returnVal The map of items to be canonicalized. This map must be modifiable. */ public void canonicalize(Map<K, V> returnVal) { Map<K, V> canonicalizedMappings = new HashMap<K, V>(); for (Iterator<Map.Entry<K, V> > iter = returnVal.entrySet().iterator(); iter.hasNext();) { Map.Entry<K, V> entry = iter.next(); V myValue = get(entry.getKey()); if (myValue != null) { iter.remove(); canonicalizedMappings.put(entry.getKey(), myValue); } } returnVal.putAll(canonicalizedMappings); }