peter
peter

Reputation: 8473

LinkedHashMap Structure for LRU Cache

I am a little confused about how to build a LRU cache by using LinkedHashMap (How would you implement an LRU cache in Java 6?), and I want to make sure I understand how it work internally behind the scene.

Lets say I define a class LRUMap that extends the LinkedHashMap and override the removeEldestEntry(final Map.Entry<A, B> eldest) just like the way it is.

Then I construct the data structure and insert 4 items into the map

    LRUMap<String,String> map = new LRUMap<String,String>(3); //capacity 3
    map.put("a", "a");
    map.put("b", "b");
    map.put("c", "c");
    map.put("d", "d");

and interally LinkedHashMap uses an Entry object called header as a starting node to link with all the items that you add to the map. So in this case it will be

   [header] ->  ["a"] -> ["b"] -> ["c"] -> ["d"] -> [header]

The header Entry object is both the start and the end of the doubly linked list since header.before = header.after = header when it initially constructs.

And lets say the map reaches the maximum Entries (3 items) that I want it to be, and from

    Entry<K,V> eldest = header.after;
    if (removeEldestEntry(eldest)) {
         removeEntryForKey(eldest.key);
    }
    .....

So does that mean it will remove ["a"] first ?
And when we call get(Object key) does it rearrange the list order where it puts that key (lets say "b") before the header node, so it becomes

     [header] ->  ["c"] -> ["d"] -> ["b"] -> [header]

Just want to clarify that.

Upvotes: 6

Views: 5629

Answers (1)

obataku
obataku

Reputation: 29646

  1. Yes; the entry <"a", "a"> will be removed first :-)
  2. Maybe; LinkedHashMap by default uses insertion-order, not access-order... straight from the specification:

    Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).

    That being said, LinkedHashMap also supports access-order;

    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).

    So, if you're using insertion-order, then the order will not change from get("b"); if you're using access-order (which generally an LRU cache would ;-) then the order will change.

Any other questions? :-)

Upvotes: 13

Related Questions