| Index: appengine/findit/lib/cache_decorator.py
|
| diff --git a/appengine/findit/lib/cache_decorator.py b/appengine/findit/lib/cache_decorator.py
|
| deleted file mode 100644
|
| index e02b12abba57b84f99ec1ce9e6ed2ec1f3aa436f..0000000000000000000000000000000000000000
|
| --- a/appengine/findit/lib/cache_decorator.py
|
| +++ /dev/null
|
| @@ -1,136 +0,0 @@
|
| -# Copyright 2015 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -
|
| -"""This module provides a decorator to cache the results of a function.
|
| -
|
| - Examples:
|
| - 1. Decorate a function:
|
| - @cache_decorator.Cached()
|
| - def Test(a):
|
| - return a + a
|
| -
|
| - Test('a')
|
| - Test('a') # Returns the cached 'aa'.
|
| -
|
| - 2. Decorate a method in a class:
|
| - class Downloader(object):
|
| - def __init__(self, url, retries):
|
| - self.url = url
|
| - self.retries = retries
|
| -
|
| - @property
|
| - def identifier(self):
|
| - return self.url
|
| -
|
| - @cache_decorator.Cached():
|
| - def Download(self, path):
|
| - return urllib2.urlopen(self.url + '/' + path).read()
|
| -
|
| - d1 = Downloader('http://url', 4)
|
| - d1.Download('path')
|
| -
|
| - d2 = Downloader('http://url', 5)
|
| - d2.Download('path') # Returned the cached downloaded data.
|
| -"""
|
| -
|
| -import functools
|
| -import hashlib
|
| -import inspect
|
| -import logging
|
| -import pickle
|
| -
|
| -
|
| -def _DefaultKeyGenerator(func, args, kwargs):
|
| - """Generates a key from the function and arguments passed to it.
|
| -
|
| - Args:
|
| - func (function): An arbitrary function.
|
| - args (list): Positional arguments passed to ``func``.
|
| - kwargs (dict): Keyword arguments passed to ``func``.
|
| -
|
| - Returns:
|
| - A string to represent a call to the given function with the given arguments.
|
| - """
|
| - params = inspect.getcallargs(func, *args, **kwargs)
|
| - for var_name in params:
|
| - if not hasattr(params[var_name], 'identifier'):
|
| - continue
|
| -
|
| - if callable(params[var_name].identifier):
|
| - params[var_name] = params[var_name].identifier()
|
| - else:
|
| - params[var_name] = params[var_name].identifier
|
| -
|
| - return hashlib.md5(pickle.dumps(params)).hexdigest()
|
| -
|
| -
|
| -def Cached(namespace=None,
|
| - expire_time=0,
|
| - key_generator=_DefaultKeyGenerator,
|
| - cache=None):
|
| - """Returns a decorator to cache the decorated function's results.
|
| -
|
| - However, if the function returns None, empty list/dict, empty string, or other
|
| - value that is evaluated as False, the results won't be cached.
|
| -
|
| - This decorator is to cache results of different calls to the decorated
|
| - function, and avoid executing it again if the calls are equivalent. Two calls
|
| - are equivalent, if the namespace is the same and the keys generated by the
|
| - ``key_generator`` are the same.
|
| -
|
| - The usage of this decorator requires that:
|
| - - If the default key generator is used, parameters passed to the decorated
|
| - function should be pickleable, or each of the parameter has an identifier
|
| - property or method which returns pickleable results.
|
| - - If the default cache is used, the returned results of the decorated
|
| - function should be pickleable.
|
| -
|
| - Args:
|
| - namespace (str): A prefix to the key for the cache. Default to the
|
| - combination of module name and function name of the decorated function.
|
| - expire_time (int): Expiration time, relative number of seconds from current
|
| - time (up to 0 month). Defaults to 0 -- never expire.
|
| - key_generator (function): A function to generate a key to represent a call
|
| - to the decorated function. Defaults to :func:`_DefaultKeyGenerator`.
|
| - cache (Cache): An instance of an implementation of interface `Cache`.
|
| - Defaults to None.
|
| -
|
| - Returns:
|
| - The cached results or the results of a new run of the decorated function.
|
| - """
|
| - def GetPrefix(func, namespace):
|
| - return namespace or '%s.%s' % (func.__module__, func.__name__)
|
| -
|
| - def Decorator(func):
|
| - """Decorator to cache a function's results."""
|
| - @functools.wraps(func)
|
| - def Wrapped(*args, **kwargs):
|
| - prefix = GetPrefix(func, namespace)
|
| - key = '%s-%s' % (prefix, key_generator(func, args, kwargs))
|
| -
|
| - try:
|
| - result = cache.Get(key)
|
| - except Exception: # pragma: no cover.
|
| - result = None
|
| - logging.exception(
|
| - 'Failed to get cached data for function %s.%s, args=%s, kwargs=%s',
|
| - func.__module__, func.__name__, repr(args), repr(kwargs))
|
| -
|
| - if result is not None:
|
| - return result
|
| -
|
| - result = func(*args, **kwargs)
|
| - if result:
|
| - try:
|
| - cache.Set(key, result, expire_time=expire_time)
|
| - except Exception: # pragma: no cover.
|
| - logging.exception(
|
| - 'Failed to cache data for function %s.%s, args=%s, kwargs=%s',
|
| - func.__module__, func.__name__, repr(args), repr(kwargs))
|
| -
|
| - return result
|
| -
|
| - return Wrapped
|
| -
|
| - return Decorator
|
|
|