safe object array

This commit is contained in:
Janis 2023-04-18 01:06:50 +02:00
parent 3d3b1b20c9
commit 41dbc1bdd0

View file

@ -49,7 +49,7 @@ impl ObjectArrayItem {
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct ObjectArrayInner { pub struct ObjectArrayInner {
objects: *const *const ObjectArrayItem, objects: NonNull<Option<NonNull<ObjectArrayItem>>>,
pre_allocated_objects: Option<NonNull<ObjectArrayItem>>, pre_allocated_objects: Option<NonNull<ObjectArrayItem>>,
max_elements: u32, max_elements: u32,
num_elements: u32, num_elements: u32,
@ -60,13 +60,13 @@ pub struct ObjectArrayInner {
impl ObjectArrayInner { impl ObjectArrayInner {
const ELEMENTS_PER_CHUNK: usize = 64 * 1024; const ELEMENTS_PER_CHUNK: usize = 64 * 1024;
fn chunks_as_slice(&self) -> &[*const ObjectArrayItem] { fn chunks_as_slice(&self) -> &[Option<NonNull<ObjectArrayItem>>] {
unsafe { std::slice::from_raw_parts(self.objects, self.num_chunks as usize) } unsafe { std::slice::from_raw_parts(self.objects.as_ptr(), self.num_chunks as usize) }
} }
pub fn get_chunks(&self) -> Vec<&[ObjectArrayItem]> { pub fn get_chunks(&self) -> Vec<&[ObjectArrayItem]> {
(0..self.num_chunks as usize) (0..self.num_chunks as usize)
.map(|i| self.chunk_as_slice(i)) .filter_map(|i| self.chunk_as_slice(i))
.collect() .collect()
} }
@ -82,13 +82,12 @@ impl ObjectArrayInner {
} }
} }
fn chunk_as_slice(&self, chunk_index: usize) -> &[ObjectArrayItem] { fn chunk_as_slice(&self, chunk_index: usize) -> Option<&[ObjectArrayItem]> {
let chunks = self.chunks_as_slice(); let chunks = self.chunks_as_slice();
let chunk = unsafe { let chunk = unsafe {
std::slice::from_raw_parts( chunks[chunk_index].map(|ptr| {
chunks[chunk_index], std::slice::from_raw_parts(ptr.as_ptr(), self.get_chunk_size(chunk_index).unwrap())
self.get_chunk_size(chunk_index).unwrap(), })
)
}; };
chunk chunk
@ -107,10 +106,11 @@ impl ObjectArrayInner {
} }
pub fn get_index(&self, i: usize) -> Option<&ObjectArrayItem> { pub fn get_index(&self, i: usize) -> Option<&ObjectArrayItem> {
self.get_chunked_index(i) if let Some((chunk, within_chunk)) = self.get_chunked_index(i) {
.map(|(chunk_index, within_chunk_index)| { self.chunk_as_slice(chunk)?.get(within_chunk)
&self.chunk_as_slice(chunk_index)[within_chunk_index] } else {
}) None
}
} }
} }