From c76f640e2e67d9dfeb345269dc0671eaf0ec31f4 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 25 Jun 2015 14:48:17 +0100 Subject: [PATCH] Simpler implementation of weighted-random order --- ipam/ring/ring.go | 50 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index c411b163..da65014b 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -392,10 +392,23 @@ func (r *Ring) ReportFree(freespace map[address.Address]address.Offset) { } } -// ChoosePeerToAskForSpace returns all peers we can ask for space in +type weightedPeer struct { + weight float64 + peername router.PeerName +} +type weightedPeers []weightedPeer + +func (ws weightedPeers) Len() int { return len(ws) } +func (ws weightedPeers) Less(i, j int) bool { return ws[i].weight < ws[j].weight } +func (ws weightedPeers) Swap(i, j int) { ws[i], ws[j] = ws[j], ws[i] } + +// ChoosePeersToAskForSpace returns all peers we can ask for space in // the range [start, end), in weighted-random order. Assumes start 0 { - // Pick a number up to remaining free space - // (note using 64-bit because rand.Intn is signed int) - rn := rand.Int63n(int64(cdf[len(cdf)-1].sum)) - // Find where this number lands in the CDF, and take that peer - i := sort.Search(len(cdf), func(j int) bool { return int64(cdf[j].sum) > rn }) - result = append(result, cdf[i].peername) - // Remove this entry from the CDF and adjust all following sums - space := totalSpacePerPeer[cdf[i].peername] - for j := i; j < len(cdf); j++ { - cdf[j].sum -= space - } - cdf = append(cdf[:i], cdf[i+1:]...) + sort.Sort(ws) + // Reverse order (bigger weights come last after sort) and copy to result + for i := range ws { + result = append(result, ws[len(ws)-i-1].peername) } return }