<s> """<STR_LIT>""" <EOL> __all__ = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> import itertools <EOL> import string <EOL> from google . appengine . api import datastore <EOL> from google . appengine . ext import db <EOL> from google . appengine . ext . db import metadata <EOL> NAMESPACE_CHARACTERS = '<STR_LIT>' . join ( sorted ( string . digits + <EOL> string . lowercase + <EOL> string . uppercase + <EOL> '<STR_LIT>' ) ) <EOL> MAX_NAMESPACE_LENGTH = <NUM_LIT:100> <EOL> MIN_NAMESPACE = '<STR_LIT>' <EOL> def _setup_constants ( alphabet = NAMESPACE_CHARACTERS , <EOL> max_length = MAX_NAMESPACE_LENGTH ) : <EOL> """<STR_LIT>""" <EOL> global NAMESPACE_CHARACTERS <EOL> global MAX_NAMESPACE_LENGTH <EOL> global MAX_NAMESPACE <EOL> global _LEX_DISTANCE <EOL> NAMESPACE_CHARACTERS = alphabet <EOL> MAX_NAMESPACE_LENGTH = max_length <EOL> MAX_NAMESPACE = NAMESPACE_CHARACTERS [ - <NUM_LIT:1> ] * MAX_NAMESPACE_LENGTH <EOL> _LEX_DISTANCE = [ <NUM_LIT:1> ] <EOL> for i in range ( <NUM_LIT:1> , MAX_NAMESPACE_LENGTH ) : <EOL> _LEX_DISTANCE . append ( <EOL> _LEX_DISTANCE [ i - <NUM_LIT:1> ] * len ( NAMESPACE_CHARACTERS ) + <NUM_LIT:1> ) <EOL> del i <EOL> _setup_constants ( ) <EOL> def _ord_to_namespace ( n , _max_length = None ) : <EOL> """<STR_LIT>""" <EOL> if _max_length is None : <EOL> _max_length = MAX_NAMESPACE_LENGTH <EOL> length = _LEX_DISTANCE [ _max_length - <NUM_LIT:1> ] <EOL> if n == <NUM_LIT:0> : <EOL> return '<STR_LIT>' <EOL> n -= <NUM_LIT:1> <EOL> return ( NAMESPACE_CHARACTERS [ n / length ] + <EOL> _ord_to_namespace ( n % length , _max_length - <NUM_LIT:1> ) ) <EOL> def _namespace_to_ord ( namespace ) : <EOL> """<STR_LIT>""" <EOL> n = <NUM_LIT:0> <EOL> for i , c in enumerate ( namespace ) : <EOL> n += ( _LEX_DISTANCE [ MAX_NAMESPACE_LENGTH - i - <NUM_LIT:1> ] * <EOL> NAMESPACE_CHARACTERS . index ( c ) <EOL> + <NUM_LIT:1> ) <EOL> return n <EOL> def _key_for_namespace ( namespace , app ) : <EOL> """<STR_LIT>""" <EOL> if namespace : <EOL> return db . Key . from_path ( metadata . Namespace . KIND_NAME , <EOL> namespace , <EOL> _app = app ) <EOL> else : <EOL> return db . Key . from_path ( metadata . Namespace . KIND_NAME , <EOL> metadata . Namespace . EMPTY_NAMESPACE_ID , <EOL> _app = app ) <EOL> class NamespaceRange ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , <EOL> namespace_start = None , <EOL> namespace_end = None , <EOL> _app = None ) : <EOL> """<STR_LIT>""" <EOL> if namespace_start is None : <EOL> namespace_start = MIN_NAMESPACE <EOL> if namespace_end is None : <EOL> namespace_end = MAX_NAMESPACE <EOL> if namespace_start > namespace_end : <EOL> raise ValueError ( '<STR_LIT>' % ( <EOL> namespace_start , namespace_end ) ) <EOL> self . __namespace_start = namespace_start <EOL> self . __namespace_end = namespace_end <EOL> self . __app = _app <EOL> @ property <EOL> def app ( self ) : <EOL> return self . __app <EOL> @ property <EOL> def namespace_start ( self ) : <EOL> return self . __namespace_start <EOL> @ property <EOL> def namespace_end ( self ) : <EOL> return self . __namespace_end <EOL> @ property <EOL> def is_single_namespace ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . namespace_start == self . namespace_end <EOL> def split_range ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . is_single_namespace : <EOL> return [ self ] <EOL> mid_point = ( _namespace_to_ord ( self . namespace_start ) + <EOL> _namespace_to_ord ( self . namespace_end ) ) // <NUM_LIT:2> <EOL> return [ NamespaceRange ( self . namespace_start , <EOL> _ord_to_namespace ( mid_point ) , <EOL> _app = self . app ) , <EOL> NamespaceRange ( _ord_to_namespace ( mid_point + <NUM_LIT:1> ) , <EOL> self . namespace_end , <EOL> _app = self . app ) ] <EOL> def __copy__ ( self ) : <EOL> return self . __class__ ( self . __namespace_start , <EOL> self . __namespace_end , <EOL> self . __app ) <EOL> def __eq__ ( self , o ) : <EOL> return ( self . namespace_start == o . namespace_start and <EOL> self . namespace_end == o . namespace_end ) <EOL> def __hash__ ( self ) : <EOL> return hash ( ( self . namespace_start , self . namespace_end , self . app ) ) <EOL> def __repr__ ( self ) : <EOL> if self . app is None : <EOL> return '<STR_LIT>' % ( <EOL> self . namespace_start , self . namespace_end ) <EOL> else : <EOL> return '<STR_LIT>' % ( <EOL> self . namespace_start , self . namespace_end , self . app ) <EOL> def with_start_after ( self , after_namespace ) : <EOL> """<STR_LIT>""" <EOL> namespace_start = _ord_to_namespace ( _namespace_to_ord ( after_namespace ) + <NUM_LIT:1> ) <EOL> return NamespaceRange ( namespace_start , self . namespace_end , _app = self . app ) <EOL> def make_datastore_query ( self ) : <EOL> """<STR_LIT>""" <EOL> filters = { } <EOL> filters [ '<STR_LIT>' ] = _key_for_namespace ( <EOL> self . namespace_start , self . app ) <EOL> filters [ '<STR_LIT>' ] = _key_for_namespace ( <EOL> self . namespace_end , self . app ) <EOL> return datastore . Query ( '<STR_LIT>' , <EOL> filters = filters , <EOL> keys_only = True , <EOL> _app = self . app ) <EOL> def normalized_start ( self ) : <EOL> """<STR_LIT>""" <EOL> namespaces_after_key = self . make_datastore_query ( ) . Get ( <NUM_LIT:1> ) <EOL> if not namespaces_after_key : <EOL> return None <EOL> namespace_after_key = namespaces_after_key [ <NUM_LIT:0> ] . name ( ) or '<STR_LIT>' <EOL> return NamespaceRange ( namespace_after_key , <EOL> self . namespace_end , <EOL> _app = self . app ) <EOL> def to_json_object ( self ) : <EOL> """<STR_LIT>""" <EOL> obj_dict = dict ( namespace_start = self . namespace_start , <EOL> namespace_end = self . namespace_end ) <EOL> if self . app is not None : <EOL> obj_dict [ '<STR_LIT>' ] = self . app <EOL> return obj_dict <EOL> @ classmethod <EOL> def from_json_object ( cls , json ) : <EOL> """<STR_LIT>""" <EOL> return cls ( json [ '<STR_LIT>' ] , <EOL> json [ '<STR_LIT>' ] , <EOL> _app = json . get ( '<STR_LIT>' ) ) <EOL> @ classmethod <EOL> def split ( cls , <EOL> n , <EOL> contiguous , <EOL> can_query = itertools . chain ( itertools . repeat ( True , <NUM_LIT:50> ) , <EOL> itertools . repeat ( False ) ) . next , <EOL> _app = None ) : <EOL> """<STR_LIT>""" <EOL> if n < <NUM_LIT:1> : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> ns_range = NamespaceRange ( _app = _app ) <EOL> if can_query ( ) : <EOL> ns_range = ns_range . normalized_start ( ) <EOL> if ns_range is None : <EOL> if contiguous : <EOL> return [ NamespaceRange ( _app = _app ) ] <EOL> else : <EOL> return [ ] <EOL> ranges = [ ns_range ] <EOL> singles = [ ] <EOL> while ranges and ( len ( ranges ) + len ( singles ) ) < n : <EOL> namespace_range = ranges . pop ( <NUM_LIT:0> ) <EOL> if namespace_range . is_single_namespace : <EOL> singles . append ( namespace_range ) <EOL> else : <EOL> left , right = namespace_range . split_range ( ) <EOL> if can_query ( ) : <EOL> right = right . normalized_start ( ) <EOL> if right is not None : <EOL> ranges . append ( right ) <EOL> ranges . append ( left ) <EOL> ns_ranges = sorted ( singles + ranges , <EOL> key = lambda ns_range : ns_range . namespace_start ) <EOL> if contiguous : <EOL> if not ns_ranges : <EOL> return [ NamespaceRange ( _app = _app ) ] <EOL> continuous_ns_ranges = [ ] <EOL> for i in range ( len ( ns_ranges ) ) : <EOL> if i == <NUM_LIT:0> : <EOL> namespace_start = MIN_NAMESPACE <EOL> else : <EOL> namespace_start = ns_ranges [ i ] . namespace_start <EOL> if i == len ( ns_ranges ) - <NUM_LIT:1> : <EOL> namespace_end = MAX_NAMESPACE <EOL> else : <EOL> namespace_end = _ord_to_namespace ( <EOL> _namespace_to_ord ( ns_ranges [ i + <NUM_LIT:1> ] . namespace_start ) - <NUM_LIT:1> ) <EOL> continuous_ns_ranges . append ( NamespaceRange ( namespace_start , <EOL> namespace_end , <EOL> _app = _app ) ) <EOL> return continuous_ns_ranges <EOL> else : <EOL> return ns_ranges <EOL> def __iter__ ( self ) : <EOL> """<STR_LIT>""" <EOL> query = self . make_datastore_query ( ) <EOL> for ns_key in query . Run ( ) : <EOL> yield ns_key . name ( ) or '<STR_LIT>' <EOL> def get_namespace_keys ( app , limit ) : <EOL> """<STR_LIT>""" <EOL> ns_query = datastore . Query ( '<STR_LIT>' , keys_only = True , _app = app ) <EOL> return ns_query . Get ( limit = limit ) </s>
