def lru_cache(maxsize=<NUM_LIT:100>, typed=False, mode=None, cache=None):
<EOL>def decorating_function(user_function):<EOL><INDENT>lock = RLock()    <EOL>_cache = cache<EOL>_maxsize = maxsize<EOL>if _cache is None:<EOL><INDENT>_cache = dict()<EOL><DEDENT>elif mode is not None:<EOL><INDENT>_maxsize = None<EOL><DEDENT>stats = [<NUM_LIT:0>, <NUM_LIT:0>]    <EOL>HITS, MISSES = <NUM_LIT:0>, <NUM_LIT:1>    <EOL>make_key = _make_key<EOL>cache_get = _cache.get    <EOL>_len = len    <EOL>root = []    <EOL>root[:] = [root, root, None, None]    <EOL>nonlocal_root = [root]    <EOL>PREV, NEXT, KEY, RESULT = <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>    <EOL>if _maxsize == <NUM_LIT:0>:<EOL><INDENT>def wrapper(*args, **kwds):<EOL><INDENT>result = user_function(*args, **kwds)<EOL>stats[MISSES] += <NUM_LIT:1><EOL>return result<EOL><DEDENT><DEDENT>elif _maxsize is None:<EOL><INDENT>def wrapper(*args, **kwds):<EOL><INDENT>key = make_key(user_function.__name__, args, kwds, typed, ())<EOL>result = cache_get(key, root)    <EOL>if result is not root:<EOL><INDENT>stats[HITS] += <NUM_LIT:1><EOL>if mode == VERIFY:<EOL><INDENT>latestres = user_function(*args, **kwds)<EOL>if latestres != result:<EOL><INDENT>raise HGVSVerifyFailedError(<EOL>'<STR_LIT>'<EOL>+ user_function.__name__ + '<STR_LIT>' + str(args) +<EOL>'<STR_LIT>' + str(kwds))<EOL><DEDENT><DEDENT>return result<EOL><DEDENT>if mode == RUN:<EOL><INDENT>raise HGVSDataNotAvailableError(<EOL>'<STR_LIT>' + user_function.__name__ +<EOL>'<STR_LIT>' + str(args) + '<STR_LIT>' + str(kwds))<EOL><DEDENT>result = user_function(*args, **kwds)<EOL>_cache[key] = result<EOL>if mode == LEARN:<EOL><INDENT>_cache.sync()<EOL><DEDENT>stats[MISSES] += <NUM_LIT:1><EOL>return result<EOL><DEDENT><DEDENT>else:<EOL><INDENT>def wrapper(*args, **kwds):<EOL><INDENT>key = make_key(user_function.__name__, args, kwds, typed, ())<EOL>with lock:<EOL><INDENT>link = cache_get(key)<EOL>if link is not None:<EOL><INDENT>root, = nonlocal_root<EOL>link_prev, link_next, key, result = link<EOL>link_prev[NEXT] = link_next<EOL>link_next[PREV] = link_prev<EOL>last = root[PREV]<EOL>last[NEXT] = root[PREV] = link<EOL>link[PREV] = last<EOL>link[NEXT] = root<EOL>stats[HITS] += <NUM_LIT:1><EOL>return result<EOL><DEDENT><DEDENT>result = user_function(*args, **kwds)<EOL>with lock:<EOL><INDENT>root, = nonlocal_root<EOL>if key in _cache:<EOL><INDENT>pass<EOL><DEDENT>elif _len(_cache) >= _maxsize:<EOL><INDENT>oldroot = root<EOL>oldroot[KEY] = key<EOL>oldroot[RESULT] = result<EOL>root = nonlocal_root[<NUM_LIT:0>] = oldroot[NEXT]<EOL>oldkey = root[KEY]<EOL>root[KEY] = root[RESULT] = None<EOL>del _cache[oldkey]<EOL>_cache[key] = oldroot<EOL><DEDENT>else:<EOL><INDENT>last = root[PREV]<EOL>link = [last, root, key, result]<EOL>last[NEXT] = root[PREV] = _cache[key] = link<EOL><DEDENT>stats[MISSES] += <NUM_LIT:1><EOL><DEDENT>return result<EOL><DEDENT><DEDENT>def cache_info():<EOL><INDENT>"""<STR_LIT>"""<EOL>with lock:<EOL><INDENT>return _CacheInfo(stats[HITS], stats[MISSES], _maxsize, len(_cache))<EOL><DEDENT><DEDENT>def cache_clear():<EOL><INDENT>"""<STR_LIT>"""<EOL>with lock:<EOL><INDENT>_cache.clear()<EOL>root = nonlocal_root[<NUM_LIT:0>]<EOL>root[:] = [root, root, None, None]<EOL>stats[:] = [<NUM_LIT:0>, <NUM_LIT:0>]<EOL><DEDENT><DEDENT>wrapper.__wrapped__ = user_function<EOL>wrapper.cache_info = cache_info<EOL>wrapper.cache_clear = cache_clear<EOL>return update_wrapper(wrapper, user_function)<EOL><DEDENT>return decorating_function<EOL>
Least-recently-used cache decorator.

    If *maxsize* is set to None, the LRU features are disabled and the cache
    can grow without bound.

    If *typed* is True, arguments of different types will be cached separately.
    For example, f(3.0) and f(3) will be treated as distinct calls with
    distinct results.

    Arguments to the cached function must be hashable.

    View the cache statistics named tuple (hits, misses, maxsize, currsize) with
    f.cache_info().  Clear the cache and statistics with f.cache_clear().
    Access the underlying function with f.__wrapped__.

    See:  http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used


    :param mode: cache run mode
        None:   the default lru cache behaver
        LEARN:  queries are executed against persistent cache from file "filename";
                in the event of a miss, the novel query and results would be written to cache, then returned.
        RUN:    queries are executed against caches; misses result in DataNotLocallyAvailableError
        VERIFY: always execute the function; if persistent cache value and returned value are different, raise VerifyFailedError
    :param cache: PersistentDict object or None;