commonlibsse_ng\re\b\BSTHashMap/
allocator.rs1use core::alloc::Layout;
2use core::{marker::PhantomData, ptr::NonNull};
3use core::{mem, ptr};
4
5use crate::re::MemoryManager::alloc::{alloc_zeroed, dealloc};
6
7use generic_array::{ArrayLength, GenericArray};
8use stdx::alloc::{AllocError, non_null_empty_slice};
9use typenum::{U2, op};
10
11pub trait Allocator {
14 unsafe fn allocate_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>;
22
23 unsafe fn deallocate(&mut self, ptr: NonNull<u8>, layout: Layout);
28
29 #[inline]
33 fn min_size() -> u32 {
34 1 << 3
35 }
36
37 fn get_entries(&self) -> *mut u8;
39
40 fn set_entries(&mut self, entries: *mut u8);
42}
43
44#[repr(C)]
49#[derive(Debug)]
50pub struct BSTScatterTableHeapAllocator {
51 pad00: u64,
53
54 entries: *mut u8,
56}
57
58impl Default for BSTScatterTableHeapAllocator {
59 #[inline]
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65impl BSTScatterTableHeapAllocator {
66 #[inline]
68 pub const fn new() -> Self {
69 Self { pad00: 0, entries: ptr::null_mut() }
70 }
71}
72
73impl Allocator for BSTScatterTableHeapAllocator {
74 unsafe fn allocate_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
80 debug_assert!(layout.size() % mem::size_of::<usize>() == 0, "Bytes must be aligned");
81
82 let ptr = unsafe { alloc_zeroed(layout) };
83 if ptr.is_null() {
84 return Err(AllocError);
85 }
86
87 self.entries = ptr;
88 Ok(match layout.size() {
89 0 => non_null_empty_slice(layout),
90 size => NonNull::slice_from_raw_parts(unsafe { NonNull::new_unchecked(ptr) }, size),
91 })
92 }
93
94 unsafe fn deallocate(&mut self, ptr: NonNull<u8>, layout: Layout) {
95 unsafe { dealloc(ptr.as_ptr(), layout) }
96 }
97
98 #[inline]
99 fn get_entries(&self) -> *mut u8 {
100 self.entries
101 }
102
103 #[inline]
104 fn set_entries(&mut self, entries: *mut u8) {
105 self.entries = entries;
106 }
107}
108
109#[repr(C)]
111#[derive(Debug)]
112pub struct BSTStaticHashMapBaseAllocator<N, A>
113where
114 N: ArrayLength,
115 U2: core::ops::Mul<N>,
116 A: ArrayLength,
117 op!(U2 * N): ArrayLength,
118{
119 buffer: GenericArray<u8, N>, entries: *mut u8, _align: PhantomData<A>, }
123
124impl<N, A> Default for BSTStaticHashMapBaseAllocator<N, A>
125where
126 N: ArrayLength,
127 U2: core::ops::Mul<N>,
128 A: ArrayLength,
129 op!(U2 * N): ArrayLength,
130{
131 #[inline]
132 fn default() -> Self {
133 Self::new()
134 }
135}
136
137impl<N, A> BSTStaticHashMapBaseAllocator<N, A>
138where
139 N: ArrayLength,
140 U2: core::ops::Mul<N>,
141 A: ArrayLength,
142 op!(U2 * N): ArrayLength,
143{
144 pub fn new() -> Self {
146 const {
147 assert!(N::USIZE > 0 && N::USIZE.is_power_of_two(), "N must be a power of two");
148 };
149
150 Self { buffer: GenericArray::default(), entries: ptr::null_mut(), _align: PhantomData }
151 }
152}
153
154impl<N, A> Allocator for BSTStaticHashMapBaseAllocator<N, A>
155where
156 N: ArrayLength,
157 A: ArrayLength,
158 U2: core::ops::Mul<N>,
159 op!(U2 * N): ArrayLength,
160{
161 #[inline]
163 fn min_size() -> u32 {
164 N::U32
165 }
166
167 #[inline]
172 unsafe fn allocate_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
173 let size = layout.size();
174 assert!(size % N::USIZE == 0, "Bytes must be aligned to S");
175
176 let len = self.buffer.len();
177 let Some(ptr) = NonNull::new(self.buffer.as_mut_ptr()) else {
178 return Err(AllocError);
179 };
180 if size <= len {
181 return Ok(match size {
182 0 => non_null_empty_slice(layout),
183 size => NonNull::slice_from_raw_parts(ptr, size),
184 });
185 }
186
187 Err(AllocError)
188 }
189
190 #[inline]
192 unsafe fn deallocate(&mut self, ptr: NonNull<u8>, _: Layout) {
193 assert!(ptr.as_ptr() == self.buffer.as_mut_ptr(), "Invalid pointer");
194 }
195
196 #[inline]
197 fn get_entries(&self) -> *mut u8 {
198 self.entries
199 }
200
201 #[inline]
202 fn set_entries(&mut self, entries: *mut u8) {
203 assert!(entries == self.buffer.as_mut_ptr() || entries.is_null());
204 self.entries = entries;
205 }
206}