Use address.Range instead of (start,end) pairs
This commit is contained in:
1 parent
1e71d2dacb
commit
e21f66db0a
9 files changed
+107
-100
No files matched your search
@@ -15,6 +15,12 @@ type Range struct {
|
||||
Start, End Address // [Start, End); Start <= End
|
||||
}
|
||||
|
||||
func MakeRange(start Address, size Offset) Range { return Range{Start: start, End: Add(start, size)} }
|
||||
func (r Range) Size() Offset { return Subtract(r.End, r.Start) }
|
||||
func (r Range) String() string { return fmt.Sprintf("[%s-%s)", r.Start, r.End) }
|
||||
func (r1 Range) Overlaps(r2 Range) bool { return !(r1.Start >= r2.End || r1.End <= r2.Start) }
|
||||
func (r Range) Contains(addr Address) bool { return addr >= r.Start && addr < r.End }
|
||||
|
||||
type CIDR struct {
|
||||
Start Address
|
||||
PrefixLen int
|
||||
@@ -39,7 +45,10 @@ func ParseCIDR(s string) (Address, CIDR, error) {
|
||||
}
|
||||
|
||||
func (cidr CIDR) Size() Offset { return 1 << uint(32-cidr.PrefixLen) }
|
||||
|
||||
// End is exclusive, same as in Range
|
||||
func (cidr CIDR) End() Address { return Add(cidr.Start, cidr.Size()) }
|
||||
func (cidr CIDR) Range() Range { return Range{Start: cidr.Start, End: Add(cidr.Start, cidr.Size())} }
|
||||
|
||||
func (cidr CIDR) String() string {
|
||||
return fmt.Sprintf("%s/%d", cidr.Start.String(), cidr.PrefixLen)
|
||||
|
||||
+9
-11
@@ -14,7 +14,7 @@ type allocate struct {
|
||||
resultChan chan<- allocateResult
|
||||
hasBeenCancelled func() bool
|
||||
ident string
|
||||
subnet address.CIDR
|
||||
r address.Range // Range we are trying to allocate within
|
||||
}
|
||||
|
||||
// Try returns true if the request is completed, false if pending
|
||||
@@ -27,31 +27,29 @@ func (g *allocate) Try(alloc *Allocator) bool {
|
||||
// If we have previously stored an address for this container in this subnet, return it.
|
||||
if addrs, found := alloc.owned[g.ident]; found {
|
||||
for _, addr := range addrs {
|
||||
if g.subnet.Contains(addr) {
|
||||
if g.r.Contains(addr) {
|
||||
g.resultChan <- allocateResult{addr, nil}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !alloc.universe.Overlaps(g.subnet) {
|
||||
g.resultChan <- allocateResult{0, fmt.Errorf("Subnet %s out of bounds: %s", g.subnet, alloc.universe)}
|
||||
if !alloc.universe.Overlaps(g.r) {
|
||||
g.resultChan <- allocateResult{0, fmt.Errorf("range %s out of bounds: %s", g.r, alloc.universe)}
|
||||
return true
|
||||
}
|
||||
|
||||
// Respect RFC1122 exclusions of first and last addresses
|
||||
start, end := g.subnet.Start+1, g.subnet.End()-1
|
||||
if ok, addr := alloc.space.Allocate(start, end); ok {
|
||||
alloc.debugln("Allocated", addr, "for", g.ident, "in", g.subnet)
|
||||
if ok, addr := alloc.space.Allocate(g.r); ok {
|
||||
alloc.debugln("Allocated", addr, "for", g.ident, "in", g.r)
|
||||
alloc.addOwned(g.ident, addr)
|
||||
g.resultChan <- allocateResult{addr, nil}
|
||||
return true
|
||||
}
|
||||
|
||||
// out of space
|
||||
if donor, err := alloc.ring.ChoosePeerToAskForSpace(start, end); err == nil {
|
||||
alloc.debugln("Decided to ask peer", donor, "for space in subnet", g.subnet)
|
||||
alloc.sendSpaceRequest(donor, g.subnet)
|
||||
if donor, err := alloc.ring.ChoosePeerToAskForSpace(g.r.Start, g.r.End); err == nil {
|
||||
alloc.debugln("Decided to ask peer", donor, "for space in range", g.r)
|
||||
alloc.sendSpaceRequest(donor, g.r)
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
+16
-14
@@ -45,7 +45,7 @@ type operation interface {
|
||||
type Allocator struct {
|
||||
actionChan chan<- func()
|
||||
ourName router.PeerName
|
||||
universe address.CIDR // superset of all ranges
|
||||
universe address.Range // superset of all ranges
|
||||
ring *ring.Ring // information on ranges owned by all peers
|
||||
space space.Space // more detail on ranges owned by us
|
||||
owned map[string][]address.Address // who owns what address, indexed by container-ID
|
||||
@@ -60,7 +60,7 @@ type Allocator struct {
|
||||
}
|
||||
|
||||
// NewAllocator creates and initialises a new Allocator
|
||||
func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname string, universe address.CIDR, quorum uint) *Allocator {
|
||||
func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname string, universe address.Range, quorum uint) *Allocator {
|
||||
return &Allocator{
|
||||
ourName: ourName,
|
||||
universe: universe,
|
||||
@@ -180,7 +180,9 @@ func hasBeenCancelled(cancelChan <-chan bool) func() bool {
|
||||
// if there isn't any space we block indefinitely
|
||||
func (alloc *Allocator) Allocate(ident string, subnet address.CIDR, cancelChan <-chan bool) (address.CIDR, error) {
|
||||
resultChan := make(chan allocateResult)
|
||||
op := &allocate{subnet: subnet, resultChan: resultChan, ident: ident,
|
||||
// Respect RFC1122 exclusions of first and last addresses
|
||||
r := address.Range{Start: subnet.Start + 1, End: subnet.End() - 1}
|
||||
op := &allocate{r: r, resultChan: resultChan, ident: ident,
|
||||
hasBeenCancelled: hasBeenCancelled(cancelChan)}
|
||||
alloc.doOperation(op, &alloc.pendingAllocates)
|
||||
result := <-resultChan
|
||||
@@ -347,12 +349,12 @@ func (alloc *Allocator) OnGossipUnicast(sender router.PeerName, msg []byte) erro
|
||||
case msgSpaceRequest:
|
||||
// some other peer asked us for space
|
||||
decoder := gob.NewDecoder(bytes.NewReader(msg[1:]))
|
||||
var cidr address.CIDR
|
||||
if err := decoder.Decode(&cidr); err != nil {
|
||||
var r address.Range
|
||||
if err := decoder.Decode(&r); err != nil {
|
||||
resultChan <- err
|
||||
return
|
||||
}
|
||||
alloc.donateSpace(cidr, sender)
|
||||
alloc.donateSpace(r, sender)
|
||||
resultChan <- nil
|
||||
case msgRingUpdate:
|
||||
resultChan <- alloc.update(msg[1:])
|
||||
@@ -570,10 +572,10 @@ func (alloc *Allocator) propose() {
|
||||
alloc.gossip.GossipBroadcast(alloc.Gossip())
|
||||
}
|
||||
|
||||
func (alloc *Allocator) sendSpaceRequest(dest router.PeerName, subnet address.CIDR) {
|
||||
func (alloc *Allocator) sendSpaceRequest(dest router.PeerName, r address.Range) {
|
||||
buf := new(bytes.Buffer)
|
||||
enc := gob.NewEncoder(buf)
|
||||
if err := enc.Encode(subnet); err != nil {
|
||||
if err := enc.Encode(r); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msg := router.Concat([]byte{msgSpaceRequest}, buf.Bytes())
|
||||
@@ -633,7 +635,7 @@ func (alloc *Allocator) update(msg []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (alloc *Allocator) donateSpace(subnet address.CIDR, to router.PeerName) {
|
||||
func (alloc *Allocator) donateSpace(r address.Range, to router.PeerName) {
|
||||
// No matter what we do, we'll send a unicast gossip
|
||||
// of our ring back to tha chap who asked for space.
|
||||
// This serves to both tell him of any space we might
|
||||
@@ -642,15 +644,15 @@ func (alloc *Allocator) donateSpace(subnet address.CIDR, to router.PeerName) {
|
||||
defer alloc.sendRingUpdate(to)
|
||||
|
||||
alloc.debugln("Peer", to, "asked me for space")
|
||||
start, end, ok := alloc.space.Donate(subnet.Start, subnet.End())
|
||||
chunk, ok := alloc.space.Donate(r)
|
||||
if !ok {
|
||||
free := alloc.space.NumFreeAddressesInRange(subnet.Start, subnet.End())
|
||||
free := alloc.space.NumFreeAddressesInRange(r)
|
||||
common.Assert(free == 0)
|
||||
alloc.debugln("No space to give to peer", to)
|
||||
return
|
||||
}
|
||||
alloc.debugln("Giving range", start, end, "to", to)
|
||||
alloc.ring.GrantRangeToHost(start, end, to)
|
||||
alloc.debugln("Giving range", chunk, "to", to)
|
||||
alloc.ring.GrantRangeToHost(chunk.Start, chunk.End, to)
|
||||
}
|
||||
|
||||
func (alloc *Allocator) assertInvariants() {
|
||||
@@ -678,7 +680,7 @@ func (alloc *Allocator) reportFreeSpace() {
|
||||
|
||||
freespace := make(map[address.Address]address.Offset)
|
||||
for _, r := range ranges {
|
||||
freespace[r.Start] = alloc.space.NumFreeAddressesInRange(r.Start, r.End)
|
||||
freespace[r.Start] = alloc.space.NumFreeAddressesInRange(r)
|
||||
}
|
||||
alloc.ring.ReportFree(freespace)
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ func TestCancel(t *testing.T) {
|
||||
alloc1, subnet := makeAllocator("01:00:00:02:00:00", CIDR, 2)
|
||||
alloc1.SetInterfaces(router.connect(alloc1.ourName, alloc1))
|
||||
|
||||
alloc2, subnet := makeAllocator("02:00:00:02:00:00", CIDR, 2)
|
||||
alloc2, _ := makeAllocator("02:00:00:02:00:00", CIDR, 2)
|
||||
alloc2.SetInterfaces(router.connect(alloc2.ourName, alloc2))
|
||||
alloc1.claimRingForTesting(alloc1, alloc2)
|
||||
alloc2.claimRingForTesting(alloc1, alloc2)
|
||||
|
||||
+32
-33
@@ -39,40 +39,41 @@ func (s *Space) Clear() {
|
||||
|
||||
// Walk down the free list calling f() on the in-range portions, until
|
||||
// f() returns true or we run out of free space. Return true iff f() returned true
|
||||
func (s *Space) walkFree(rangeStart, rangeEnd address.Address, f func(start, end address.Address) bool) bool {
|
||||
if rangeStart >= rangeEnd { // degenerate case
|
||||
func (s *Space) walkFree(r address.Range, f func(address.Range) bool) bool {
|
||||
if r.Start >= r.End { // degenerate case
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s.free); i += 2 {
|
||||
start, end := s.free[i], s.free[i+1]
|
||||
if end <= rangeStart { // this chunk comes before the range
|
||||
chunk := address.Range{Start: s.free[i], End: s.free[i+1]}
|
||||
if chunk.End <= r.Start { // this chunk comes before the range
|
||||
continue
|
||||
}
|
||||
if start >= rangeEnd {
|
||||
if chunk.Start >= r.End {
|
||||
// all remaining free space is completely after range
|
||||
break
|
||||
}
|
||||
// at this point we know end>start && end>rangeStart && rangeEnd>start && rangeEnd>rangeStart
|
||||
// therefore max(start, rangeStart) < min(end, rangeEnd)
|
||||
// at this point we know chunk.End>chunk.Start &&
|
||||
// chunk.End>r.Start && r.End>chunk.Start && r.End>r.Start
|
||||
// therefore max(start, r.Start) < min(end, r.End)
|
||||
// Restrict this block of free space to be in range
|
||||
if start < rangeStart {
|
||||
start = rangeStart
|
||||
if chunk.Start < r.Start {
|
||||
chunk.Start = r.Start
|
||||
}
|
||||
if end > rangeEnd {
|
||||
end = rangeEnd
|
||||
if chunk.End > r.End {
|
||||
chunk.End = r.End
|
||||
}
|
||||
// at this point we know start<end
|
||||
if f(start, end) {
|
||||
if f(chunk) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Space) Allocate(rangeStart, rangeEnd address.Address) (bool, address.Address) {
|
||||
func (s *Space) Allocate(r address.Range) (bool, address.Address) {
|
||||
var result address.Address
|
||||
return s.walkFree(rangeStart, rangeEnd, func(start, end address.Address) bool {
|
||||
result = start
|
||||
return s.walkFree(r, func(chunk address.Range) bool {
|
||||
result = chunk.Start
|
||||
s.ours = add(s.ours, result, result+1)
|
||||
s.free = subtract(s.free, result, result+1)
|
||||
return true
|
||||
@@ -89,10 +90,10 @@ func (s *Space) Claim(addr address.Address) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Space) NumFreeAddressesInRange(rangeStart, rangeEnd address.Address) address.Offset {
|
||||
func (s *Space) NumFreeAddressesInRange(r address.Range) address.Offset {
|
||||
res := address.Offset(0)
|
||||
s.walkFree(rangeStart, rangeEnd, func(start, end address.Address) bool {
|
||||
res += address.Subtract(end, start)
|
||||
s.walkFree(r, func(chunk address.Range) bool {
|
||||
res += chunk.Size()
|
||||
return false
|
||||
})
|
||||
return res
|
||||
@@ -111,12 +112,11 @@ func (s *Space) Free(addr address.Address) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Space) biggestFreeRange(rangeStart, rangeEnd address.Address) (biggestStart, biggestEnd address.Address) {
|
||||
var biggestSize address.Offset
|
||||
s.walkFree(rangeStart, rangeEnd, func(start, end address.Address) bool {
|
||||
size := address.Subtract(end, start)
|
||||
if size >= biggestSize {
|
||||
biggestStart, biggestEnd = start, end
|
||||
func (s *Space) biggestFreeRange(r address.Range) (biggest address.Range) {
|
||||
biggestSize := address.Offset(0)
|
||||
s.walkFree(r, func(chunk address.Range) bool {
|
||||
if size := chunk.Size(); size >= biggestSize {
|
||||
biggest = chunk
|
||||
biggestSize = size
|
||||
}
|
||||
return false
|
||||
@@ -124,21 +124,20 @@ func (s *Space) biggestFreeRange(rangeStart, rangeEnd address.Address) (biggestS
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Space) Donate(rangeStart, rangeEnd address.Address) (address.Address, address.Address, bool) {
|
||||
start, end := s.biggestFreeRange(rangeStart, rangeEnd)
|
||||
size := address.Subtract(end, start)
|
||||
func (s *Space) Donate(r address.Range) (address.Range, bool) {
|
||||
biggest := s.biggestFreeRange(r)
|
||||
|
||||
if size == 0 {
|
||||
return 0, 0, false
|
||||
if biggest.Size() == 0 {
|
||||
return address.Range{}, false
|
||||
}
|
||||
|
||||
// Donate half of that biggest free range. Note size/2 rounds down, so
|
||||
// the resulting donation size rounds up, and in particular can't be empty.
|
||||
start = address.Add(start, size/2)
|
||||
biggest.Start = address.Add(biggest.Start, biggest.Size()/2)
|
||||
|
||||
s.ours = subtract(s.ours, start, end)
|
||||
s.free = subtract(s.free, start, end)
|
||||
return start, end, true
|
||||
s.ours = subtract(s.ours, biggest.Start, biggest.End)
|
||||
s.free = subtract(s.free, biggest.Start, biggest.End)
|
||||
return biggest, true
|
||||
}
|
||||
|
||||
func firstGreater(a []address.Address, x address.Address) int {
|
||||
|
||||
+36
-37
@@ -62,12 +62,12 @@ func TestLowlevel(t *testing.T) {
|
||||
|
||||
s := New()
|
||||
wt.AssertEquals(t, s.NumFreeAddresses(), address.Offset(0))
|
||||
ok, got := s.Allocate(0, 1000)
|
||||
ok, got := s.Allocate(address.MakeRange(0, 1000))
|
||||
wt.AssertFalse(t, ok, "allocate in empty space should fail")
|
||||
|
||||
s.Add(100, 100)
|
||||
wt.AssertEquals(t, s.NumFreeAddresses(), address.Offset(100))
|
||||
ok, got = s.Allocate(0, 1000)
|
||||
ok, got = s.Allocate(address.MakeRange(0, 1000))
|
||||
wt.AssertTrue(t, ok && got == 100, "allocate")
|
||||
wt.AssertEquals(t, s.NumFreeAddresses(), address.Offset(99))
|
||||
wt.AssertNoErr(t, s.Claim(150))
|
||||
@@ -77,19 +77,19 @@ func TestLowlevel(t *testing.T) {
|
||||
wt.AssertErrorInterface(t, s.Free(0), (*error)(nil), "free not allocated")
|
||||
wt.AssertErrorInterface(t, s.Free(100), (*error)(nil), "double free")
|
||||
|
||||
start, end, ok := s.Donate(0, 1000)
|
||||
wt.AssertTrue(t, ok && start == 125 && address.Subtract(end, start) == 25, "donate")
|
||||
r, ok := s.Donate(address.MakeRange(0, 1000))
|
||||
wt.AssertTrue(t, ok && r.Start == 125 && r.Size() == 25, "donate")
|
||||
|
||||
// test Donate when addresses are scarce
|
||||
s = New()
|
||||
start, end, ok = s.Donate(0, 1000)
|
||||
r, ok = s.Donate(address.MakeRange(0, 1000))
|
||||
wt.AssertTrue(t, !ok, "donate on empty space should fail")
|
||||
s.Add(0, 3)
|
||||
wt.AssertNoErr(t, s.Claim(0))
|
||||
wt.AssertNoErr(t, s.Claim(2))
|
||||
start, end, ok = s.Donate(0, 1000)
|
||||
wt.AssertTrue(t, ok && start == 1 && end == 2, "donate")
|
||||
start, end, ok = s.Donate(0, 1000)
|
||||
r, ok = s.Donate(address.MakeRange(0, 1000))
|
||||
wt.AssertTrue(t, ok && r.Start == 1 && r.End == 2, "donate")
|
||||
r, ok = s.Donate(address.MakeRange(0, 1000))
|
||||
wt.AssertTrue(t, !ok, "donate should fail")
|
||||
}
|
||||
|
||||
@@ -104,23 +104,22 @@ func TestSpaceAllocate(t *testing.T) {
|
||||
)
|
||||
var (
|
||||
start = ip(testAddr1)
|
||||
end = address.Add(ip(testAddr1), 20)
|
||||
)
|
||||
|
||||
space1 := makeSpace(start, size)
|
||||
wt.AssertEquals(t, space1.NumFreeAddresses(), address.Offset(20))
|
||||
space1.assertInvariants()
|
||||
|
||||
_, addr1 := space1.Allocate(start, end)
|
||||
_, addr1 := space1.Allocate(address.MakeRange(start, size))
|
||||
wt.AssertEqualString(t, addr1.String(), testAddr1, "address")
|
||||
wt.AssertEquals(t, space1.NumFreeAddresses(), address.Offset(19))
|
||||
space1.assertInvariants()
|
||||
|
||||
_, addr2 := space1.Allocate(start, end)
|
||||
_, addr2 := space1.Allocate(address.MakeRange(start, size))
|
||||
wt.AssertFalse(t, addr2.String() == testAddr1, "address")
|
||||
wt.AssertEquals(t, space1.NumFreeAddresses(), address.Offset(18))
|
||||
wt.AssertEquals(t, space1.NumFreeAddressesInRange(ip(testAddr1), ip(testAddrx)), address.Offset(13))
|
||||
wt.AssertEquals(t, space1.NumFreeAddressesInRange(ip(testAddr1), ip(testAddry)), address.Offset(18))
|
||||
wt.AssertEquals(t, space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddrx)}), address.Offset(13))
|
||||
wt.AssertEquals(t, space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddry)}), address.Offset(18))
|
||||
space1.assertInvariants()
|
||||
|
||||
space1.Free(addr2)
|
||||
@@ -141,32 +140,33 @@ func TestSpaceFree(t *testing.T) {
|
||||
containerID = "deadbeef"
|
||||
)
|
||||
|
||||
entireRange := address.MakeRange(ip(testAddr1), 20)
|
||||
space := makeSpace(ip(testAddr1), 20)
|
||||
|
||||
// Check we are prepared to give up the entire space
|
||||
start, end := space.biggestFreeRange(ip(testAddr1), ip(testAddry))
|
||||
wt.AssertTrue(t, start == ip(testAddr1) && address.Subtract(end, start) == 20, "Wrong space")
|
||||
r := space.biggestFreeRange(entireRange)
|
||||
wt.AssertTrue(t, r.Start == ip(testAddr1) && r.Size() == 20, "Wrong space")
|
||||
|
||||
for i := 0; i < 20; i++ {
|
||||
ok, _ := space.Allocate(ip(testAddr1), ip(testAddry))
|
||||
ok, _ := space.Allocate(entireRange)
|
||||
wt.AssertTrue(t, ok, "Failed to get address")
|
||||
}
|
||||
|
||||
// Check we are full
|
||||
ok, _ := space.Allocate(ip(testAddr1), ip(testAddry))
|
||||
ok, _ := space.Allocate(entireRange)
|
||||
wt.AssertTrue(t, !ok, "Should have failed to get address")
|
||||
start, end, ok = space.Donate(ip(testAddr1), ip(testAddry))
|
||||
wt.AssertTrue(t, address.Subtract(end, start) == 0, "Wrong space")
|
||||
r, ok = space.Donate(entireRange)
|
||||
wt.AssertTrue(t, r.Size() == 0, "Wrong space")
|
||||
|
||||
// Free in the middle
|
||||
wt.AssertSuccess(t, space.Free(ip("10.0.3.13")))
|
||||
start, end = space.biggestFreeRange(ip(testAddr1), ip(testAddry))
|
||||
wt.AssertTrue(t, start == ip("10.0.3.13") && address.Subtract(end, start) == 1, "Wrong space")
|
||||
r = space.biggestFreeRange(entireRange)
|
||||
wt.AssertTrue(t, r.Start == ip("10.0.3.13") && r.Size() == 1, "Wrong space")
|
||||
|
||||
// Free one at the end
|
||||
wt.AssertSuccess(t, space.Free(ip("10.0.3.23")))
|
||||
start, end = space.biggestFreeRange(ip(testAddr1), ip(testAddry))
|
||||
wt.AssertTrue(t, start == ip("10.0.3.23") && address.Subtract(end, start) == 1, "Wrong space")
|
||||
r = space.biggestFreeRange(entireRange)
|
||||
wt.AssertTrue(t, r.Start == ip("10.0.3.23") && r.Size() == 1, "Wrong space")
|
||||
|
||||
// Now free a few at the end
|
||||
wt.AssertSuccess(t, space.Free(ip("10.0.3.22")))
|
||||
@@ -175,8 +175,8 @@ func TestSpaceFree(t *testing.T) {
|
||||
wt.AssertEquals(t, space.NumFreeAddresses(), address.Offset(4))
|
||||
|
||||
// Now get the biggest free space; should be 3.21
|
||||
start, end = space.biggestFreeRange(ip(testAddr1), ip(testAddry))
|
||||
wt.AssertTrue(t, start == ip("10.0.3.21") && address.Subtract(end, start) == 3, "Wrong space")
|
||||
r = space.biggestFreeRange(entireRange)
|
||||
wt.AssertTrue(t, r.Start == ip("10.0.3.21") && r.Size() == 3, "Wrong space")
|
||||
|
||||
// Now free a few in the middle
|
||||
wt.AssertSuccess(t, space.Free(ip("10.0.3.12")))
|
||||
@@ -186,8 +186,8 @@ func TestSpaceFree(t *testing.T) {
|
||||
wt.AssertEquals(t, space.NumFreeAddresses(), address.Offset(7))
|
||||
|
||||
// Now get the biggest free space; should be 3.21
|
||||
start, end = space.biggestFreeRange(ip(testAddr1), ip(testAddry))
|
||||
wt.AssertTrue(t, start == ip("10.0.3.10") && address.Subtract(end, start) == 4, "Wrong space")
|
||||
r = space.biggestFreeRange(entireRange)
|
||||
wt.AssertTrue(t, r.Start == ip("10.0.3.10") && r.Size() == 4, "Wrong space")
|
||||
|
||||
wt.AssertEquals(t, space.OwnedRanges(), []address.Range{address.Range{Start: ip("10.0.3.4"), End: ip("10.0.3.24")}})
|
||||
}
|
||||
@@ -210,21 +210,21 @@ func TestDonateSimple(t *testing.T) {
|
||||
ps1 := makeSpace(ipAddr1, size)
|
||||
|
||||
// Empty space set should split in two and give me the second half
|
||||
start, end, ok := ps1.Donate(ip(testAddr1), ip(testAddr1)+size)
|
||||
numGivenUp := address.Subtract(end, start)
|
||||
r, ok := ps1.Donate(address.MakeRange(ip(testAddr1), size))
|
||||
numGivenUp := r.Size()
|
||||
wt.AssertTrue(t, ok, "Donate result")
|
||||
wt.AssertEqualString(t, start.String(), "10.0.1.24", "Invalid start")
|
||||
wt.AssertEqualString(t, r.Start.String(), "10.0.1.24", "Invalid start")
|
||||
wt.AssertEquals(t, numGivenUp, address.Offset(size/2))
|
||||
wt.AssertEquals(t, ps1.NumFreeAddresses(), address.Offset(size/2))
|
||||
|
||||
// Now check we can give the rest up.
|
||||
count := 0 // count to avoid infinite loop
|
||||
for ; count < 1000; count++ {
|
||||
start, end, ok := ps1.Donate(ip(testAddr1), ip(testAddr1)+size)
|
||||
r, ok := ps1.Donate(address.MakeRange(ip(testAddr1), size))
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
numGivenUp += address.Subtract(end, start)
|
||||
numGivenUp += r.Size()
|
||||
}
|
||||
wt.AssertEquals(t, ps1.NumFreeAddresses(), address.Offset(0))
|
||||
wt.AssertEquals(t, numGivenUp, address.Offset(size))
|
||||
@@ -235,13 +235,12 @@ func TestDonateHard(t *testing.T) {
|
||||
var (
|
||||
start = ip("10.0.1.0")
|
||||
size address.Offset = 48
|
||||
end = address.Add(start, size)
|
||||
)
|
||||
|
||||
// Fill a fresh space
|
||||
spaceset := makeSpace(start, size)
|
||||
for i := address.Offset(0); i < size; i++ {
|
||||
ok, _ := spaceset.Allocate(start, address.Add(start, size))
|
||||
ok, _ := spaceset.Allocate(address.MakeRange(start, size))
|
||||
wt.AssertTrue(t, ok, "Failed to get IP!")
|
||||
}
|
||||
|
||||
@@ -254,10 +253,10 @@ func TestDonateHard(t *testing.T) {
|
||||
}
|
||||
|
||||
// Now split
|
||||
newRange, end, ok := spaceset.Donate(start, end)
|
||||
newRange, ok := spaceset.Donate(address.MakeRange(start, size))
|
||||
wt.AssertTrue(t, ok, "GiveUpSpace result")
|
||||
wt.AssertEquals(t, newRange, ip("10.0.1.23"))
|
||||
wt.AssertEquals(t, address.Subtract(end, newRange), address.Offset(24))
|
||||
wt.AssertEquals(t, newRange.Start, ip("10.0.1.23"))
|
||||
wt.AssertEquals(t, newRange.Size(), address.Offset(24))
|
||||
wt.AssertEquals(t, spaceset.NumFreeAddresses(), address.Offset(23))
|
||||
|
||||
//Space set should now have 2 spaces
|
||||
|
||||
@@ -140,7 +140,7 @@ func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, addres
|
||||
}
|
||||
|
||||
alloc := NewAllocator(peername, router.PeerUID(rand.Int63()),
|
||||
"nick-"+name, cidr, quorum)
|
||||
"nick-"+name, cidr.Range(), quorum)
|
||||
|
||||
return alloc, cidr
|
||||
}
|
||||
@@ -165,7 +165,7 @@ func (alloc *Allocator) claimRingForTesting(allocs ...*Allocator) {
|
||||
func (alloc *Allocator) NumFreeAddresses(subnet address.CIDR) address.Offset {
|
||||
resultChan := make(chan address.Offset)
|
||||
alloc.actionChan <- func() {
|
||||
resultChan <- alloc.space.NumFreeAddressesInRange(subnet.Start+1, subnet.End()-1)
|
||||
resultChan <- alloc.space.NumFreeAddressesInRange(address.MakeRange(subnet.Start+1, subnet.Size()-2))
|
||||
}
|
||||
return <-resultChan
|
||||
}
|
||||
|
||||
+1
-1
@@ -218,7 +218,7 @@ func createAllocator(router *weave.Router, apiPath string, ipRangeStr string, de
|
||||
log.Fatalf("Default subnet %s out of bounds: %s", defaultSubnet, ipRange)
|
||||
}
|
||||
}
|
||||
allocator := ipam.NewAllocator(router.Ourself.Peer.Name, router.Ourself.Peer.UID, router.Ourself.Peer.NickName, ipRange, quorum)
|
||||
allocator := ipam.NewAllocator(router.Ourself.Peer.Name, router.Ourself.Peer.UID, router.Ourself.Peer.NickName, ipRange.Range(), quorum)
|
||||
|
||||
allocator.SetInterfaces(router.NewGossip("IPallocation", allocator))
|
||||
allocator.Start()
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package router
|
||||
|
||||
const (
|
||||
Protocol = "weave"
|
||||
ProtocolVersion = 19
|
||||
ProtocolVersion = 20
|
||||
)
|
||||
|
||||
type ProtocolTag byte
|
||||
|
||||
Reference in new issue
Block a user