Cache implementations and the "in" operator / __contains__ method
Closed this issue · 2 comments
Consider the following examples:
from cachetools import LRUCache
cache = LRUCache(2)
cache[1] = 1
cache[2] = 2
cache[1] # get first key
cache[3] = 3
cache
Expected and actual result:
LRUCache([(1, 1), (3, 3)], maxsize=2, currsize=2)
But if you use the in
operator or the __contains__
method instead, this doesn't count as usage:
from cachetools import LRUCache
cache = LRUCache(2)
cache[1] = 1
cache[2] = 2
1 in cache # lookup first key
cache[3] = 3
cache
Expected result:
LRUCache([(1, 1), (3, 3)], maxsize=2, currsize=2)
Actual result:
LRUCache([(2, 2), (3, 3)], maxsize=2, currsize=2)
Hanse the question -- is this by design?
I saw only one other kinda-related issue #26, which is the opposite case of this one -- missing vs contains.
Yes, using the in
operator doesn't count as usage and should not affect caching behavior.
It surely can be argued both ways, but frankly it just never occurred to me that __contains__()
could be seen as "accessing" the cached item.
Thank you for answering. My use case requires this behavior, so I wanted to know if this is by design.
Example with lookup (this use case doesn't care about the actual stored value):
from cachetools import LRUCache
class LookupCache(LRUCache):
def __contains__(self, key):
found = super().__contains__(key)
self[key] = None
return found
cache = LookupCache(2)
cache[1] = 1
cache[2] = 2
1 in cache # lookup first key
cache[3] = 3
cache