package com.rubika.aotalk.util;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import android.graphics.Bitmap;
public class MemoryCache {
private static final String APP_TAG = "--> The Leet :: MemoryCache";
private Map<String, Bitmap> cache = Collections.synchronizedMap(new LinkedHashMap<String, Bitmap>(10,1.5f,true)); //Last argument true for LRU ordering
private long size = 0; //current allocated size
private long limit = 1000000; //max memory in bytes
public MemoryCache(){
//use 25% of available heap size
setLimit(Runtime.getRuntime().maxMemory() / 4);
}
public void setLimit(long new_limit){
limit = new_limit;
Logging.log(APP_TAG, "MemoryCache will use up to " + limit/1024./1024. + "MB");
}
public Bitmap get(String id){
try{
if (!cache.containsKey(id)) {
return null;
}
return cache.get(id);
} catch(NullPointerException ex) {
Logging.log(APP_TAG, ex.getMessage());
return null;
}
}
public void put(String id, Bitmap bitmap){
try{
if (cache.containsKey(id)) {
size-=getSizeInBytes(cache.get(id));
}
cache.put(id, bitmap);
size += getSizeInBytes(bitmap);
checkSize();
} catch(Throwable th) {
Logging.log(APP_TAG, th.getMessage());
}
}
private void checkSize() {
Logging.log(APP_TAG, "cache size=" + size + " length=" + cache.size());
if (size>limit) {
Iterator<Entry<String, Bitmap>> iter = cache.entrySet().iterator(); //least recently accessed item will be the first one iterated
while (iter.hasNext()) {
Entry<String, Bitmap> entry = iter.next();
size -= getSizeInBytes(entry.getValue());
iter.remove();
if (size <= limit) {
break;
}
}
Logging.log(APP_TAG, "Clean cache. New size "+cache.size());
}
}
public void clear() {
try{
cache.clear();
size = 0;
} catch (NullPointerException ex) {
Logging.log(APP_TAG, ex.getMessage());
}
}
long getSizeInBytes(Bitmap bitmap) {
if (bitmap == null) {
return 0;
}
return bitmap.getRowBytes() * bitmap.getHeight();
}
}