def _gather_parts_for_balance_forced(self, assign_parts, start, **kwargs):
        for offset in range(self.parts):
            part = (start + offset) % self.parts
            if self._last_part_moves[part] < self.min_part_hours:
                continue
            overweight_dev_replica = []
            for replica in self._replicas_for_part(part):
                dev_id = self._replica2part2dev[replica][part]
                if dev_id == NONE_DEV:
                    continue
                dev = self.devs[dev_id]
                if dev['parts_wanted'] < 0:
                    overweight_dev_replica.append((dev, replica))

            if not overweight_dev_replica:
                continue

            overweight_dev_replica.sort(
                key=lambda dr: dr[0]['parts_wanted'])
            for dev, replica in overweight_dev_replica:
                if self._last_part_moves[part] < self.min_part_hours:
                    break
                # this is the most overweight_device holding a replica of this
                # part we don't know where it's going to end up - but we'll
                # pick it up and hope for the best.
                dev['parts_wanted'] += 1
                dev['parts'] -= 1
                assign_parts[part].append(replica)
                self.logger.debug(
                    "Gathered %d/%d from dev %d [weight forced]",
                    part, replica, dev['id'])
                self._replica2part2dev[replica][part] = NONE_DEV
                self._last_part_moves[part] = 0
Included for API consistency
dataset/ETHPy150Open openstack/swift/swift/common/ring/builder.py/RingBuilder._gather_parts_for_balance_forced--crossover with--dataset/ETHPy150Open saltstack/salt/salt/returners/couchdb_return.py/save_minions