'Returns a dict mapping <tier> => replicanths for all tiers in
the ring based on their weights.'

def _build_weighted_replicas_by_tier(self):

    weight_of_one_part = self.weight_of_one_part()
    weighted_replicas_for_dev = {}
    devices_with_room = []
    for dev in self._iter_devs():
        if (not dev['weight']):
            continue
        weighted_replicas = ((dev['weight'] * weight_of_one_part) / self.parts)
        if (weighted_replicas < 1):
            devices_with_room.append(dev['id'])
        else:
            weighted_replicas = 1
        weighted_replicas_for_dev[dev['id']] = weighted_replicas
    while True:
        remaining = (self.replicas - sum(weighted_replicas_for_dev.values()))
        if (remaining < 1e-10):
            break
        devices_with_room = [d for d in devices_with_room if (weighted_replicas_for_dev[d] < 1)]
        rel_weight = (remaining / sum((weighted_replicas_for_dev[d] for d in devices_with_room)))
        for d in devices_with_room:
            weighted_replicas_for_dev[d] = min(1, (weighted_replicas_for_dev[d] * (rel_weight + 1)))
    weighted_replicas_by_tier = defaultdict(float)
    for dev in self._iter_devs():
        if (not dev['weight']):
            continue
        assigned_replicanths = weighted_replicas_for_dev[dev['id']]
        dev_tier = (dev['region'], dev['zone'], dev['ip'], dev['id'])
        for i in range((len(dev_tier) + 1)):
            tier = dev_tier[:i]
            weighted_replicas_by_tier[tier] += assigned_replicanths
    tiers = ['cluster', 'regions', 'zones', 'servers', 'devices']
    for (i, tier_name) in enumerate(tiers):
        replicas_at_tier = sum((weighted_replicas_by_tier[t] for t in weighted_replicas_by_tier if (len(t) == i)))
        if (abs((self.replicas - replicas_at_tier)) > 1e-10):
            raise exceptions.RingValidationError(('%s    !=    %s    at    tier    %s' % (replicas_at_tier, self.replicas, tier_name)))
    return weighted_replicas_by_tier
