package rabbitescape.render; import rabbitescape.render.androidlike.Bitmap; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; public class ReLruCache<T extends Bitmap> { private final long maxSize; private long curSize; private final Map<String, T> map; private final Queue<String> usedKeys; public ReLruCache( long maxSize ) { this.maxSize = maxSize; this.curSize = 0; this.map = new HashMap<>(); this.usedKeys = new LinkedList<>(); } public void put( String key, T value ) { if ( value == null ) { throw new IllegalArgumentException( "Null values are not allowed in LruCache" ); } makeSpaceFor( value ); T existing = map.get( key ); if ( existing != null ) { usedKeys.remove( key ); curSize -= existing.getByteCount(); } usedKeys.add( key ); map.put( key, value ); curSize += value.getByteCount(); } public T get( String key ) { T ret = map.get( key ); if ( ret != null ) { usedKeys.remove( key ); // Move key to front usedKeys.add( key ); // because it was used } return ret; } public long currentSize() { return curSize; } public void recycle() { for ( T bitmap : map.values() ) { bitmap.recycle(); } map.clear(); usedKeys.clear(); } // --- private void makeSpaceFor( T value ) { long valueSize = value.getByteCount(); while ( !isEmpty() && currentSize() + valueSize > maxSize ) { recycleOldest(); } } private boolean isEmpty() { return map.isEmpty(); } private void recycleOldest() { String oldestKey = usedKeys.remove(); T value = map.remove( oldestKey ); curSize -= value.getByteCount(); value.recycle(); } }