Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 273
peter Avatar asked Aug 19 '12 21:08

peter


People also ask

Which data structure is used for LRU cache?

An LRU cache is built by combining two data structures: a doubly linked list and a hash map.

What is LinkedHashMap in data structures?

LinkedHashMap is the data structure used to store the key-value pairs like HashMap but it guarantees the order of insertion(unlike the HashMap). So the elements are stored in the order of their insertion.

Why does LRU cache need a doubly linked list?

Optimized Approach: The key to solve this problem is using a double linked list which enables us to quickly move nodes. The LRU cache is a hash map of keys and double linked nodes. The hash map makes the time of get() to be O(1). The list of double linked nodes make the nodes adding/removal operations O(1).


1 Answers

  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? :-)

like image 156
obataku Avatar answered Oct 01 '22 15:10

obataku