sql >> Database teknologi >  >> NoSQL >> MongoDB

Python:opbygning af en LRU-cache

LRU-cachen i Python3.3 har O(1) indsættelse, sletning og søgning.

Designet bruger en cirkulær dobbelt-linket liste over poster (ordnet ældst-til-nyeste) og en hash-tabel til at finde individuelle links. Cache-hits bruger hash-tabellen til at finde det relevante link og flytte det til toppen af ​​listen. Cache misses sletter det ældste link og opretter et nyt link i spidsen af ​​den linkede liste.

Her er en forenklet (men hurtig) version i 33 linjer med meget grundlæggende Python (kun ved hjælp af simple ordbogs- og listeoperationer). Den kører på Python2.0 og senere (eller PyPy eller Jython eller Python3.x):

class LRU_Cache:

    def __init__(self, original_function, maxsize=1024):
        # Link structure: [PREV, NEXT, KEY, VALUE]
        self.root = [None, None, None, None]
        self.root[0] = self.root[1] = self.root
        self.original_function = original_function
        self.maxsize = maxsize
        self.mapping = {}

    def __call__(self, *key):
        mapping = self.mapping
        root = self.root
        link = mapping.get(key)
        if link is not None:
            link_prev, link_next, link_key, value = link
            link_prev[1] = link_next
            link_next[0] = link_prev
            last = root[0]
            last[1] = root[0] = link
            link[0] = last
            link[1] = root
            return value
        value = self.original_function(*key)
        if len(mapping) >= self.maxsize:
            oldest = root[1]
            next_oldest = oldest[1]
            root[1] = next_oldest
            next_oldest[0] = root
            del mapping[oldest[2]]
        last = root[0]
        last[1] = root[0] = mapping[key] = [last, root, key, value]
        return value


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

Startende i Python 3.1, OrderedDict gør det endnu nemmere at implementere en LRU-cache:

from collections import OrderedDict

class LRU_Cache:

    def __init__(self, original_function, maxsize=1024):
        self.original_function = original_function
        self.maxsize = maxsize
        self.mapping = OrderedDict()

    def __call__(self, *key):
        mapping = self.mapping
        try:
            value = mapping[key]
            mapping.move_to_end(key)
        except KeyError:
            value = self.original_function(*key)
            if len(mapping) >= self.maxsize:
                mapping.popitem(False)
            mapping[key] = value
        return value


  1. Hvordan får man Redis til at starte på Heroku?

  2. Redigere nøglenavnekonventioner?

  3. Hvordan kan jeg teste nye aggregeringsramme for Mongodb

  4. Sådan udelukker du nogle felter fra dokumentet