Как использовать кэширование LRU на диске с клепто?

Я пытаюсь использовать клепто для LRU-кэширования. Я хотел бы сохранить кэш на диск, и в настоящее время я использую Klepto's dir_archive вариант для этого. Я написал следующий код, в значительной степени основанный на коде в скриптах теста klepto:

def mymap(data):
    return hashlib.sha256(data).hexdigest()

class MyLRUCache:
    @lru_cache(cache=dir_archive(cached=False), keymap=mymap, ignore='self', maxsize=5)
    def __call__(self, data)
        return data

    call = __call__

    def store(self, data):
        self.call(data)

    # I would also appreciate a better way to do this, if possible.
    def lookup(self, key):
        return self.call.__cache__()[key]

Этот код работает нормально, пока не достигнет кеша maxsize, На этом этапе вместо использования LRU для удаления одного элемента, lru_cache удаляет весь кеш! Ниже приведен фрагмент исходного кода Klepto, который делает это ( https://github.com/uqfoundation/klepto/blob/master/klepto/safe.py):

# purge cache
if _len(cache) > maxsize:
    if cache.archived():
        cache.dump()
        cache.clear() 
        queue.clear()
        refcount.clear()
     else: # purge least recently used cache entry
        key = queue_popleft()
        refcount[key] -= 1
        while refcount[key]:
            key = queue_popleft()
            refcount[key] -= 1
        del cache[key], refcount[key]

Итак, мой вопрос: почему Klepto удаляет "заархивированные" кэши? Можно ли использовать lru_cache а также dir_archive все вместе?

Кроме того, если мой код выглядит совершенно чокнутым, я был бы очень признателен за некоторый пример кода того, как я должен писать это, так как для klepto не было много документации.

ДОПОЛНИТЕЛЬНЫЕ ЗАМЕЧАНИЯ: я также попытался определить dir_archive с cached=True, Кэш в памяти все еще очищается, когда maxsize достигнут, но содержимое кеша сбрасывается в заархивированный кеш в этот момент. У меня есть несколько проблем с этим:

  1. Кэш в памяти точен только до maxsize достигается, в этот момент он стирается.
  2. На архивированный кеш не влияет maxsize, Каждый раз maxsize достигается кэшем в памяти, все элементы в кэше в памяти выгружаются в архивный кеш, независимо от того, сколько их уже есть.
  3. Кэширование LRU кажется невозможным на основании пунктов 1 и 2.

1 ответ

Решение

Ответ в том, что вы не могли раньше ответить на свой вопрос, но теперь вы можете. Если вы получаете самые последние klepto от GitHub, и предоставьте новый флагpurge=False - тогда вы получите поведение, которое вы ищете. Я просто добавил это в ответ на ваш вопрос.

В твоем случае:

lru_cache(cache=dir_archive(cached=False), keymap=mymap, ignore='self', maxsize=5, purge=False)

Или, например:

@lru_cache(maxsize=3, cache=dict_archive('test'), purge=True)
def identity(x):
  return x

identity(1)
identity(2)
identity(3)
ic = identity.__cache__()
assert len(ic.keys()) == 3
assert len(ic.archive.keys()) == 0
identity(4)
assert len(ic.keys()) == 0
assert len(ic.archive.keys()) == 4
identity(5)
assert len(ic.keys()) == 1
assert len(ic.archive.keys()) == 4

@lru_cache(maxsize=3, cache=dict_archive('test'), purge=False)
def inverse(x):
  return -x

inverse(1)
inverse(2)
inverse(3)
ic = inverse.__cache__()
assert len(ic.keys()) == 3
assert len(ic.archive.keys()) == 0
inverse(4)
assert len(ic.keys()) == 3
assert len(ic.archive.keys()) == 1
inverse(5)
assert len(ic.keys()) == 3
assert len(ic.archive.keys()) == 2

Пожалуйста, добавьте билет, если это не делает то, что вы ожидали. Спасибо за предложение.

Другие вопросы по тегам