+ return (self.use_peers, self.preexisting_shares)
+ else:
+ delta = self.servers_of_happiness - len(effective_happiness)
+ shares = shares_by_server(self.preexisting_shares)
+ # Each server in shares maps to a set of shares stored on it.
+ # Since we want to keep at least one share on each server
+ # that has one (otherwise we'd only be making
+ # the situation worse by removing distinct servers),
+ # each server has len(its shares) - 1 to spread around.
+ shares_to_spread = sum([len(list(sharelist)) - 1
+ for (server, sharelist)
+ in shares.items()])
+ if delta <= len(self.uncontacted_peers) and \
+ shares_to_spread >= delta:
+ # Loop through the allocated shares, removing
+ items = shares.items()
+ while len(self.homeless_shares) < delta:
+ servernum, sharelist = items.pop()
+ if len(sharelist) > 1:
+ share = sharelist.pop()
+ self.homeless_shares.append(share)
+ del(self.preexisting_shares[share])
+ items.append((servernum, sharelist))
+ return self._loop()
+ else:
+ raise NotEnoughSharesError("shares could only be placed on %d "
+ "servers (%d were requested)" %
+ (len(effective_happiness),
+ self.servers_of_happiness))