/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt
******************************************************************************/
package com.opendoorlogistics.core.utils;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import com.sun.corba.se.impl.oa.poa.ActiveObjectMap.Key;
/**
* A very simple map using soft references (references which are garbage-collected
* when needed). Every nbPutsTillClear puts the map is checked for any references
* which are no longer valid and the keys are removed.
* @author Phil
*
* @param <Key>
* @param <Value>
*/
final public class SimpleSoftReferenceMap<Key,Value> implements Iterable<Map.Entry<Key,Value>> {
private final HashMap<Key, SoftReference<Value>> map = new HashMap<>();
private static final int DEFAULT_PUTS_TILL_CLEAR = 1000;
private int nbPuts;
private int putsTillClear = DEFAULT_PUTS_TILL_CLEAR;
public SimpleSoftReferenceMap(){
}
public SimpleSoftReferenceMap(int nbPutsTillClear){
this.putsTillClear = nbPutsTillClear;
}
public void clear(){
map.clear();
}
public Value get(Key key){
Value ret=null;
SoftReference<Value> soft = map.get(key);
if(soft!=null){
ret = soft.get();
if(ret==null){
map.remove(key);
}
}
return ret;
}
public void put(Key key, Value value){
map.put(key, new SoftReference<Value>(value));
if(nbPuts>putsTillClear){
Iterator<Map.Entry<Key,SoftReference<Value>>> it = map.entrySet().iterator();
while(it.hasNext()){
if(it.next().getValue().get()==null){
it.remove();
}
};
nbPuts=0;
}else{
nbPuts++;
}
}
public int size(){
return map.size();
}
public void remove(Key key){
map.remove(key);
}
@Override
public Iterator<Entry<Key, Value>> iterator() {
HashMap<Key, Value> tmpMap = new HashMap<>();
for(Map.Entry<Key, SoftReference<Value>> entry:map.entrySet()){
Value val = entry.getValue().get();
if(val!=null){
tmpMap.put(entry.getKey(), val);
}
}
return tmpMap.entrySet().iterator();
}
}