1use std::num::NonZeroU64;
2
3use super::OutOfMemory;
4
5#[derive(Debug, Clone)]
11pub struct LinearAllocator {
12 block_size: u64,
14 cursor_offset: u64,
16}
17
18impl LinearAllocator {
19 pub fn new(block_size: u64) -> Self {
20 Self {
21 block_size,
22 cursor_offset: 0,
23 }
24 }
25
26 pub fn reset(&mut self) {
29 self.cursor_offset = 0;
30 }
31
32 pub fn space_free(&mut self) -> u64 {
34 self.block_size - self.cursor_offset
35 }
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
40pub struct LinearAllocation {
41 offset: u64,
42 size: u64,
43}
44
45impl super::Allocation for LinearAllocation {
46 fn offset(&self) -> u64 {
47 self.offset
48 }
49
50 fn size(&self) -> u64 {
51 self.size
52 }
53}
54
55impl super::Allocator for LinearAllocator {
56 type Allocation = LinearAllocation;
57
58 fn allocate(
60 &mut self,
61 size: std::num::NonZeroU64,
62 alignment: std::num::NonZeroU64,
63 ) -> Result<Self::Allocation, OutOfMemory> {
64 self.cursor_offset += self.cursor_offset % alignment;
66
67 let size = size.get();
68 if size > self.space_free() {
69 Err(OutOfMemory)
72 } else {
73 self.cursor_offset += size;
74 Ok(LinearAllocation {
75 offset: self.cursor_offset - size,
76 size,
77 })
78 }
79 }
80
81 fn from_properties(_min_alloc: u64, capacity: NonZeroU64) -> Self {
82 Self::new(capacity.get())
83 }
84}