Memoize objects to trade memory for execution speed

    Use a limited size cache to store the value, which takes into account
    The calling args and kwargs

    See https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
180218
def memoize(obj):
    
    cache = obj.cache = {}

    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        key = str(args) + str(kwargs)
        if key not in cache:
            cache[key] = obj(*args, **kwargs)
        # only keep the most recent 100 entries
        if len(cache) > 100:
            cache.popitem(last=False)
        return cache[key]
    return memoizer
632377
def memoized_ignoreargs(func):
    
    def wrapper(*args, **kwargs):
        if func not in _MEMOIZED_NOARGS:
            res = func(*args, **kwargs)
            _MEMOIZED_NOARGS[func] = res
            return res
        return _MEMOIZED_NOARGS[func]
    return wrapper
294020
def memoize_nullary(f):
    
    def func():
        if not hasattr(func, 'retval'):
            func.retval = f()
        return func.retval
    return func
493859
def memoize(f):
    
    cache = {}

    @wraps(f)
    def inner(arg):
        if arg not in cache:
            cache[arg] = f(arg)
        return cache[arg]
    return inner
1105850
def _memoize(self, name, getter, *args, **kwargs):
        
        field = "custom_m_" + name
        cached = self.fetch(field)
        if cached:
            value = cached
        else:
            value = getter(*args, **kwargs)
            self._make_it_so("caching %s=%r for" % (name, value,), ["custom.set"], field[7:], value)
            self._fields[field] = value
        return value
831316
def memoize(fn):
    
    cache = {}

    @wraps(fn)
    def wrapped_fn(*args, **kwargs):
        cache_key = _memoize_cache_key(args, kwargs)
        try:
            return cache[cache_key]
        except KeyError:
            value = fn(*args, **kwargs)
            cache[cache_key] = value
            return value

    def clear_cache():
        cache.clear()

    # Needed to ensure that EnsemblRelease.clear_cache
    # is able to clear memoized values from each of its methods
    wrapped_fn.clear_cache = clear_cache
    # expose the cache so we can check if an item has already been computed
    wrapped_fn.cache = cache
    # if we want to check whether an item is in the cache, first need
    # to construct the same cache key as used by wrapped_fn
    wrapped_fn.make_cache_key = _memoize_cache_key
    return wrapped_fn
1368103
def memorize(func):
    
    @wraps(func)
    def wrapped_func(*args, **kwargs):
        if (len(args) > 0 and len(kwargs) > 0): 
            cacheKey = list(args)
            cacheKey.append(kwargs)
        elif (len(args) > 0): 
            cacheKey = args
        else:
            cacheKey = func.__name__
            
        global __cache__
        result = __cache__.get(cacheKey)
        if result is None:
            result = func(*args, **kwargs)
            __cache__[cacheKey] = result
        return result

    return wrapped_func
452237
def cache_key(*args, **kwargs):
    
    key = ""
    for arg in args:
        if callable(arg):
            key += ":%s" % repr(arg)
        else:
            key += ":%s" % str(arg)

    return key
1263190
def memoize_methodcalls(func, pickle=False, dumps=pickle.dumps):
    '''
    '''
    cache = func._memoize_cache = {}
    @functools.wraps(func)
    def memoizer(self, *args, **kwargs):
        if pickle:
            key = dumps((args, kwargs))
        else:
            key = args
        if key not in cache:
            cache[key] = func(self, *args, **kwargs)
        return cache[key]
    return memoizer
389137
def memoize_single_argument(f):
    
    class memodict(dict):

        def __missing__(self, key):
            ret = self[key] = f(key)
            return ret
    return memodict().__getitem__
1102841
def memoize(fun):
    
    argspec = inspect2.getfullargspec(fun)
    arg_names = argspec.args + argspec.kwonlyargs
    kwargs_defaults = get_kwargs_defaults(argspec)

    def cache_key(args, kwargs):
        return get_args_tuple(args, kwargs, arg_names, kwargs_defaults)

    @functools.wraps(fun)
    def new_fun(*args, **kwargs):
        k = cache_key(args, kwargs)
        if k not in new_fun.__cache:
            new_fun.__cache[k] = fun(*args, **kwargs)
        return new_fun.__cache[k]

    def clear_cache():
        """Removes all cached values for this function."""
        new_fun.__cache.clear()

    new_fun.__cache = {}
    new_fun.clear_cache = clear_cache
    return new_fun
