#NEWLINE# def _build_weighted_replicas_by_tier( self ) : #NEWLINE# #INDENT# '\n        Returns a dict mapping <tier> => replicanths for all tiers in\n        the ring based on their weights.\n        ' #NEWLINE# weight_of_one_part = self . weight_of_one_part ( ) #NEWLINE# weighted_replicas_for_dev = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# devices_with_room = [ ] #NEWLINE# for dev in self . _iter_devs ( ) : #NEWLINE# #INDENT# if ( not dev [ 'weight' ] ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# weighted_replicas = ( ( dev [ 'weight' ] * weight_of_one_part ) / self . parts ) #NEWLINE# if ( weighted_replicas < 1 ) : #NEWLINE# #INDENT# devices_with_room . append ( dev [ 'id' ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# weighted_replicas = 1 #NEWLINE# #UNINDENT# weighted_replicas_for_dev [ dev [ 'id' ] ] = weighted_replicas #NEWLINE# #UNINDENT# while True : #NEWLINE# #INDENT# remaining = ( self . replicas - sum ( weighted_replicas_for_dev . values ( ) ) ) #NEWLINE# if ( remaining < 1e-10 ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# devices_with_room = [ d for d in devices_with_room if ( weighted_replicas_for_dev [ d ] < 1 ) ] #NEWLINE# rel_weight = ( remaining / sum ( ( weighted_replicas_for_dev [ d ] for d in devices_with_room ) ) ) #NEWLINE# for d in devices_with_room : #NEWLINE# #INDENT# weighted_replicas_for_dev [ d ] = min ( 1 , ( weighted_replicas_for_dev [ d ] * ( rel_weight + 1 ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# weighted_replicas_by_tier = defaultdict ( float ) #NEWLINE# for dev in self . _iter_devs ( ) : #NEWLINE# #INDENT# if ( not dev [ 'weight' ] ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# assigned_replicanths = weighted_replicas_for_dev [ dev [ 'id' ] ] #NEWLINE# dev_tier = ( dev [ 'region' ] , dev [ 'zone' ] , dev [ 'ip' ] , dev [ 'id' ] ) #NEWLINE# for i in range ( ( len ( dev_tier ) + 1 ) ) : #NEWLINE# #INDENT# tier = dev_tier [ : i ] #NEWLINE# weighted_replicas_by_tier [ tier ] += assigned_replicanths #NEWLINE# #UNINDENT# #UNINDENT# tiers = [ 'cluster' , 'regions' , 'zones' , 'servers' , 'devices' ] #NEWLINE# for ( i , tier_name ) in enumerate ( tiers ) : #NEWLINE# #INDENT# replicas_at_tier = sum ( ( weighted_replicas_by_tier [ t ] for t in weighted_replicas_by_tier if ( len ( t ) == i ) ) ) #NEWLINE# if ( abs ( ( self . replicas - replicas_at_tier ) ) > 1e-10 ) : #NEWLINE# #INDENT# raise exceptions . RingValidationError ( ( '%s != %s at tier %s' % ( replicas_at_tier , self . replicas , tier_name ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# return weighted_replicas_by_tier