use std::num::NonZeroU64;
use super::OutOfMemory;
#[derive(Debug, Clone)]
pub struct LinearAllocator {
block_size: u64,
cursor_offset: u64,
}
impl LinearAllocator {
pub fn new(block_size: u64) -> Self {
Self {
block_size,
cursor_offset: 0,
}
}
pub fn reset(&mut self) {
self.cursor_offset = 0;
}
pub fn space_free(&mut self) -> u64 {
self.block_size - self.cursor_offset
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LinearAllocation {
offset: u64,
size: u64,
}
impl super::Allocation for LinearAllocation {
fn offset(&self) -> u64 {
self.offset
}
fn size(&self) -> u64 {
self.size
}
}
impl super::Allocator for LinearAllocator {
type Allocation = LinearAllocation;
fn allocate(
&mut self,
size: std::num::NonZeroU64,
alignment: std::num::NonZeroU64,
) -> Result<Self::Allocation, OutOfMemory> {
self.cursor_offset += self.cursor_offset % alignment;
let size = size.get();
if size > self.space_free() {
Err(OutOfMemory)
} else {
self.cursor_offset += size;
Ok(LinearAllocation {
offset: self.cursor_offset - size,
size,
})
}
}
fn from_properties(_min_alloc: u64, capacity: NonZeroU64) -> Self {
Self::new(capacity.get())
}
}