Data structure that supports efficient kick-out policy based on recently accessed items

YohanRoth :

I need a data structure that would support the most efficient kick-out policy for items that are were requested the longest time ago. e.g I have bunch of items that are being requested time to time. when I run out of memory I want to kick out the oldest items in my data structure (hash map).

I was thinking about FIFO ds smth like Queue, but I am not sure how to deal with this situation:

--> a b c d a -->

a is both oldest and newest item. If on adding "a" again I need to search entire queue to delete it. It is very inefficient, but I cannot think of any efficient way of doing it. Maybe some kind of a tree structure that keeps the least accessed one at the top?

Are there any implementation of such data structure in Java already?

Federico Peralta Schaffner :

LinkedHashMap is the structure you're after. From the docs:

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.

So you should just use the appropriate constructor:

Map<K, V> map = new LinkedHashMap<>(CAPACITY, LOAD_FACTOR, true);

The boolean argument determines if the map is access-order or insertion-order. true means access-order.

Furthermore, if you want your map to work as a LRU cache, you can create your own class that extends LinkedHashMap and overrides the removeEldestEntry method. Again, from the docs:

The removeEldestEntry(Map.Entry) method may be overridden to impose a policy for removing stale mappings automatically when new mappings are added to the map.

This means that you could create your own class for the cache:

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

    private static final int MAX_ENTRIES = 100;

    public Cache() {
        super(SOME_INITIAL_CAPACITY, SOME_LOAD_FACTOR, true);
    }

    protected boolean removeEldestEntry(Entry<K, V> entry) {
        return size() > MAX_ENTRIES;
    }
}

Usage:

Map<K, V> map = new Cache<>();

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=91495&siteId=1