views:

100

answers:

2

Are there any implementations of a static size hashtable that limits the entries to either the most recently or most frequently used metadata? I would prefer not to keep track of this information myself.

I know most caching components keep track of this, but I would rather not introduce quite a lot of new dependencies.

+10  A: 

You can build an LRU cache using the standard JDK library using LinkedHashMap:

public class MyLRUCache<K, V> extends LinkedHashMap<K, V> {

    private final int maxEntries;

    public MyLRUCache(int maxEntries) {
        // you can be a bit fancy with capacity and load factor
        super(16, 0.75, true);
        this.maxEntries = maxEntries;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > maxEntries;
    }
}

You may want to play with WeakReferences as well.

notnoop
I like that. I haven't heard of that before.
monksy
+2  A: 

Use LinkedHashMap and override removeEldestEntry and make sure to use the constructor that allows to accessOrder as true

Accessordered makes the map remove the least recently accessed item instead of the eldest.

All queries will alter the structure of the map, hence be a tiny bit slower.

Example:

public AccesOrderedLRUCache<V,K> extends LinkedHashMap<V,K>{
    private final m_capacity;

    public AccesOrderedLRUCache(int capacity) {
     super(0.75*capacity, 0.75, true);
     m_capacity = capacity;
    }

    @Override 
    protected boolean removeEldestEntry (Map.Entry<K,V> eldest) {
         return size() > getCapacity(); 
    }

    public int getCapacity() {
     return m_capacity;
    }
}
Fedearne
not in jdk 1.6.0_13. http://kickjava.com/src/java/util/LinkedHashMap.java.htm (dont know which version that is, but still no)
Fedearne
@Fedearne, thanks. I confused access-ordered by insertion-ordered
notnoop
0.75*capacity is probably not what you mean here. Assuming you actually mean capacity/0.75 ?Also getCapacity is missing a parens and I would prefer ref'ing m_capacity to LRUCache.this.cacheSize in removeEldestEntry().
Alex Miller
@Alex You are totally right about the cacheSize being wrong. 0.75*capacity is (as You most likely already know) the initial capacity. I don't se any point in making it larger than the maximum size. 75% of the maximum capacity might be that clever either. Do You have some insights on that?
Fedearne