aboutsummaryrefslogtreecommitdiff
path: root/src/Cache.py
blob: 97e09268ba9577e554c717f0aa535b4a272b6923 (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
55
56
57
58
59
60
61
62
63
64
65
66
import hashlib, time, typing, uuid
from src import PollHook

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

        self._cached_expiration = None

    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.time()+timeout)
    def _cache(self, key: str, value: typing.Any,
            expiration: typing.Optional[float]) -> str:
        id = self.cache_key(key)
        self._cached_expiration = None
        self._items[id] = [key, value, expiration]
        return id

    def next(self) -> typing.Optional[float]:
        if not self._cached_expiration == None:
            return self._cached_expiration

        expirations = [value[-1] for value in self._items.values()]
        expirations = list(filter(None, expirations))
        if not expirations:
            return None
        now = time.time()
        expirations = [e-now for e in expirations]

        expiration = max(min(expirations), 0)
        self._cached_expiration = expiration
        return expiration

    def call(self):
        now = time.time()
        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:
            self._cached_expiration = None
            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):
        self._cached_expiration = None
        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.time()