How to create the last recently used cache?

How to create the last recently used cache?

Suppose you visited some items. You need to create a data structure to store these items. Each item is associated with the last time visited.

Every time you visit an item, check it in the data structure. If the item is in cache, update its visit time. Otherwise, insert it into the cache. The cache size is fixed, if it is full, delete the oldest item.

My decision:

  • Use the map <item, visitTime>

  • Initaliztion: Sort map with f (visitTime) in descending order. O (nlg n)

  • If the object is visited, find it on the map using O (lg n).

  • If it was on the map, update the time O (1). Sort map O (lg p).

  • If not, insert it into the card and then sort. O (log n)

  • If card size> fixed size, delete the last O (1) element.

Another solution:

  • Using hashtable <item, visitTime>

  • Sort O (n lgn).

  • If the object is visited, find it in the talba using O (1).

  • If it was in the table, update the O (1) time. Sort table O (n lg n).

  • If not, insert it into the table and then sort. O (n lg n)

  • If the table size is> fixed size, delete the last O (1) element.

Are there any better solutions? O (n)?

+5
source share
6 answers

If you use the Doubly Linked List, you will get the setting O (1) (after searching), O (1), O (n).

Assuming you insert new elements in front:

, (O (1)).

, (O (n)), (O (1)), (O (1)).

, , (O (1)) (O (1)) [: , , O (n)].

, .

+4

Python LRU cache , O (1). ( ) - .

( ) 40 Python. Python ++:

class LRU_Cache(object):

    def __init__(self, original_function, maxsize=1000):
        self.original_function = original_function
        self.maxsize = maxsize
        self.mapping = {}

        PREV, NEXT, KEY, VALUE = 0, 1, 2, 3
        self.head = [None, None, None, None]        # oldest
        self.tail = [self.head, None, None, None]   # newest
        self.head[NEXT] = self.tail

    def __call__(self, *key):
        PREV, NEXT, KEY, VALUE = 0, 1, 2, 3
        mapping, head, tail = self.mapping, self.head, self.tail
        sentinel = object()

        link = mapping.get(key, sentinel)
        if link is sentinel:
            value = self.original_function(*key)
            if len(mapping) >= self.maxsize:
                oldest = head[NEXT]
                next_oldest = oldest[NEXT]
                head[NEXT] = next_oldest
                next_oldest[PREV] = head
                del mapping[oldest[KEY]]
            last = tail[PREV]
            link = [last, tail, key, value]
            mapping[key] = last[NEXT] = tail[PREV] = link
        else:
            link_prev, link_next, key, value = link
            link_prev[NEXT] = link_next
            link_next[PREV] = link_prev
            last = tail[PREV]
            last[NEXT] = tail[PREV] = link
            link[PREV] = last
            link[NEXT] = tail
        return value

if __name__ == '__main__':
    p = LRU_Cache(ord, maxsize=3)
    for c in 'abcdecaeaa':
        print(c, p(c))
+3

, . - . -, , , ( - - ). . ( -). , .

: std:: list iterator , , . . .

+1

Java java.util.LinkedHashSet. - , , . () , , .

WeakHashMap, , .

+1

. , ( ).

O(n).

0

Take a look at boost :: multi_index . One example he shows is the MRU List .

0
source

All Articles