<s> from synapse . util . async import ObservableDeferred <EOL> class SnapshotCache ( object ) : <EOL> """<STR_LIT>""" <EOL> DURATION_MS = <NUM_LIT:5> * <NUM_LIT> * <NUM_LIT:1000> <EOL> def __init__ ( self ) : <EOL> self . pending_result_cache = { } <EOL> self . prev_result_cache = { } <EOL> self . next_result_cache = { } <EOL> self . time_last_rotated_ms = <NUM_LIT:0> <EOL> def rotate ( self , time_now_ms ) : <EOL> if time_now_ms - self . time_last_rotated_ms >= self . DURATION_MS : <EOL> self . prev_result_cache = self . next_result_cache <EOL> self . next_result_cache = { } <EOL> self . time_last_rotated_ms += self . DURATION_MS <EOL> if time_now_ms - self . time_last_rotated_ms >= self . DURATION_MS : <EOL> self . prev_result_cache = self . next_result_cache <EOL> self . next_result_cache = { } <EOL> self . time_last_rotated_ms = time_now_ms <EOL> def get ( self , time_now_ms , key ) : <EOL> self . rotate ( time_now_ms ) <EOL> result = self . prev_result_cache . get ( key ) <EOL> result = self . next_result_cache . get ( key , result ) <EOL> result = self . pending_result_cache . get ( key , result ) <EOL> if result is not None : <EOL> return result . observe ( ) <EOL> else : <EOL> return None <EOL> def set ( self , time_now_ms , key , deferred ) : <EOL> self . rotate ( time_now_ms ) <EOL> result = ObservableDeferred ( deferred ) <EOL> self . pending_result_cache [ key ] = result <EOL> def shuffle_along ( r ) : <EOL> self . next_result_cache [ key ] = result <EOL> self . pending_result_cache . pop ( key , None ) <EOL> return r <EOL> result . addBoth ( shuffle_along ) <EOL> return result . observe ( ) </s>
