Skip to content

Instantly share code, notes, and snippets.

@whiteclover
Last active August 29, 2015 13:57
Show Gist options
  • Save whiteclover/9621829 to your computer and use it in GitHub Desktop.
Save whiteclover/9621829 to your computer and use it in GitHub Desktop.
a cache for method
#!/usr/bin/python
import functools
from threading import RLock
import logging
class CacheNullValue(object):
pass
_Null = CacheNullValue()
class Cache(object):
def __init__(self, cache_limit=1000):
self._cache = {}
self._queue = []
self.cache_limit = cache_limit
self._lock = RLock()
def __getitem__(self, name):
with self._lock:
return self._cache.get(name, _Null)
get = __getitem__
def __setitem__(self, name, value):
with self._lock:
if len(self._queue) >= self.cache_limit:
del self._cache[self._queue.pop()]
self._queue.append(name)
self._cache[name] = value
set = __setitem__
def cache(cache_limit):
"""A function decorator for method cache store
"""
def cached(f):
@functools.wraps(f)
def _cached(*args, **kwargs):
cid = repr((args, kwargs))
data = _cached.cache.get(cid)
if data != _Null:
logging.debug('hit cached `' + _cached.__name__ + '` for ' + cid)
return data
data = _cached.f(*args, **kwargs)
_cached.cache.set(cid, data)
return data
_cached.f = f
_cached.cache = Cache(cache_limit)
return _cached
return cached
def setup(cache_limit):
""" A global thread safe key-value store
"""
global _cache_object
_cache_object = Cache(cache_limit)
def set(cid, data):
_cache_object.set(cid, data)
def get(cid):
return _cache_object.get(cid)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(levelname)-8s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S', filemode='a+')
class T(object):
@cache(100)
def c(self, t):
return t
@cache(100)
def cc(t):
return t
t = T()
print t.c('hello')
print t.c('hello')
print t.c('h')
print t.c('hello')
print cc('he')
print cc('he')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment