pub trait Pointable<E> {
fn as_ptr(&self) -> *const E;
fn len(&self) -> usize;
}
impl<E> Pointable<E> for Vec<E> {
fn len(&self) -> usize {
self.len()
}
fn as_ptr(&self) -> *const E {
self.as_ptr()
}
}
impl<E> Pointable<E> for std::sync::Arc<Vec<E>> {
fn len(&self) -> usize {
self.as_ref().len()
}
fn as_ptr(&self) -> *const E {
self.as_ref().as_ptr()
}
}
pub trait MutPointable<E> {
fn as_mut_ptr(&mut self) -> *mut E;
fn len(&self) -> usize;
}
impl<E> MutPointable<E> for Vec<E> {
fn len(&self) -> usize {
self.len()
}
fn as_mut_ptr(&mut self) -> *mut E {
self.as_mut_ptr()
}
}
pub struct LockedMutPtrs<T, E>
where
T: MutPointable<E>,
{
data: Vec<T>,
pointers: Vec<*mut E>,
lens: Vec<u64>,
phantom: std::marker::PhantomData<E>,
}
impl<T, E> LockedMutPtrs<T, E>
where
T: MutPointable<E>,
{
pub fn new(mut v: Vec<T>) -> Self {
let mut pointers: Vec<*mut E> = vec![];
let mut lens = vec![];
for elem in v.iter_mut() {
pointers.push(elem.as_mut_ptr());
lens.push(elem.len() as u64);
}
Self { data: v, pointers, lens, phantom: std::marker::PhantomData }
}
pub unsafe fn swap_element(&mut self, idx: usize, elem: &mut T) -> Result<(), ()> {
if idx >= self.pointers.len() {
Err(())
} else {
if elem.len() == 0 {
return Err(());
}
std::mem::swap(&mut self.data[idx], elem);
self.pointers[idx] = self.data[idx].as_mut_ptr();
self.lens[idx] = self.data[idx].len() as u64;
Ok(())
}
}
#[inline]
pub fn len(&self) -> usize {
self.pointers.len()
}
#[inline]
pub fn element_len(&self, idx: usize) -> usize {
if idx >= self.data.len() {
return 0;
}
self.data[idx].len()
}
#[inline]
pub fn lens(&self) -> &[u64] {
self.lens.as_ref()
}
#[inline]
pub fn pointers(&self) -> &[*mut E] {
self.pointers.as_ref()
}
}
pub struct LockedPtrs<T, E>
where
T: Pointable<E>,
{
data: Vec<T>,
pointers: Vec<*const E>,
lens: Vec<u64>,
phantom: std::marker::PhantomData<E>,
}
impl<T, E> LockedPtrs<T, E>
where
T: Pointable<E>,
{
pub fn new(v: Vec<T>) -> Self {
let mut pointers: Vec<*const E> = vec![];
let mut lens = vec![];
for elem in v.iter() {
pointers.push(elem.as_ptr());
lens.push(elem.len() as u64);
}
Self { data: v, pointers, lens, phantom: std::marker::PhantomData }
}
pub unsafe fn swap_element(&mut self, idx: usize, elem: &mut T) -> Result<(), ()> {
if idx >= self.pointers.len() {
Err(())
} else {
if elem.len() == 0 {
return Err(());
}
std::mem::swap(&mut self.data[idx], elem);
self.pointers[idx] = self.data[idx].as_ptr();
self.lens[idx] = self.data[idx].len() as u64;
Ok(())
}
}
#[inline]
pub fn len(&self) -> usize {
self.pointers.len()
}
#[inline]
pub fn element_len(&self, idx: usize) -> usize {
if idx >= self.data.len() {
return 0;
}
self.data[idx].len()
}
#[inline]
pub fn lens(&self) -> &[u64] {
self.lens.as_ref()
}
#[inline]
pub fn pointers(&self) -> &[*const E] {
&self.pointers[..]
}
}