Skip to content

Instantly share code, notes, and snippets.

@mtovmassian
Last active October 17, 2022 09:55
Show Gist options
  • Save mtovmassian/9038dd0c51e103cf6f82dd25017b7632 to your computer and use it in GitHub Desktop.
Save mtovmassian/9038dd0c51e103cf6f82dd25017b7632 to your computer and use it in GitHub Desktop.
Cache store with memoizing behavior and decorator
import logging
import pickle
from datetime import datetime
from sys import getsizeof
logger = logging.getLogger(__name__)
class CacheStore:
def __init__(self, maxsize, expiration_secs):
self.maxsize = maxsize
self.expiration_secs = expiration_secs
self.cache_store = {}
def memoize(self, func, *args):
logger.info("Memoizing call to function {function_name} with arguments {arguments}".format(
function_name=func.func_name,
arguments=args
)
)
cache_key = ",".join(map(str, args))
cached_item = self.get_item(cache_key)
if cached_item and not self.is_item_expired(cached_item):
logger.info("Function result retrieved from cache.")
return cached_item["data"]
logger.info("Function result retrieved from compute.")
data = func(*args)
self.add_item(cache_key, data)
return data
def is_item_expired(self, item):
datetime_now = datetime.utcnow()
item_datetime = item["datetime"]
return (datetime_now - item_datetime).total_seconds() > self.expiration_secs
def is_oversized(self):
return getsizeof(pickle.dumps(self.cache_store)) > self.maxsize
def flush_all(self):
self.cache_store = {}
def get_item(self, key):
return self.cache_store.get(key, None)
def add_item(self, key, data):
self.__add_item(key, data)
if self.is_oversized():
logger.info("Flushing cache store since it reached its maximal size.")
self.flush_all()
self.__add_item(key, data)
def __add_item(self, key, data):
item = {
"datetime": datetime.utcnow(),
"data": data
}
self.cache_store[key] = item
def cache(maxsize=1000000, expiration_secs=60):
def decorator(func):
cache_store = CacheStore(maxsize, expiration_secs)
def wrapper(*args):
return cache_store.memoize(func, *args)
return wrapper
return decorator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment