Make ClaimForPeers to claim CIDR-aligned ranges

This commit is contained in:
Martynas Pumputis authored and Bryan Boreham committed 2016-06-08 16:44:54 +01:00
1 parent 2266868648
commit 49f2e208c3
2 files changed
+23 -21

No files matched your search

+22 -20
View File
@@ -368,34 +368,36 @@ func (r *Ring) AllRangeInfo() (result []RangeInfo) {
}
// ClaimForPeers claims the entire ring for the array of peers passed
// in. Only works for empty rings.
// in. Only works for empty rings. Each claimed range is CIDR-aligned.
func (r *Ring) ClaimForPeers(peers []mesh.PeerName) {
common.Assert(r.Empty())
defer r.assertInvariants()
defer r.updateExportedVariables()
defer func() {
e := r.Entries[len(r.Entries)-1]
common.Assert(address.Add(e.Token, address.Offset(e.Free)) == r.End)
}()
totalSize := r.distance(r.Start, r.End)
share := totalSize/address.Count(len(peers)) + 1
remainder := totalSize % address.Count(len(peers))
pos := r.Start
for i, peer := range peers {
if address.Count(i) == remainder {
share--
if share == 0 {
break
}
}
r.Entries.insert(entry{Token: pos, Peer: peer, Free: share})
pos += address.Address(share)
}
common.Assert(pos == r.End)
r.subdivide(r.Start, r.End, peers)
r.Seeds = peers
}
// subdivide subdivides the [from,to) CIDR for the given peers into
// CIDR-aligned subranges.
func (r *Ring) subdivide(from, to address.Address, peers []mesh.PeerName) {
share := address.Length(to, from)
if share == 0 {
return
}
if share == 1 || len(peers) == 1 {
r.Entries.insert(entry{Token: from, Peer: peers[0], Free: share})
return
}
mid := address.Add(from, address.Offset(share/2))
r.subdivide(from, mid, peers[:len(peers)/2])
r.subdivide(address.Add(mid, address.Offset(share%2)), to, peers[len(peers)/2:])
}
func (r *Ring) FprintWithNicknames(w io.Writer, m map[mesh.PeerName]string) {
for _, entry := range r.Entries {
nickname, found := m[entry.Peer]
+1 -1
View File
@@ -540,7 +540,7 @@ func TestClaimForPeers(t *testing.T) {
// Different end to usual so we get a number of addresses that a)
// is smaller than the max number of peers, and b) is divisible by
// some number of peers. This maximises coverage of edge cases.
end := dot10
end := dot8
peers := makePeers(numPeers)
// Test for a range of peer counts
for i := 0; i < numPeers; i++ {