View Javadoc
1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
3    * Thomschke.
4    * 
5    * All Rights Reserved. This program and the accompanying materials
6    * are made available under the terms of the Eclipse Public License v1.0
7    * which accompanies this distribution, and is available at
8    * http://www.eclipse.org/legal/epl-v10.html
9    * 
10   * Contributors:
11   *     Sebastian Thomschke - initial implementation.
12   *******************************************************************************/
13  package net.sf.oval.internal.util;
14  
15  import java.lang.ref.SoftReference;
16  import java.util.HashMap;
17  import java.util.LinkedList;
18  import java.util.Map;
19  
20  /**
21   * @author Sebastian Thomschke
22   */
23  public final class ObjectCache<K, V>
24  {
25  	private final Map<K, SoftReference<V>> map = new HashMap<K, SoftReference<V>>();
26  
27  	private final LinkedList<V> objectsLastAccessed = new LinkedList<V>();
28  	private final int objectsToKeepCount;
29  
30  	/**
31  	 * Creates a new cache keeping all objects.
32  	 */
33  	public ObjectCache()
34  	{
35  		objectsToKeepCount = -1;
36  	}
37  
38  	/**
39  	 * @param maxObjectsToKeep the number of cached objects that should stay in memory when GC 
40  	 * starts removing SoftReferences to free memory 
41  	 */
42  	public ObjectCache(final int maxObjectsToKeep)
43  	{
44  		this.objectsToKeepCount = maxObjectsToKeep;
45  	}
46  
47  	public void compact()
48  	{
49  		for (final Map.Entry<K, SoftReference<V>> entry : map.entrySet())
50  		{
51  			final SoftReference<V> ref = entry.getValue();
52  			if (ref.get() == null) map.remove(entry.getKey());
53  		}
54  	}
55  
56  	public boolean contains(final K key)
57  	{
58  		return map.containsKey(key);
59  	}
60  
61  	public V get(final K key)
62  	{
63  		final SoftReference<V> softReference = map.get(key);
64  		if (softReference != null)
65  		{
66  			final V value = softReference.get();
67  
68  			if (value == null)
69  				map.remove(key);
70  			else if (objectsToKeepCount > 0 && value != objectsLastAccessed.getFirst())
71  			{
72  				objectsLastAccessed.remove(value);
73  				objectsLastAccessed.addFirst(value);
74  				if (objectsLastAccessed.size() > objectsToKeepCount) objectsLastAccessed.removeLast();
75  			}
76  			return softReference.get();
77  		}
78  		return null;
79  	}
80  
81  	public void put(final K key, final V value)
82  	{
83  		map.remove(key);
84  		map.put(key, new SoftReference<V>(value));
85  	}
86  }