Rework memoize class

- Removed *args: segments are not receiveing any non-keyword arguments so no
  need to bother with *args at all.
- Replaced additional_cache_key with cache_key: all functions that formerly used
  additional_cache_key appear not to need initial arguments as cache keys. It
  also simplifies the code.
- Made _cache be defined in __init__, it is much easier to implement cache
  purging this way.

Ref #205
Fixes #208
This commit is contained in:
ZyX 2013-02-12 23:59:45 +04:00 committed by Kim Silkebækken
parent 5202807269
commit 0fddb24b9b
3 changed files with 20 additions and 20 deletions

View File

@ -4,28 +4,28 @@ from functools import wraps
import time
def default_cache_key(**kwargs):
return frozenset(kwargs.items())
class memoize(object):
'''Memoization decorator with timeout.'''
_cache = {}
def __init__(self, timeout, additional_key=None):
def __init__(self, timeout, cache_key=default_cache_key):
self.timeout = timeout
self.additional_key = additional_key
self.cache_key = cache_key
self._cache = {}
def __call__(self, func):
@wraps(func)
def decorated_function(*args, **kwargs):
if self.additional_key:
key = (func.__name__, args, self.additional_key(*args, **kwargs))
else:
key = (func.__name__, args)
def decorated_function(**kwargs):
key = self.cache_key(**kwargs)
try:
cached = self._cache.get(key, None)
except TypeError:
return func(*args, **kwargs)
return func(**kwargs)
if cached is None or time.time() - cached['time'] > self.timeout:
cached = self._cache[key] = {
'result': func(*args, **kwargs),
'result': func(**kwargs),
'time': time.time(),
}
return cached['result']

View File

@ -34,7 +34,7 @@ def user():
def branch():
'''Return the current VCS branch.'''
from powerline.lib.vcs import guess
repo = guess(os.path.abspath(os.getcwd()))
repo = guess(path=os.path.abspath(os.getcwd()))
if repo:
return repo.branch()
return None

View File

@ -47,7 +47,7 @@ mode_translations = {
}
def bufnr(segment_info, *args, **kwargs):
def bufnr(segment_info, **kwargs):
'''Used for cache key, returns current buffer number'''
return segment_info['bufnr']
@ -157,7 +157,7 @@ def file_name(segment_info, display_no_file=False, no_file_text='[No file]'):
@requires_segment_info
@memoize(2, additional_key=bufnr)
@memoize(2, cache_key=bufnr)
def file_size(segment_info, suffix='B', binary_prefix=False):
'''Return file size.
@ -254,10 +254,10 @@ def modified_buffers(text=u'+', join_str=','):
@requires_segment_info
@memoize(2)
@memoize(2, cache_key=bufnr)
def branch(segment_info):
'''Return the current working branch.'''
repo = guess(os.path.abspath(segment_info['buffer'].name or os.getcwd()))
repo = guess(path=os.path.abspath(segment_info['buffer'].name or os.getcwd()))
if repo:
return repo.branch()
return None
@ -265,12 +265,12 @@ def branch(segment_info):
# TODO Drop cache on BufWrite event
@requires_segment_info
@memoize(2, additional_key=bufnr)
@memoize(2, cache_key=bufnr)
def file_vcs_status(segment_info):
'''Return the VCS status for this buffer.'''
name = segment_info['buffer'].name
if name and not getbufvar(segment_info['bufnr'], '&buftype'):
repo = guess(os.path.abspath(name))
repo = guess(path=os.path.abspath(name))
if repo:
status = repo.status(os.path.relpath(name, repo.directory))
if not status:
@ -288,10 +288,10 @@ def file_vcs_status(segment_info):
@requires_segment_info
@memoize(2)
@memoize(2, cache_key=bufnr)
def repository_status(segment_info):
'''Return the status for the current repo.'''
repo = guess(os.path.abspath(segment_info['buffer'].name or os.getcwd()))
repo = guess(path=os.path.abspath(segment_info['buffer'].name or os.getcwd()))
if repo:
return repo.status()
return None