ipalloc

package
v1.15.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 11, 2024 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrFull       = errors.New("cannot allocate IP, no more IPs available")
	ErrOutOfRange = errors.New("the requested IP is out of the allocators range")
	ErrInUse      = errors.New("the requested IP is already allocated")
	ErrNotFound   = errors.New("the requested IP cannot be found")
	ErrBadLoop    = errors.New("allocator detected a potentially infinite loop and broke free")
)

Functions

func NewServiceAllocatorAdapter

func NewServiceAllocatorAdapter(alloc Allocator[bool]) ipallocator.Interface

NewServiceAllocatorAdapter creates a new ServiceAllocatorAdapter.

Types

type Allocator

type Allocator[T any] interface {
	// AllocAny allocates an available IP and associates value `val` to it. The caller has no control over the
	// exact IP that is allocated. The chosen IP is returned or error is non-nil.
	AllocAny(val T) (netip.Addr, error)

	// Alloc attempts to allocated the specific `ip` and associate value `val`. Allocation succeeded if the returned
	// error is nil.
	Alloc(ip netip.Addr, val T) error

	// Update updates the value `val` associated with the allocated `ip`.
	Update(ip netip.Addr, val T) error

	// Free de-allocates the given `ip` so its available once again.
	Free(ip netip.Addr) error

	// Get returns the value for the given `ip` if it has been allocated. Otherwise the default value for `T` is
	// returned. The boolean indicates if the `ip` has found.
	Get(ip netip.Addr) (T, bool)

	// ForEach calls `fn` for each allocated IP. The order of iteration is not guaranteed.
	// If `fn` return a non-nil error, the iteration is stopped and the error is returned.
	ForEach(fn func(addr netip.Addr, val T) error) error

	// Stats returns the number of IPs that have been allocated and the amount of IPs that are still
	// available for allocation.
	Stats() (allocated uint64, available *big.Int)

	// Range returns the start and stop IP of the allocator.
	Range() (from, to netip.Addr)
}

Allocator allocates IP addresses, `T` is the type of value associated with the IP. The associated value can be used to store metadata about the IP, such as owner, purpose, etc.

type HashAllocator

type HashAllocator[T any] struct {
	// contains filtered or unexported fields
}

HashAllocator is an IP allocator. This allocator stores ip-value pairs in a hash map, so memory usage grows proportionally to the amount of IPs allocated. The value type `T` is generic, larger types incur more memory usage. No artificial limits are placed on the range of the allocator other than inherent resource limits.

The allocator uses a custom datatype to keep track of available IP blocks. Its both a min heap and a linked list. Blocks are linked in IP space order to optimize for block-merge detection. The block heap order in the slice is from smallest to largest. Allocating arbitrary IPs will take from the smallest blocks to decrease the block amount over the long term to reduce memory usage and allocation time.

Due to this implementation, the AllocAny, Get, and Update methods are all O(1), these are expected to be the most commonly called methods. The Alloc and Free methods are O(n) where n is the amount of available blocks of IPs. So fragmented IP range utilization incurs more memory and cpu usage. These two are expected to be called way less since allocating specific IPs is assumed to be underutilized in k8s and freeing IPs will also be rare.

func NewHashAllocator

func NewHashAllocator[T any](start, stop netip.Addr, caphint int) (*HashAllocator[T], error)

NewHashAllocator creates a new IP allocator which will allocate IPs between `start` and `stop` including `start` and `stop`. The `start` IP should be lower then or equal to `stop`. The `caphint` is passed to the backing hashmap to save on map resizing when initial IP count is broadly known.

func (*HashAllocator[T]) Alloc

func (a *HashAllocator[T]) Alloc(ip netip.Addr, val T) error

Alloc attempts to allocated the specific `ip` and associate value `val`. Allocation succeeded if the returned error is nil.

func (*HashAllocator[T]) AllocAny

func (a *HashAllocator[T]) AllocAny(val T) (netip.Addr, error)

AllocAny allocates an available IP and associates value `val` to it. The caller has no control over the exact IP that is allocated. The chosen IP is returned or error is non-nil.

func (*HashAllocator[T]) ForEach

func (a *HashAllocator[T]) ForEach(fn func(addr netip.Addr, val T) error) error

func (*HashAllocator[T]) Free

func (a *HashAllocator[T]) Free(ip netip.Addr) error

Free de-allocates the given `ip` so its available once again.

func (*HashAllocator[T]) Get

func (a *HashAllocator[T]) Get(ip netip.Addr) (T, bool)

Get returns the value for the given `ip` if it has been allocated. Otherwise the default value for `T` is returned. The boolean indicates if the `ip` has found.

func (*HashAllocator[T]) Range

func (a *HashAllocator[T]) Range() (from, to netip.Addr)

Range returns the start and stop IP of the allocator.

func (*HashAllocator[T]) Stats

func (a *HashAllocator[T]) Stats() (allocated uint64, available *big.Int)

Stats returns the number of IPs that have been allocated and the amount of IPs that are still available for allocation.

func (*HashAllocator[T]) Update

func (a *HashAllocator[T]) Update(ip netip.Addr, val T) error

Update updates the value `val` associated with the allocated `ip`.

type ServiceAllocatorAdapter

type ServiceAllocatorAdapter struct {
	// contains filtered or unexported fields
}

ServiceAllocatorAdapter is an adapter that converts the Allocator[bool] interface to the ipallocator.Interface interface.

func (*ServiceAllocatorAdapter) Allocate

func (saa *ServiceAllocatorAdapter) Allocate(ip net.IP) error

Allocate allocates the given IP address.

func (*ServiceAllocatorAdapter) AllocateNext

func (saa *ServiceAllocatorAdapter) AllocateNext() (net.IP, error)

AllocateNext allocates the next available IP address.

func (*ServiceAllocatorAdapter) CIDR

func (saa *ServiceAllocatorAdapter) CIDR() net.IPNet

CIDR returns the best approximation of a CIDR of the IP range managed by this allocator. Some ranges can't be converted to an equal CIDR, so this CIDR should not be used for anything other than user feedback.

func (*ServiceAllocatorAdapter) ForEach

func (saa *ServiceAllocatorAdapter) ForEach(fn func(net.IP))

ForEach calls the given function for each allocated IP address.

func (*ServiceAllocatorAdapter) Has

func (saa *ServiceAllocatorAdapter) Has(ip net.IP) bool

Has returns true if the given IP address is allocated.

func (*ServiceAllocatorAdapter) Release

func (saa *ServiceAllocatorAdapter) Release(ip net.IP) error

Release releases the given IP address.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL