/** * Removes the least recently used elements if the cache size is greater than or equal to the * maximum allowed size until the cache is at least 10% empty. */ protected synchronized void cullCache() { // Check if a max cache size is defined. if (maxCacheSize < 0) { return; } // See if the cache is too big. If so, clean out cache until it's 10% free. if (map.size() > maxCacheSize) { // First, delete any old entries to see how much memory that frees. deleteExpiredEntries(); // Next, delete the least recently used elements until 10% of the cache // has been freed. int desiredSize = (int) (maxCacheSize * .90); for (int i = map.size(); i > desiredSize; i--) { // Get the key and invoke the remove method on it. if (remove(lastAccessedList.getLast().object, true) == null) { LOGGER.warning( "Error attempting to cullCache with remove(" + lastAccessedList.getLast().object.toString() + ") - cacheObject not found in cache!"); lastAccessedList.getLast().remove(); } } } }
public synchronized boolean containsKey(Object key) { // First, clear all entries that have been in cache longer than the // maximum defined age. deleteExpiredEntries(); return map.containsKey(key); }
public synchronized Set<K> keySet() { // First, clear all entries that have been in cache longer than the // maximum defined age. deleteExpiredEntries(); return Collections.unmodifiableSet(map.keySet()); }
public synchronized Collection<V> values() { // First, clear all entries that have been in cache longer than the // maximum defined age. deleteExpiredEntries(); return Collections.unmodifiableCollection( new AbstractCollection<V>() { Collection<CacheObject<V>> values = map.values(); public Iterator<V> iterator() { return new Iterator<V>() { Iterator<CacheObject<V>> it = values.iterator(); public boolean hasNext() { return it.hasNext(); } public V next() { return it.next().object; } public void remove() { it.remove(); } }; } public int size() { return values.size(); } }); }
public synchronized boolean isEmpty() { // First, clear all entries that have been in cache longer than the // maximum defined age. deleteExpiredEntries(); return map.isEmpty(); }
public synchronized boolean containsValue(Object value) { // First, clear all entries that have been in cache longer than the // maximum defined age. deleteExpiredEntries(); //noinspection unchecked @SuppressWarnings("unchecked") CacheObject<V> cacheObject = new CacheObject<V>((V) value); return map.containsValue(cacheObject); }
public synchronized Set<Map.Entry<K, V>> entrySet() { // Warning -- this method returns CacheObject instances and not Objects // in the same form they were put into cache. // First, clear all entries that have been in cache longer than the // maximum defined age. deleteExpiredEntries(); return new AbstractSet<Map.Entry<K, V>>() { private final Set<Map.Entry<K, CacheObject<V>>> set = map.entrySet(); public Iterator<Entry<K, V>> iterator() { return new Iterator<Entry<K, V>>() { private final Iterator<Entry<K, CacheObject<V>>> it = set.iterator(); public boolean hasNext() { return it.hasNext(); } public Entry<K, V> next() { Map.Entry<K, CacheObject<V>> entry = it.next(); return new AbstractMapEntry<K, V>(entry.getKey(), entry.getValue().object) { @Override public V setValue(V value) { throw new UnsupportedOperationException("Cannot set"); } }; } public void remove() { it.remove(); } }; } public int size() { return set.size(); } }; }
public synchronized V get(Object key) { // First, clear all entries that have been in cache longer than the // maximum defined age. deleteExpiredEntries(); CacheObject<V> cacheObject = map.get(key); if (cacheObject == null) { // The object didn't exist in cache, so increment cache misses. cacheMisses++; return null; } // Remove the object from it's current place in the cache order list, // and re-insert it at the front of the list. cacheObject.lastAccessedListNode.remove(); lastAccessedList.addFirst(cacheObject.lastAccessedListNode); // The object exists in cache, so increment cache hits. Also, increment // the object's read count. cacheHits++; cacheObject.readCount++; return cacheObject.object; }