use super::r#use::Use;
use alloc::vec::Vec;
use orx_concurrent_ordered_bag::ConcurrentOrderedBag;
pub struct UseVec<T: Send, F: Fn(usize) -> T + Sync> {
init: F,
cache: ConcurrentOrderedBag<T>,
}
impl<T: Send, F: Fn(usize) -> T + Sync> UseVec<T, F> {
pub fn new(init: F) -> Self {
let cache = ConcurrentOrderedBag::new();
Self { init, cache }
}
pub fn into_vec(self) -> Vec<T> {
let vec = unsafe { self.cache.into_inner().unwrap_only_if_counts_match() };
vec.into_iter().collect()
}
}
impl<T: Send, F: Fn(usize) -> T + Sync> Use for UseVec<T, F> {
type Item = T;
unsafe fn init_get(&self, thread_idx: usize) -> &mut Self::Item {
let use_var = (self.init)(thread_idx);
unsafe { self.cache.set_value(thread_idx, use_var) };
unsafe { &mut *self.cache.ptr_mut(thread_idx) }
}
#[inline]
fn get(&mut self, thread_idx: usize) -> &mut Self::Item {
assert!(self.cache.len() > thread_idx);
unsafe { &mut *self.cache.ptr_mut(thread_idx) }
}
fn max_threads(&self) -> Option<usize> {
None
}
}
impl<T: Send, F: Fn(usize) -> T + Sync> Use for &mut UseVec<T, F> {
type Item = T;
unsafe fn init_get(&self, thread_idx: usize) -> &mut Self::Item {
let use_var = (self.init)(thread_idx);
unsafe { self.cache.set_value(thread_idx, use_var) };
unsafe { &mut *self.cache.ptr_mut(thread_idx) }
}
#[inline]
fn get(&mut self, thread_idx: usize) -> &mut Self::Item {
assert!(self.cache.len() > thread_idx);
unsafe { &mut *self.cache.ptr_mut(thread_idx) }
}
fn max_threads(&self) -> Option<usize> {
None
}
}