Introduce 'Count' type to avoid abusing 'Offset'
This commit is contained in:
1 parent
7b6364696c
commit
f11314ed3e
9 files changed
+45
-38
No files matched your search
+1
-1
@@ -795,7 +795,7 @@ func (alloc *Allocator) reportFreeSpace() {
|
||||
return
|
||||
}
|
||||
|
||||
freespace := make(map[address.Address]address.Offset)
|
||||
freespace := make(map[address.Address]address.Count)
|
||||
for _, r := range ranges {
|
||||
freespace[r.Start] = alloc.space.NumFreeAddressesInRange(r)
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestAllocFree(t *testing.T) {
|
||||
// Move the clock forward and clear out the dead container
|
||||
alloc.actionChan <- func() { alloc.now = func() time.Time { return time.Now().Add(containerDiedTimeout * 2) } }
|
||||
alloc.actionChan <- func() { alloc.removeDeadContainers() }
|
||||
require.Equal(t, address.Offset(spaceSize+1), alloc.NumFreeAddresses(subnet.Range()))
|
||||
require.Equal(t, address.Count(spaceSize+1), alloc.NumFreeAddresses(subnet.Range()))
|
||||
}
|
||||
|
||||
func TestBootstrap(t *testing.T) {
|
||||
@@ -345,7 +345,7 @@ func TestTransfer(t *testing.T) {
|
||||
require.NoError(t, alloc1.AdminTakeoverRanges(alloc3.ourName.String()))
|
||||
router.Flush()
|
||||
|
||||
require.Equal(t, address.Offset(1024), alloc1.NumFreeAddresses(subnet.Range()))
|
||||
require.Equal(t, address.Count(1024), alloc1.NumFreeAddresses(subnet.Range()))
|
||||
|
||||
_, err = alloc1.Allocate("foo", subnet, returnFalse)
|
||||
require.True(t, err == nil, "Failed to get address")
|
||||
|
||||
@@ -15,6 +15,7 @@ type entry struct {
|
||||
Peer mesh.PeerName // Who owns this range
|
||||
Version uint32 // Version of this range
|
||||
Free address.Offset // Number of free IPs in this range
|
||||
// Note: Free should perhaps be an address.Count, but we can't change the wire protocol
|
||||
}
|
||||
|
||||
func (e *entry) Equal(e2 *entry) bool {
|
||||
|
||||
+4
-4
@@ -393,7 +393,7 @@ func (r *Ring) String() string {
|
||||
// ReportFree is used by the allocator to tell the ring how many free
|
||||
// ips are in a given range, so that ChoosePeersToAskForSpace can make
|
||||
// more intelligent decisions.
|
||||
func (r *Ring) ReportFree(freespace map[address.Address]address.Offset) {
|
||||
func (r *Ring) ReportFree(freespace map[address.Address]address.Count) {
|
||||
r.assertInvariants()
|
||||
defer r.assertInvariants()
|
||||
defer r.updateExportedVariables()
|
||||
@@ -423,13 +423,13 @@ func (r *Ring) ReportFree(freespace map[address.Address]address.Offset) {
|
||||
// Check we're not reporting more space than the range
|
||||
entry, next := entries.entry(i), entries.entry(i+1)
|
||||
maxSize := r.distance(entry.Token, next.Token)
|
||||
common.Assert(free <= maxSize)
|
||||
common.Assert(free <= address.Count(maxSize))
|
||||
|
||||
if entries[i].Free == free {
|
||||
if address.Count(entries[i].Free) == free {
|
||||
return
|
||||
}
|
||||
|
||||
entries[i].Free = free
|
||||
entries[i].Free = address.Offset(free)
|
||||
entries[i].Version++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ func TestFindFree(t *testing.T) {
|
||||
assertPeersWithSpace(t, ring1, start, end, 0)
|
||||
|
||||
// We shouldn't return outselves
|
||||
ring1.ReportFree(map[address.Address]address.Offset{start: 10})
|
||||
ring1.ReportFree(map[address.Address]address.Count{start: 10})
|
||||
assertPeersWithSpace(t, ring1, start, end, 0)
|
||||
|
||||
ring1.Entries = []*entry{{Token: start, Peer: peer1name, Free: 1},
|
||||
@@ -409,7 +409,7 @@ func TestReportFree(t *testing.T) {
|
||||
ring1.GrantRangeToHost(middle, end, peer2name)
|
||||
require.NoError(t, ring2.Merge(*ring1))
|
||||
|
||||
freespace := make(map[address.Address]address.Offset)
|
||||
freespace := make(map[address.Address]address.Count)
|
||||
for _, r := range ring2.OwnedRanges() {
|
||||
freespace[r.Start] = 0
|
||||
}
|
||||
|
||||
+4
-4
@@ -88,8 +88,8 @@ func (s *Space) Claim(addr address.Address) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Space) NumFreeAddressesInRange(r address.Range) address.Offset {
|
||||
res := address.Offset(0)
|
||||
func (s *Space) NumFreeAddressesInRange(r address.Range) address.Count {
|
||||
res := address.Count(0)
|
||||
s.walkFree(r, func(chunk address.Range) bool {
|
||||
res += chunk.Size()
|
||||
return false
|
||||
@@ -111,7 +111,7 @@ func (s *Space) Free(addr address.Address) error {
|
||||
}
|
||||
|
||||
func (s *Space) biggestFreeRange(r address.Range) (biggest address.Range) {
|
||||
biggestSize := address.Offset(0)
|
||||
biggestSize := address.Count(0)
|
||||
s.walkFree(r, func(chunk address.Range) bool {
|
||||
if size := chunk.Size(); size >= biggestSize {
|
||||
biggest = chunk
|
||||
@@ -131,7 +131,7 @@ func (s *Space) Donate(r address.Range) (address.Range, bool) {
|
||||
|
||||
// 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.
|
||||
biggest.Start = address.Add(biggest.Start, biggest.Size()/2)
|
||||
biggest.Start = address.Add(biggest.Start, address.Offset(biggest.Size()/2))
|
||||
|
||||
s.ours = subtract(s.ours, biggest.Start, biggest.End)
|
||||
s.free = subtract(s.free, biggest.Start, biggest.End)
|
||||
|
||||
+22
-22
@@ -21,10 +21,10 @@ func ip(s string) address.Address {
|
||||
|
||||
// Helper function to avoid 'NumFreeAddressesInRange(start, end)'
|
||||
// dozens of times in tests
|
||||
func (s *Space) NumFreeAddresses() address.Offset {
|
||||
res := address.Offset(0)
|
||||
func (s *Space) NumFreeAddresses() address.Count {
|
||||
res := address.Count(0)
|
||||
for i := 0; i < len(s.free); i += 2 {
|
||||
res += address.Subtract(s.free[i+1], s.free[i])
|
||||
res += address.Length(s.free[i+1], s.free[i])
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -61,19 +61,19 @@ func TestLowlevel(t *testing.T) {
|
||||
require.Equal(t, []address.Address{}, a)
|
||||
|
||||
s := New()
|
||||
require.Equal(t, address.Offset(0), s.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(0), s.NumFreeAddresses())
|
||||
ok, got := s.Allocate(address.NewRange(0, 1000))
|
||||
require.False(t, ok, "allocate in empty space should fail")
|
||||
|
||||
s.Add(100, 100)
|
||||
require.Equal(t, address.Offset(100), s.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(100), s.NumFreeAddresses())
|
||||
ok, got = s.Allocate(address.NewRange(0, 1000))
|
||||
require.True(t, ok && got == 100, "allocate")
|
||||
require.Equal(t, address.Offset(99), s.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(99), s.NumFreeAddresses())
|
||||
require.NoError(t, s.Claim(150))
|
||||
require.Equal(t, address.Offset(98), s.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(98), s.NumFreeAddresses())
|
||||
require.NoError(t, s.Free(100))
|
||||
require.Equal(t, address.Offset(99), s.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(99), s.NumFreeAddresses())
|
||||
wt.AssertErrorInterface(t, (*error)(nil), s.Free(0), "free not allocated")
|
||||
wt.AssertErrorInterface(t, (*error)(nil), s.Free(100), "double free")
|
||||
|
||||
@@ -107,19 +107,19 @@ func TestSpaceAllocate(t *testing.T) {
|
||||
)
|
||||
|
||||
space1 := makeSpace(start, size)
|
||||
require.Equal(t, address.Offset(20), space1.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(20), space1.NumFreeAddresses())
|
||||
space1.assertInvariants()
|
||||
|
||||
_, addr1 := space1.Allocate(address.NewRange(start, size))
|
||||
require.Equal(t, testAddr1, addr1.String(), "address")
|
||||
require.Equal(t, address.Offset(19), space1.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(19), space1.NumFreeAddresses())
|
||||
space1.assertInvariants()
|
||||
|
||||
_, addr2 := space1.Allocate(address.NewRange(start, size))
|
||||
require.False(t, addr2.String() == testAddr1, "address")
|
||||
require.Equal(t, address.Offset(18), space1.NumFreeAddresses())
|
||||
require.Equal(t, address.Offset(13), space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddrx)}))
|
||||
require.Equal(t, address.Offset(18), space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddry)}))
|
||||
require.Equal(t, address.Count(18), space1.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(13), space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddrx)}))
|
||||
require.Equal(t, address.Count(18), space1.NumFreeAddressesInRange(address.Range{Start: ip(testAddr1), End: ip(testAddry)}))
|
||||
space1.assertInvariants()
|
||||
|
||||
space1.Free(addr2)
|
||||
@@ -172,7 +172,7 @@ func TestSpaceFree(t *testing.T) {
|
||||
require.NoError(t, space.Free(ip("10.0.3.22")))
|
||||
require.NoError(t, space.Free(ip("10.0.3.21")))
|
||||
|
||||
require.Equal(t, address.Offset(4), space.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(4), space.NumFreeAddresses())
|
||||
|
||||
// Now get the biggest free space; should be 3.21
|
||||
r = space.biggestFreeRange(entireRange)
|
||||
@@ -183,7 +183,7 @@ func TestSpaceFree(t *testing.T) {
|
||||
require.NoError(t, space.Free(ip("10.0.3.11")))
|
||||
require.NoError(t, space.Free(ip("10.0.3.10")))
|
||||
|
||||
require.Equal(t, address.Offset(7), space.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(7), space.NumFreeAddresses())
|
||||
|
||||
// Now get the biggest free space; should be 3.21
|
||||
r = space.biggestFreeRange(entireRange)
|
||||
@@ -210,8 +210,8 @@ func TestDonateSimple(t *testing.T) {
|
||||
numGivenUp := r.Size()
|
||||
require.True(t, ok, "Donate result")
|
||||
require.Equal(t, "10.0.1.24", r.Start.String(), "Invalid start")
|
||||
require.Equal(t, address.Offset(size/2), numGivenUp)
|
||||
require.Equal(t, address.Offset(size/2), ps1.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(size/2), numGivenUp)
|
||||
require.Equal(t, address.Count(size/2), ps1.NumFreeAddresses())
|
||||
|
||||
// Now check we can give the rest up.
|
||||
count := 0 // count to avoid infinite loop
|
||||
@@ -222,8 +222,8 @@ func TestDonateSimple(t *testing.T) {
|
||||
}
|
||||
numGivenUp += r.Size()
|
||||
}
|
||||
require.Equal(t, address.Offset(0), ps1.NumFreeAddresses())
|
||||
require.Equal(t, address.Offset(size), numGivenUp)
|
||||
require.Equal(t, address.Count(0), ps1.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(size), numGivenUp)
|
||||
}
|
||||
|
||||
func TestDonateHard(t *testing.T) {
|
||||
@@ -240,7 +240,7 @@ func TestDonateHard(t *testing.T) {
|
||||
require.True(t, ok, "Failed to get IP!")
|
||||
}
|
||||
|
||||
require.Equal(t, address.Offset(0), spaceset.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(0), spaceset.NumFreeAddresses())
|
||||
|
||||
// Now free all but the last address
|
||||
// this will force us to split the free list
|
||||
@@ -252,8 +252,8 @@ func TestDonateHard(t *testing.T) {
|
||||
newRange, ok := spaceset.Donate(address.NewRange(start, size))
|
||||
require.True(t, ok, "GiveUpSpace result")
|
||||
require.Equal(t, ip("10.0.1.23"), newRange.Start)
|
||||
require.Equal(t, address.Offset(24), newRange.Size())
|
||||
require.Equal(t, address.Offset(23), spaceset.NumFreeAddresses())
|
||||
require.Equal(t, address.Count(24), newRange.Size())
|
||||
require.Equal(t, address.Count(23), spaceset.NumFreeAddresses())
|
||||
|
||||
//Space set should now have 2 spaces
|
||||
expected := New()
|
||||
|
||||
@@ -167,8 +167,8 @@ func (alloc *Allocator) claimRingForTesting(allocs ...*Allocator) {
|
||||
alloc.space.AddRanges(alloc.ring.OwnedRanges())
|
||||
}
|
||||
|
||||
func (alloc *Allocator) NumFreeAddresses(r address.Range) address.Offset {
|
||||
resultChan := make(chan address.Offset)
|
||||
func (alloc *Allocator) NumFreeAddresses(r address.Range) address.Count {
|
||||
resultChan := make(chan address.Count)
|
||||
alloc.actionChan <- func() {
|
||||
resultChan <- alloc.space.NumFreeAddressesInRange(r)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
// Using 32-bit integer to represent IPv4 address
|
||||
type Address uint32
|
||||
type Offset uint32
|
||||
type Count uint32
|
||||
|
||||
type Range struct {
|
||||
Start, End Address // [Start, End); Start <= End
|
||||
@@ -18,7 +19,7 @@ type Range struct {
|
||||
func NewRange(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) Size() Count { return Length(r.End, r.Start) }
|
||||
func (r Range) String() string { return fmt.Sprintf("%s-%s", r.Start, r.End-1) }
|
||||
func (r Range) Overlaps(or Range) bool { return !(r.Start >= or.End || r.End <= or.Start) }
|
||||
func (r Range) Contains(addr Address) bool { return addr >= r.Start && addr < r.End }
|
||||
@@ -116,6 +117,11 @@ func Subtract(a, b Address) Offset {
|
||||
return Offset(a - b)
|
||||
}
|
||||
|
||||
func Length(a, b Address) Count {
|
||||
common.Assert(a >= b)
|
||||
return Count(a - b)
|
||||
}
|
||||
|
||||
func Min(a, b Offset) Offset {
|
||||
if a > b {
|
||||
return b
|
||||
|
||||
Reference in new issue
Block a user