@@ -391,46 +391,17 @@ def _set_parts_wanted(self):
391
391
392
392
def _initial_balance (self ):
393
393
"""
394
- Initial partition assignment is treated separately from rebalancing an
395
- existing ring. Initial assignment is performed by ordering all the
396
- devices by how many partitions they still want (and kept in order
397
- during the process). The partitions are then iterated through,
398
- assigning them to the next "most wanted" device, with distinct zone
399
- restrictions.
394
+ Initial partition assignment is the same as rebalancing an
395
+ existing ring, but with some initial setup beforehand.
400
396
"""
401
- for dev in self ._iter_devs ():
402
- dev ['sort_key' ] = \
403
- '%08x.%04x' % (dev ['parts_wanted' ], randint (0 , 0xffff ))
404
- available_devs = sorted ((d for d in self ._iter_devs ()),
405
- key = lambda x : x ['sort_key' ])
406
397
self ._replica2part2dev = \
407
- [array ('H' ) for _junk in xrange (self .replicas )]
408
- for _junk in xrange (self .parts ):
409
- other_zones = array ('H' )
410
- for replica in xrange (self .replicas ):
411
- index = len (available_devs ) - 1
412
- while available_devs [index ]['zone' ] in other_zones :
413
- index -= 1
414
- dev = available_devs .pop (index )
415
- self ._replica2part2dev [replica ].append (dev ['id' ])
416
- dev ['parts_wanted' ] -= 1
417
- dev ['parts' ] += 1
418
- dev ['sort_key' ] = \
419
- '%08x.%04x' % (dev ['parts_wanted' ], randint (0 , 0xffff ))
420
- index = 0
421
- end = len (available_devs )
422
- while index < end :
423
- mid = (index + end ) // 2
424
- if dev ['sort_key' ] < available_devs [mid ]['sort_key' ]:
425
- end = mid
426
- else :
427
- index = mid + 1
428
- available_devs .insert (index , dev )
429
- other_zones .append (dev ['zone' ])
398
+ [array ('H' , (0 for _junk in xrange (self .parts )))
399
+ for _junk in xrange (self .replicas )]
400
+
401
+ replicas = range (self .replicas )
430
402
self ._last_part_moves = array ('B' , (0 for _junk in xrange (self .parts )))
431
403
self ._last_part_moves_epoch = int (time ())
432
- for dev in self ._iter_devs ():
433
- del dev ['sort_key' ]
404
+ self ._reassign_parts ((p , replicas ) for p in xrange (self .parts ))
434
405
435
406
def _update_last_part_moves (self ):
436
407
"""
@@ -493,8 +464,7 @@ def _reassign_parts(self, reassign_parts):
493
464
according to the "most wanted" and distinct zone restrictions.
494
465
"""
495
466
for dev in self ._iter_devs ():
496
- dev ['sort_key' ] = '%08x.%04x' % (self .parts +
497
- dev ['parts_wanted' ], randint (0 , 0xffff ))
467
+ dev ['sort_key' ] = self ._sort_key_for (dev )
498
468
available_devs = \
499
469
sorted ((d for d in self ._iter_devs () if d ['weight' ]),
500
470
key = lambda x : x ['sort_key' ])
@@ -518,17 +488,23 @@ def _reassign_parts(self, reassign_parts):
518
488
self ._replica2part2dev [replica ][part ] = dev ['id' ]
519
489
dev ['parts_wanted' ] -= 1
520
490
dev ['parts' ] += 1
521
- dev ['sort_key' ] = \
522
- '%08x.%04x' % (self .parts + dev ['parts_wanted' ],
523
- randint (0 , 0xffff ))
524
- index = 0
525
- end = len (available_devs )
526
- while index < end :
527
- mid = (index + end ) // 2
528
- if dev ['sort_key' ] < available_devs [mid ]['sort_key' ]:
529
- end = mid
530
- else :
531
- index = mid + 1
532
- available_devs .insert (index , dev )
491
+ dev ['sort_key' ] = self ._sort_key_for (dev )
492
+ self ._insert_dev_sorted (available_devs , dev )
493
+
533
494
for dev in self ._iter_devs ():
534
495
del dev ['sort_key' ]
496
+
497
+ def _insert_dev_sorted (self , devs , dev ):
498
+ index = 0
499
+ end = len (devs )
500
+ while index < end :
501
+ mid = (index + end ) // 2
502
+ if dev ['sort_key' ] < devs [mid ]['sort_key' ]:
503
+ end = mid
504
+ else :
505
+ index = mid + 1
506
+ devs .insert (index , dev )
507
+
508
+ def _sort_key_for (self , dev ):
509
+ return '%08x.%04x' % (self .parts + dev ['parts_wanted' ],
510
+ randint (0 , 0xffff ))
0 commit comments