cache calculated "next expiration" time

This commit is contained in:
jesopo 2019-09-20 11:47:57 +01:00
parent 8a3e480ef5
commit d609bfb16d

View file

@ -4,6 +4,8 @@ class Cache(object):
def __init__(self): def __init__(self):
self._items = {} self._items = {}
self._cached_expiration = None
def cache_key(self, key: str): def cache_key(self, key: str):
return "sha1:%s" % hashlib.sha1(key.encode("utf8")).hexdigest() return "sha1:%s" % hashlib.sha1(key.encode("utf8")).hexdigest()
@ -15,17 +17,24 @@ class Cache(object):
def _cache(self, key: str, value: typing.Any, def _cache(self, key: str, value: typing.Any,
expiration: typing.Optional[float]) -> str: expiration: typing.Optional[float]) -> str:
id = self.cache_key(key) id = self.cache_key(key)
self._cached_expiration = None
self._items[id] = [key, value, expiration] self._items[id] = [key, value, expiration]
return id return id
def next_expiration(self) -> typing.Optional[float]: def next_expiration(self) -> typing.Optional[float]:
if not self._cached_expiration == None:
return self._cached_expiration
expirations = [value[-1] for value in self._items.values()] expirations = [value[-1] for value in self._items.values()]
expirations = list(filter(None, expirations)) expirations = list(filter(None, expirations))
if not expirations: if not expirations:
return None return None
now = time.monotonic() now = time.monotonic()
expirations = [e-now for e in expirations] expirations = [e-now for e in expirations]
return max(min(expirations), 0)
expiration = max(min(expirations), 0)
self._cached_expiration = expiration
return expiration
def expire(self): def expire(self):
now = time.monotonic() now = time.monotonic()
@ -35,6 +44,7 @@ class Cache(object):
if expiration and expiration <= now: if expiration and expiration <= now:
expired.append(id) expired.append(id)
for id in expired: for id in expired:
self._cached_expiration = None
del self._items[id] del self._items[id]
def has_item(self, key: typing.Any) -> bool: def has_item(self, key: typing.Any) -> bool:
@ -44,6 +54,7 @@ class Cache(object):
key, value, expiration = self._items[self.cache_key(key)] key, value, expiration = self._items[self.cache_key(key)]
return value return value
def remove(self, key: str): def remove(self, key: str):
self._cached_expiration = None
del self._items[self.cache_key(key)] del self._items[self.cache_key(key)]
def get_expiration(self, key: typing.Any) -> float: def get_expiration(self, key: typing.Any) -> float: