diff options
author | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:24:06 +0300 |
---|---|---|
committer | nkozlovskiy <nmk@ydb.tech> | 2023-09-29 12:41:34 +0300 |
commit | e0e3e1717e3d33762ce61950504f9637a6e669ed (patch) | |
tree | bca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/python/prompt-toolkit/py2/prompt_toolkit/cache.py | |
parent | 38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff) | |
download | ydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz |
add ydb deps
Diffstat (limited to 'contrib/python/prompt-toolkit/py2/prompt_toolkit/cache.py')
-rw-r--r-- | contrib/python/prompt-toolkit/py2/prompt_toolkit/cache.py | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/cache.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/cache.py new file mode 100644 index 00000000000..55c7369c9c5 --- /dev/null +++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/cache.py @@ -0,0 +1,111 @@ +from __future__ import unicode_literals +from collections import deque +from functools import wraps + +__all__ = ( + 'SimpleCache', + 'FastDictCache', + 'memoized', +) + + +class SimpleCache(object): + """ + Very simple cache that discards the oldest item when the cache size is + exceeded. + + :param maxsize: Maximum size of the cache. (Don't make it too big.) + """ + def __init__(self, maxsize=8): + assert isinstance(maxsize, int) and maxsize > 0 + + self._data = {} + self._keys = deque() + self.maxsize = maxsize + + def get(self, key, getter_func): + """ + Get object from the cache. + If not found, call `getter_func` to resolve it, and put that on the top + of the cache instead. + """ + # Look in cache first. + try: + return self._data[key] + except KeyError: + # Not found? Get it. + value = getter_func() + self._data[key] = value + self._keys.append(key) + + # Remove the oldest key when the size is exceeded. + if len(self._data) > self.maxsize: + key_to_remove = self._keys.popleft() + if key_to_remove in self._data: + del self._data[key_to_remove] + + return value + + def clear(self): + " Clear cache. " + self._data = {} + self._keys = deque() + + +class FastDictCache(dict): + """ + Fast, lightweight cache which keeps at most `size` items. + It will discard the oldest items in the cache first. + + The cache is a dictionary, which doesn't keep track of access counts. + It is perfect to cache little immutable objects which are not expensive to + create, but where a dictionary lookup is still much faster than an object + instantiation. + + :param get_value: Callable that's called in case of a missing key. + """ + # NOTE: This cache is used to cache `prompt_toolkit.layout.screen.Char` and + # `prompt_toolkit.Document`. Make sure to keep this really lightweight. + # Accessing the cache should stay faster than instantiating new + # objects. + # (Dictionary lookups are really fast.) + # SimpleCache is still required for cases where the cache key is not + # the same as the arguments given to the function that creates the + # value.) + def __init__(self, get_value=None, size=1000000): + assert callable(get_value) + assert isinstance(size, int) and size > 0 + + self._keys = deque() + self.get_value = get_value + self.size = size + + def __missing__(self, key): + # Remove the oldest key when the size is exceeded. + if len(self) > self.size: + key_to_remove = self._keys.popleft() + if key_to_remove in self: + del self[key_to_remove] + + result = self.get_value(*key) + self[key] = result + self._keys.append(key) + return result + + +def memoized(maxsize=1024): + """ + Momoization decorator for immutable classes and pure functions. + """ + cache = SimpleCache(maxsize=maxsize) + + def decorator(obj): + @wraps(obj) + def new_callable(*a, **kw): + def create_new(): + return obj(*a, **kw) + + key = (a, tuple(kw.items())) + return cache.get(key, create_new) + return new_callable + return decorator |