<s> """<STR_LIT>""" <EOL> from functools import wraps <EOL> from bson import json_util , datetime <EOL> import api <EOL> import time <EOL> log = api . logger . use ( __name__ ) <EOL> no_cache = False <EOL> fast_cache = { } <EOL> _mongo_index = None <EOL> def clear_all ( ) : <EOL> """<STR_LIT>""" <EOL> db = api . common . get_conn ( ) <EOL> db . cache . remove ( ) <EOL> fast_cache . clear ( ) <EOL> def get_mongo_key ( f , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> min_kwargs = dict ( filter ( lambda pair : pair [ <NUM_LIT:1> ] is not None , kwargs . items ( ) ) ) <EOL> return { <EOL> "<STR_LIT>" : "<STR_LIT>" . format ( f . __module__ , f . __name__ ) , <EOL> "<STR_LIT:args>" : args , <EOL> "<STR_LIT>" : min_kwargs , <EOL> } <EOL> def get_key ( f , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if len ( args ) > <NUM_LIT:0> : <EOL> kwargs [ "<STR_LIT>" ] = "<STR_LIT:U+002C>" . join ( map ( str , args ) ) <EOL> sorted_keys = sorted ( kwargs ) <EOL> arg_key = "<STR_LIT:&>" . join ( [ "<STR_LIT>" . format ( key , kwargs [ key ] ) for key in sorted_keys ] ) <EOL> key = "<STR_LIT>" . format ( f . __module__ , f . __name__ , arg_key ) . replace ( "<STR_LIT:U+0020>" , "<STR_LIT>" ) <EOL> return key <EOL> def get ( key , fast = False ) : <EOL> """<STR_LIT>""" <EOL> if fast : <EOL> return fast_cache . get ( key , None ) <EOL> db = api . common . get_conn ( ) <EOL> cached_result = db . cache . find_one ( key ) <EOL> if cached_result : <EOL> return cached_result [ "<STR_LIT:value>" ] <EOL> def set ( key , value , timeout = None , fast = False ) : <EOL> """<STR_LIT>""" <EOL> if fast : <EOL> fast_cache [ key ] = { <EOL> "<STR_LIT:result>" : value , <EOL> "<STR_LIT>" : timeout , <EOL> "<STR_LIT>" : time . time ( ) <EOL> } <EOL> return <EOL> db = api . common . get_conn ( ) <EOL> update = key . copy ( ) <EOL> update . update ( { "<STR_LIT:value>" : value } ) <EOL> if timeout is not None : <EOL> expireAt = datetime . datetime . now ( ) + datetime . timedelta ( seconds = timeout ) <EOL> update . update ( { "<STR_LIT>" : expireAt } ) <EOL> db . cache . update ( key , update , upsert = True ) <EOL> def timed_out ( info ) : <EOL> """<STR_LIT>""" <EOL> return int ( time . time ( ) ) - info [ '<STR_LIT>' ] > info [ '<STR_LIT>' ] <EOL> def memoize ( timeout = None , fast = False ) : <EOL> """<STR_LIT>""" <EOL> assert ( not fast or ( fast and timeout is not None ) ) , "<STR_LIT>" <EOL> def decorator ( f ) : <EOL> """<STR_LIT>""" <EOL> @ wraps ( f ) <EOL> def wrapper ( * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if not kwargs . get ( "<STR_LIT>" , True ) : <EOL> kwargs . pop ( "<STR_LIT>" , None ) <EOL> return f ( * args , ** kwargs ) <EOL> key = get_key ( f , * args , ** kwargs ) if fast else get_mongo_key ( f , * args , ** kwargs ) <EOL> cached_result = get ( key , fast = fast ) <EOL> if cached_result is None or no_cache or ( fast and timed_out ( cached_result ) ) : <EOL> function_result = f ( * args , ** kwargs ) <EOL> set ( key , function_result , timeout = timeout , fast = fast ) <EOL> return function_result <EOL> return cached_result [ '<STR_LIT:result>' ] if fast else cached_result <EOL> return wrapper <EOL> return decorator <EOL> def invalidate_memoization ( f , * keys ) : <EOL> """<STR_LIT>""" <EOL> db = api . common . get_conn ( ) <EOL> search = { "<STR_LIT>" : "<STR_LIT>" . format ( f . __module__ , f . __name__ ) } <EOL> search . update ( { "<STR_LIT>" : list ( keys ) } ) <EOL> db . cache . remove ( search ) </s>
