From e89d5518176624a18cee2055c7fbb44efd67548a Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Wed, 27 May 2015 17:32:45 -0400 Subject: [PATCH] Add a new contiguous allocator strategy option Also fix an error in port allocator --- pkg/registry/service/allocator/bitmap.go | 38 +++++++++++++++++++ .../service/portallocator/allocator.go | 3 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/pkg/registry/service/allocator/bitmap.go b/pkg/registry/service/allocator/bitmap.go index f5a50363bfc..3c647ab431d 100644 --- a/pkg/registry/service/allocator/bitmap.go +++ b/pkg/registry/service/allocator/bitmap.go @@ -55,6 +55,7 @@ var _ Snapshottable = &AllocationBitmap{} // allocateStrategy is a search strategy in the allocation map for a valid item. type allocateStrategy func(allocated *big.Int, max, count int) (int, bool) +// NewAllocationMap creates an allocation bitmap using the random scan strategy. func NewAllocationMap(max int, rangeSpec string) *AllocationBitmap { a := AllocationBitmap{ strategy: randomScanStrategy, @@ -66,6 +67,30 @@ func NewAllocationMap(max int, rangeSpec string) *AllocationBitmap { return &a } +// NewContiguousAllocationMap creates an allocation bitmap using the contiguous scan strategy. +func NewContiguousAllocationMap(max int, rangeSpec string) *AllocationBitmap { + a := AllocationBitmap{ + strategy: contiguousScanStrategy, + allocated: big.NewInt(0), + count: 0, + max: max, + rangeSpec: rangeSpec, + } + return &a +} + +// NewRandomAllocationInterface creates an allocation bitmap satisfying Interface using the +// random scan strategy. +func NewRandomAllocationInterface(max int, rangeSpec string) Interface { + return NewAllocationMap(max, rangeSpec) +} + +// NewContiguousAllocationInterface creates an allocation bitmap satisfying Interface using the +// contiguous scan strategy. +func NewContiguousAllocationInterface(max int, rangeSpec string) Interface { + return NewContiguousAllocationMap(max, rangeSpec) +} + // Allocate attempts to reserve the provided item. // Returns true if it was allocated, false if it was already in use func (r *AllocationBitmap) Allocate(offset int) (bool, error) { @@ -166,3 +191,16 @@ func randomScanStrategy(allocated *big.Int, max, count int) (int, bool) { } return 0, false } + +// contiguousScanStrategy tries to allocate starting at 0 and filling in any gaps +func contiguousScanStrategy(allocated *big.Int, max, count int) (int, bool) { + if count >= max { + return 0, false + } + for i := 0; i < max; i++ { + if allocated.Bit(i) == 0 { + return i, true + } + } + return 0, false +} diff --git a/pkg/registry/service/portallocator/allocator.go b/pkg/registry/service/portallocator/allocator.go index 72b34d4123e..448cfd623a2 100644 --- a/pkg/registry/service/portallocator/allocator.go +++ b/pkg/registry/service/portallocator/allocator.go @@ -151,8 +151,7 @@ func (r *PortAllocator) Restore(pr util.PortRange, data []byte) error { if !ok { return fmt.Errorf("not a snapshottable allocator") } - snapshottable.Restore(pr.String(), data) - return nil + return snapshottable.Restore(pr.String(), data) } // contains returns true and the offset if the port is in the range, and false