In my previous post where I use PriorityQueue to construct a LRU cache. I was aware of LinkedHashMap data structure, but never provided great attention to its documentation. It turns out there is a much simpler way to construct an LRU cache using it.
The documentation clearly states,
"A special
The
With this new discovery (at-least I became aware of the fact :) ), I wanted to try this out. Within few minutes, I was ready to test my code and as expected the code works. For purpose of testing, I have printed the eldest entry that will be removed once the size is reached. As you can see, I extended LinkedHashMap and overridden the method: removeEldestEntry.
Following is the code if someone wishes to try out.
Output produces is:
Size limit reached, removing eldest entry:e
size:5
Cache contains:d
Cache contains:c
Cache contains:b
Cache contains:f
Cache contains:a
Conclusion/Advantages:
1) Code is very much terse.
2) Reusing the code which is much stable, instead of re-inventing the world.
The documentation clearly states,
"A special
constructor is provided to create a linked hash map whose order of iteration is the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order). This kind of map is well-suited to building LRU caches. Invoking the put or get method results in an access to the corresponding entry (assuming it exists after the invocation completes). The putAll method generates one entry access for each mapping in the specified map, in the order that key-value mappings are provided by the specified map's entry set iterator. No other methods generate entry accesses. In particular, operations on collection-views do not affect the order of iteration of the backing mapThe
removeEldestEntry(Map.Entry) method may be overridden to impose a policy for removing stale mappings automatically when new mappings are added to the map."With this new discovery (at-least I became aware of the fact :) ), I wanted to try this out. Within few minutes, I was ready to test my code and as expected the code works. For purpose of testing, I have printed the eldest entry that will be removed once the size is reached. As you can see, I extended LinkedHashMap and overridden the method: removeEldestEntry.
Following is the code if someone wishes to try out.
package lru;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class Cache extends LinkedHashMap {
private static int CACHE_SIZE=5;
private static float LOAD_FACTOR = 0.75f;
private static boolean ACCESS_ORDER = true;
public Cache(int initialCapacity, float loadFactor, boolean accessOrder) {
super(initialCapacity,loadFactor, accessOrder);
}
protected boolean removeEldestEntry(Map.Entry eldest) {
if (size() > CACHE_SIZE) {
System.out.println("Size limit reached, removing eldest entry:"+eldest.getKey());
return true;
} else {
return false;
}
}
public static void main (String[] args) {
Cache cache = new Cache(CACHE_SIZE, LOAD_FACTOR , ACCESS_ORDER);
cache.put("a","a");cache.put("b","b");
cache.put("c","c");cache.put("d","d");
cache.put("e","e");cache.put("b","b");
cache.put("d","d");cache.put("b","b");
cache.put("c","c");cache.put("b","b");
cache.put("a","a");cache.put("f","f");
cache.get("a");
System.out.println("size:"+cache.size());
Set keys = cache.keySet();
for (String key : keys) {
System.out.println("Cache contains:"+key);
}
}
}
Output produces is:
Size limit reached, removing eldest entry:e
size:5
Cache contains:d
Cache contains:c
Cache contains:b
Cache contains:f
Cache contains:a
Conclusion/Advantages:
1) Code is very much terse.
2) Reusing the code which is much stable, instead of re-inventing the world.
No comments:
Post a Comment