219981
def memoize(function):
    
    cache = {}
    @functools.wraps(function)
    def _memoize(*args):
        if args in cache:
            return cache[args]
        result = function(*args)
        cache[args] = result
        return result
    return function
322603
def _weak_lru_cache(maxsize=100):
    
    def decorating_function(
            user_function, tuple=tuple, sorted=sorted, len=len,
            KeyError=KeyError):

        hits, misses = [0], [0]
        kwd_mark = (object(),)    # separates positional and keyword args
        lock = Lock()             # needed because OrderedDict isn't threadsafe

        if maxsize is None:
            cache = _WeakArgsDict()  # cache without ordering or size limit

            @wraps(user_function)
            def wrapper(*args, **kwds):
                key = args
                if kwds:
                    key += kwd_mark + tuple(sorted(kwds.items()))
                try:
                    result = cache[key]
                    hits[0] += 1
                    return result
                except KeyError:
                    pass
                result = user_function(*args, **kwds)
                cache[key] = result
                misses[0] += 1
                return result
        else:
            # ordered least recent to most recent
            cache = _WeakArgsOrderedDict()
            cache_popitem = cache.popitem
            cache_renew = cache.move_to_end

            @wraps(user_function)
            def wrapper(*args, **kwds):
                key = args
                if kwds:
                    key += kwd_mark + tuple(sorted(kwds.items()))
                with lock:
                    try:
                        result = cache[key]
                        cache_renew(key)    # record recent use of this key
                        hits[0] += 1
                        return result
                    except KeyError:
                        pass
                result = user_function(*args, **kwds)
                with lock:
                    cache[key] = result     # record recent use of this key
                    misses[0] += 1
                    if len(cache) > maxsize:
                        # purge least recently used cache entry
                        cache_popitem(False)
                return result

        def cache_info():
            """Report cache statistics"""
            with lock:
                return hits[0], misses[0], maxsize, len(cache)

        def cache_clear():
            """Clear the cache and cache statistics"""
            with lock:
                cache.clear()
                hits[0] = misses[0] = 0

        wrapper.cache_info = cache_info
        wrapper.cache_clear = cache_clear
        return wrapper

    return decorating_function
987853
function memoize(value, objectKey) {
            const oldValue = memoized[memoizedIndex];
            if (oldValue !== undefined) {
                memoizedMap.delete(oldValue);
                memoizedObjectMap.delete(oldValue);
            }
            
            if (objectKey)
                memoizedObjectMap.set(objectKey, memoizedIndex);
            else
                memoizedMap.set(value, memoizedIndex);
            memoized[memoizedIndex] = value;
            
            memoizedIndex++;
            if (memoizedIndex >= maxDictSize + MIN_DICT_INDEX)
                memoizedIndex = MIN_DICT_INDEX;
        }
784518
def memoize_by_args(func):
    """"""
    memory = {}

    @functools.wraps(func)
    def memoized(*args):
        if args not in memory.keys():
            value = func(*args)
            memory[args] = value

        return memory[args]

    return memoized
815303
def method_cache(by='value',method='run'):
    """"""

    def decorate_(func):
        def decorate(*args, **kwargs):
            model = args[0] # Assumed to be self.
            assert hasattr(model,method), "Model must have a '%s' method."%method
            if func.__name__ == method: # Run itself.
                method_args = kwargs
            else: # Any other method.
                method_args = kwargs[method] if method in kwargs else {}
            if not hasattr(model.__class__,'cached_runs'): # If there is no run cache.
                model.__class__.cached_runs = {} # Create the method cache.
            cache = model.__class__.cached_runs
            if by == 'value':
                model_dict = {key:value for key,value in list(model.__dict__.items()) \
                              if key[0]!='_'}
                method_signature = SciUnit.dict_hash({'attrs':model_dict,'args':method_args}) # Hash key.
            elif by == 'instance':
                method_signature = SciUnit.dict_hash({'id':id(model),'args':method_args}) # Hash key.
            else:
                raise ValueError("Cache type must be 'value' or 'instance'")
            if method_signature not in cache:
                print("Method with this signature not found in the cache. Running...")
                f = getattr(model,method)
                f(**method_args)
                cache[method_signature] = (datetime.now(),model.__dict__.copy())
            else:
                print("Method with this signature found in the cache. Restoring...")
                _,attrs = cache[method_signature]
                model.__dict__.update(attrs)
            return func(*args, **kwargs)
        return decorate
    return decorate_
770257
function memoize(key, val) {
  if (cache.hasOwnProperty(key)) {
    return cache[key];
  }
  return (cache[key] = val);
}