Skip to main content

RangeAllocator

Struct RangeAllocator 

Source
pub struct RangeAllocator<T> { /* private fields */ }
Expand description

A best-fit range allocator over a generic index type T.

RangeAllocator manages a single contiguous range and hands out non-overlapping sub-ranges on request. Freed ranges are automatically merged with their neighbors.

§Example

use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..100);
let r = alloc.allocate_range(10).unwrap();
assert_eq!(r, 0..10);
alloc.free_range(r);

Implementations§

Source§

impl<T> RangeAllocator<T>
where T: Clone + Copy + Add<Output = T> + AddAssign + Sub<Output = T> + Eq + PartialOrd + Debug,

Source

pub fn new(range: Range<T>) -> Self

Creates a new allocator that manages the given range.

The entire range starts as free and available for allocation.

§Example
use range_alloc::RangeAllocator;

let alloc = RangeAllocator::new(0u32..1024);
assert!(alloc.is_empty());
Source

pub fn initial_range(&self) -> &Range<T>

Returns the full range this allocator was created with (including any extensions from grow_to).

Source

pub fn grow_to(&mut self, new_end: T)

Extends the allocator’s range to a new end value.

The newly added region (old_end..new_end) becomes available for allocation. If the last free range is adjacent to the old end, it is extended in place rather than creating a new entry.

§Example
use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..10);
alloc.allocate_range(10).unwrap();
// Out of space -- grow the pool.
alloc.grow_to(20);
let r = alloc.allocate_range(5).unwrap();
assert_eq!(r, 10..15);
Source

pub fn allocate_range( &mut self, length: T, ) -> Result<Range<T>, RangeAllocationError<T>>

Allocates a sub-range of the given length.

Uses a best-fit strategy: the smallest free range that can satisfy the request is chosen to minimise fragmentation.

§Panics

Panics if length is zero.

§Example
use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..100);
let a = alloc.allocate_range(30).unwrap();
let b = alloc.allocate_range(20).unwrap();
assert_eq!(a, 0..30);
assert_eq!(b, 30..50);
Source

pub fn allocate_range_aligned( &mut self, length: T, alignment: T, ) -> Result<Range<T>, RangeAllocationError<T>>
where T: Rem<Output = T>,

Allocates a sub-range of the given length whose start is aligned to a multiple of alignment.

Any space before the aligned start within a free range is kept free and available for future allocations – no space is wasted on alignment padding.

Uses the same best-fit strategy as allocate_range.

§Panics

Panics if length or alignment is zero.

§Example
use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..256);
// Offset the free region so the next aligned start is not at 0.
alloc.allocate_range(1).unwrap(); // 0..1

// Allocate 16 units starting at the next multiple of 16.
let r = alloc.allocate_range_aligned(16, 16).unwrap();
assert_eq!(r, 16..32);

// The gap (1..16) is still free and usable.
let small = alloc.allocate_range(15).unwrap();
assert_eq!(small, 1..16);
Source

pub fn free_range(&mut self, range: Range<T>)

Returns a previously allocated range to the free pool.

Adjacent free ranges are automatically merged to reduce fragmentation.

§Panics

Panics if range is outside the allocator’s initial range, is empty, or overlaps with an already-free range.

§Example
use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..10);
let r = alloc.allocate_range(10).unwrap();
alloc.free_range(r);
assert!(alloc.is_empty());
Source

pub fn allocated_ranges(&self) -> impl Iterator<Item = Range<T>> + '_

Returns an iterator over all currently allocated (non-free) ranges.

The ranges are yielded in ascending order.

§Example
use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..30);
alloc.allocate_range(10).unwrap(); // 0..10
alloc.allocate_range(10).unwrap(); // 10..20

// Adjacent allocations appear as a single contiguous range.
let allocated: Vec<_> = alloc.allocated_ranges().collect();
assert_eq!(allocated, vec![0..20]);
Source

pub fn reset(&mut self)

Frees all allocations, restoring the allocator to its initial state.

§Example
use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..10);
alloc.allocate_range(10).unwrap();
alloc.reset();
assert!(alloc.is_empty());
Source

pub fn is_empty(&self) -> bool

Returns true if nothing is currently allocated.

Source§

impl<T: Copy + Sub<Output = T> + Sum> RangeAllocator<T>

Source

pub fn total_available(&self) -> T

Returns the total length of all free ranges combined.

This may be spread across multiple non-contiguous ranges, so an allocation of this size is not guaranteed to succeed.

§Example
use range_alloc::RangeAllocator;

let mut alloc = RangeAllocator::new(0..100);
alloc.allocate_range(30).unwrap();
assert_eq!(alloc.total_available(), 70);

Trait Implementations§

Source§

impl<T: Debug> Debug for RangeAllocator<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for RangeAllocator<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for RangeAllocator<T>
where T: RefUnwindSafe,

§

impl<T> Send for RangeAllocator<T>
where T: Send,

§

impl<T> Sync for RangeAllocator<T>
where T: Sync,

§

impl<T> Unpin for RangeAllocator<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for RangeAllocator<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for RangeAllocator<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.