aboutsummaryrefslogtreecommitdiff
path: root/src/Cache.py
blob: 7a72c1f211c7b70c2d794b3a9344172012fecd93 (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import hashlib, time, typing, uuid

class Cache(object):
    def __init__(self):
        self._items = {}

    def cache_key(self, key: str):
        return "sha1:%s" % hashlib.sha1(key.encode("utf8")).hexdigest()

    def cache(self, key: str, value: typing.Any) -> str:
        return self._cache(key, value, None)
    def temporary_cache(self, key: str, value: typing.Any, timeout: float
            )-> str:
        return self._cache(key, value, time.monotonic()+timeout)
    def _cache(self, key: str, value: typing.Any,
            expiration: typing.Optional[float]) -> str:
        id = self.cache_key(key)
        self._items[id] = [key, value, expiration]
        return id

    def next_expiration(self) -> typing.Optional[float]:
        expirations = [value[-1] for value in self._items.values()]
        expirations = list(filter(None, expirations))
        if not expirations:
            return None
        now = time.monotonic()
        expirations = [e-now for e in expirations]
        return max(min(expirations), 0)

    def expire(self):
        now = time.monotonic()
        expired = []
        for id in self._items.keys():
            key, value, expiration = self._items[id]
            if expiration and expiration <= now:
                expired.append(id)
        for id in expired:
            del self._items[id]

    def has_item(self, key: typing.Any) -> bool:
        return self.cache_key(key) in self._items

    def get(self, key: str) -> typing.Any:
        key, value, expiration = self._items[self.cache_key(key)]
        return value
    def remove(self, key: str):
        del self._items[self.cache_key(key)]

    def get_expiration(self, key: typing.Any) -> float:
        key, value, expiration = self._items[self.cache_key(key)]
        return expiration
    def until_expiration(self, key: typing.Any) -> float:
        expiration = self.get_expiration(key)
        return expiration-time.monotonic()