<s> """<STR_LIT>""" <EOL> from Bcfg2 . Compat import MutableMapping <EOL> class _Cache ( MutableMapping ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , registry , tags ) : <EOL> self . _registry = registry <EOL> self . _tags = tags <EOL> def __getitem__ ( self , key ) : <EOL> return self . _registry [ self . _tags | set ( [ key ] ) ] <EOL> def __setitem__ ( self , key , value ) : <EOL> self . _registry [ self . _tags | set ( [ key ] ) ] = value <EOL> def __delitem__ ( self , key ) : <EOL> del self . _registry [ self . _tags | set ( [ key ] ) ] <EOL> def __iter__ ( self ) : <EOL> for item in self . _registry . iterate ( * self . _tags ) : <EOL> yield list ( item . difference ( self . _tags ) ) [ <NUM_LIT:0> ] <EOL> def keys ( self ) : <EOL> """<STR_LIT>""" <EOL> return list ( iter ( self ) ) <EOL> def __len__ ( self ) : <EOL> return len ( list ( iter ( self ) ) ) <EOL> def expire ( self , key = None ) : <EOL> """<STR_LIT>""" <EOL> if key is None : <EOL> expire ( * self . _tags ) <EOL> else : <EOL> tags = self . _tags | set ( [ key ] ) <EOL> kwargs = dict ( exact = True ) <EOL> expire ( * tags , ** kwargs ) <EOL> def __repr__ ( self ) : <EOL> return repr ( dict ( self ) ) <EOL> def __str__ ( self ) : <EOL> return str ( dict ( self ) ) <EOL> class _CacheRegistry ( dict ) : <EOL> """<STR_LIT>""" <EOL> def iterate ( self , * tags ) : <EOL> """<STR_LIT>""" <EOL> tags = frozenset ( tags ) <EOL> for key in self . keys ( ) : <EOL> if key . issuperset ( tags ) and len ( key . difference ( tags ) ) == <NUM_LIT:1> : <EOL> yield key <EOL> def iter_all ( self , * tags ) : <EOL> """<STR_LIT>""" <EOL> tags = frozenset ( tags ) <EOL> for key in list ( self . keys ( ) ) : <EOL> if key . issuperset ( tags ) : <EOL> yield key <EOL> _cache = _CacheRegistry ( ) <EOL> _hooks = [ ] <EOL> def Cache ( * tags ) : <EOL> """<STR_LIT>""" <EOL> return _Cache ( _cache , frozenset ( tags ) ) <EOL> def expire ( * tags , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> exact = kwargs . pop ( "<STR_LIT>" , False ) <EOL> count = <NUM_LIT:0> <EOL> if not tags : <EOL> count = len ( _cache ) <EOL> _cache . clear ( ) <EOL> elif exact : <EOL> if frozenset ( tags ) in _cache : <EOL> count = <NUM_LIT:1> <EOL> del _cache [ frozenset ( tags ) ] <EOL> else : <EOL> for match in _cache . iter_all ( * tags ) : <EOL> count += <NUM_LIT:1> <EOL> del _cache [ match ] <EOL> for hook in _hooks : <EOL> hook ( tags , exact , count ) <EOL> def add_expire_hook ( func ) : <EOL> """<STR_LIT>""" <EOL> _hooks . append ( func ) </s>
