<s> '''<STR_LIT>''' <EOL> import threading <EOL> import time <EOL> class SimpleCache ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , timeout = <NUM_LIT> , max_entries = <NUM_LIT:200> ) : <EOL> self . storage = { } <EOL> self . expire_info = { } <EOL> self . lock = threading . RLock ( ) <EOL> self . default_timeout = timeout <EOL> self . max_entries = max_entries <EOL> self . cull_frequency = <NUM_LIT:3> <EOL> def locking ( method ) : <EOL> '''<STR_LIT>''' <EOL> def locked ( self , * args , ** kwargs ) : <EOL> self . lock . acquire ( ) <EOL> try : <EOL> return method ( self , * args , ** kwargs ) <EOL> finally : <EOL> self . lock . release ( ) <EOL> return locked <EOL> @ locking <EOL> def get ( self , key , default = None ) : <EOL> '''<STR_LIT>''' <EOL> now = time . time ( ) <EOL> exp = self . expire_info . get ( repr ( key ) ) <EOL> if exp is None : <EOL> return default <EOL> elif exp < now : <EOL> self . delete ( repr ( key ) ) <EOL> return default <EOL> return self . storage [ repr ( key ) ] <EOL> @ locking <EOL> def set ( self , key , value , timeout = None ) : <EOL> '''<STR_LIT>''' <EOL> if len ( self . storage ) >= self . max_entries : <EOL> self . cull ( ) <EOL> if timeout is None : <EOL> timeout = self . default_timeout <EOL> self . storage [ repr ( key ) ] = value <EOL> self . expire_info [ repr ( key ) ] = time . time ( ) + timeout <EOL> @ locking <EOL> def delete ( self , key ) : <EOL> '''<STR_LIT>''' <EOL> if key in self . storage : <EOL> del self . storage [ key ] <EOL> if key in self . expire_info : <EOL> del self . expire_info [ key ] <EOL> @ locking <EOL> def has ( self , key ) : <EOL> '''<STR_LIT>''' <EOL> return self . get ( repr ( key ) ) is not None <EOL> @ locking <EOL> def __contains__ ( self , key ) : <EOL> '''<STR_LIT>''' <EOL> return self . has ( repr ( key ) ) <EOL> @ locking <EOL> def cull ( self ) : <EOL> '''<STR_LIT>''' <EOL> doomed = [ k for ( i , k ) in enumerate ( self . storage ) <EOL> if i % self . cull_frequency == <NUM_LIT:0> ] <EOL> for k in doomed : <EOL> self . delete ( k ) <EOL> @ locking <EOL> def __len__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> return len ( self . storage ) </s>
