Source code for jammy.utils.cache
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# File : cache.py
# Author : Jiayuan Mao
# Email : maojiayuan@gmail.com
# Date : 01/19/2018
#
# Qinsheng Zhang modified based on Jacinle.
# Distributed under terms of the MIT license.
import collections
import functools
import os.path as osp
import threading
from jammy.logging import get_logger
from .meta import synchronized
logger = get_logger()
__all__ = ["cached_property", "cached_result", "fs_cached_result"]
[docs]class cached_property: # pylint: disable=too-few-public-methods, invalid-name
def __init__(self, fget):
self.fget = fget
self.__module__ = fget.__module__
self.__name__ = fget.__name__
self.__doc__ = fget.__doc__
self.__cache_key = "__result_cache_{}_{}".format(fget.__name__, id(fget))
self.__mutex = collections.defaultdict(threading.Lock)
def __get__(self, instance, owner):
with self.__mutex[id(instance)]:
if instance is None:
return self.fget
v = getattr(instance, self.__cache_key, None)
if v is not None:
return v
v = self.fget(instance)
assert v is not None
setattr(instance, self.__cache_key, v)
return v
[docs]def cached_result(func):
def impl():
nonlocal impl
ret = func()
impl = lambda: ret
return ret
@synchronized()
@functools.wraps(func)
def f():
return impl()
return f
[docs]def fs_cached_result(filename, force_update=False, verbose=False):
import jammy.io as io
def wrapper(func):
@synchronized()
@functools.wraps(func)
def wrapped_func(*args, **kwargs):
if not force_update and osp.exists(filename):
if verbose:
logger.info('Using cached results from "{}".'.format(filename))
cached_value = io.load(filename)
if cached_value is not None:
return cached_value
computed_value = func(*args, **kwargs)
if verbose:
logger.info('Writing result cache to "{}".'.format(filename))
io.dump(filename, computed_value)
return computed_value
return wrapped_func
return wrapper