

Solving Problems Using Data Structures - variadic
http://variadic.me/posts/2013-03-06-solving-problems-data-structures.html

======
ianbishop
There is actually an LRU map implemented in Java, though it is sort of hidden
in the LinkedHashMap using a special constructor.

[http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Linke...](http://docs.oracle.com/javase/1.4.2/docs/api/java/util/LinkedHashMap.html#LinkedHashMap\(int,%20float,%20boolean\))

~~~
jwn
One issue with that is that it doesn't expel older entries. The capacity
specified in the constructor is just the initial capacity.

------
headfake
from collections import deque

class LRUDict(dict):

    
    
        """ LRU queue with dictionary lookups based on the Python Cookbook RingBuffer recipe.
         A deque-based ringbuffer expires entries past size_max.
        Doesn't allow deletion for obvious reasons.
        """
    
        def __init__(self, size_max):
            dict.__init__(self)
            self.queue = deque()
            self.size_max = size_max-1
    
        def append(self, value):
            self.queue.append(value)
            if len(self) >= self.size_max:
                self.append = self._full_append
    
        def _full_append(self, value):
            self.queue.append(value)
            return super(LRUDict, self).__delitem__(self.queue.popleft())
    
        def __repr__(self):
            return "%s(%s)" % (self.__class__.__name__, dict.__repr__(self))
    
        def __setitem__(self, key, value):
            if key not in self:
                self.append(key)
            return super(LRUDict, self).__setitem__(key, value)
    
        def __delitem__(self, key):
            pass

------
iand
Wouldn't this be better implemented using a standard priority queue where the
score is related to the timestamp of insertion?

~~~
ohwp
My thought exactly. I don't get his example. But maybe it's a speed issue.
Adding items to a Dictionary might be faster than updating a timestamp on an
object.

~~~
shintoist
That doesn't make sense. The fundamental operations on a queue is push and
pop. If you pop from the queue, you remove it from the queue. So on page
reload, the 5 latest viewed entries would be gone. You popped them.

A queue is fundamentally wrong for this type of use case.

~~~
meta
I think they are implying you only pop() when you are doing the replacement
(Trim). The rest of the time you Sink and Swim depending on how the LRU was
done. IE: every time you get() an item you set the access time to now() and
then call sink/swim to fix the ordering. This would give logn time to get and
set.

See here for a very good writeup of priority queues and variants.
<http://algs4.cs.princeton.edu/24pq/>

(not hugely familiar with Java so this stuff might be wrong) The
implementation presented has some bad timing issues (List.Contains is a linear
search). I think List.Remove is also a linear search. As well this
implementation doesn't seem to do Point (1).

~~~
morpher
The OP is talking about a list with at most five items in it. Linear search is
not an issue. Using a dict may even be slower than just searching a 5 element
array linearly...

------
jehud
Why not use a Set and a doubly linked list?

------
vemv
I'd use a sorted set.

