From af5531cbf62fbc179f74141feac765ec290c8a45 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 28 May 2015 18:12:30 +0100 Subject: [PATCH] Fix incorrect calculation of free space when granting a range that spans a token and inserting a new token, the free space on the last token that we are handing over has to change. Add unit test for this too. --- ipam/address/address.go | 7 +++++++ ipam/ring/ring.go | 2 +- ipam/ring/ring_test.go | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ipam/address/address.go b/ipam/address/address.go index b9f47ac3..97e162d0 100644 --- a/ipam/address/address.go +++ b/ipam/address/address.go @@ -52,3 +52,10 @@ func Subtract(a, b Address) Offset { common.Assert(a >= b) return Offset(a - b) } + +func Min(a, b Offset) Offset { + if a > b { + return b + } + return a +} diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index 7590a3ce..16ae1451 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -167,7 +167,7 @@ func (r *Ring) GrantRangeToHost(start, end address.Address, peer router.PeerName pos := preceedingPos + 1 for ; pos < len(r.Entries) && r.Entries.entry(pos).Token < end; pos++ { entry := r.Entries.entry(pos) - entry.update(peer, entry.Free) + entry.update(peer, address.Min(entry.Free, r.distance(entry.Token, end))) } // There is never an entry with a token of r.End, as the end of diff --git a/ipam/ring/ring_test.go b/ipam/ring/ring_test.go index 1c12c777..f3ec1e0f 100644 --- a/ipam/ring/ring_test.go +++ b/ipam/ring/ring_test.go @@ -158,6 +158,17 @@ func TestGrantSplit(t *testing.T) { wt.AssertEquals(t, ring1.Entries, entries{{Token: start, Peer: peer1name, Free: 10, Version: 1}, {Token: dot10, Peer: peer2name, Free: 235}, {Token: dot245, Peer: peer1name, Free: 10}}) + ring1.assertInvariants() + + // Grant range spanning a live token, and inserting a new token + ring1.Entries = []*entry{{Token: start, Peer: peer1name, Free: 10, Version: 2}, + {Token: dot10, Peer: peer1name, Free: 118}, {Token: middle, Peer: peer1name, Free: 127}} + ring1.GrantRangeToHost(dot10, dot245, peer2name) + wt.AssertEquals(t, ring1.Entries, entries{{Token: start, Peer: peer1name, Free: 10, Version: 2}, + {Token: dot10, Peer: peer2name, Free: 118, Version: 1}, + {Token: middle, Peer: peer2name, Free: 117, Version: 1}, + {Token: dot245, Peer: peer1name, Free: 10, Version: 0}}) + ring1.assertInvariants() } func TestMergeSimple(t *testing.T) {