89 lines
2.1 KiB
Rust
89 lines
2.1 KiB
Rust
use parking_lot::Mutex;
|
|
use shared::core::geometry::{Bounds2i, Point2i};
|
|
use shared::utils::containers::DeviceArray2D;
|
|
use std::collections::HashSet;
|
|
use std::hash::Hash;
|
|
use std::ops::{Deref, DerefMut};
|
|
use std::sync::Arc;
|
|
|
|
pub struct InternCache<T> {
|
|
cache: Mutex<HashSet<Arc<T>>>,
|
|
}
|
|
|
|
impl<T> InternCache<T>
|
|
where
|
|
T: Eq + Clone + Hash,
|
|
{
|
|
pub fn new() -> Self {
|
|
Self {
|
|
cache: Mutex::new(HashSet::new()),
|
|
}
|
|
}
|
|
|
|
pub fn lookup(&self, value: T) -> Arc<T> {
|
|
let mut lock = self.cache.lock();
|
|
|
|
if let Some(existing) = lock.get(&value) {
|
|
return existing.clone();
|
|
}
|
|
|
|
let new_item = Arc::new(value);
|
|
lock.insert(Arc::clone(&new_item));
|
|
new_item
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Array2D<T> {
|
|
pub device: DeviceArray2D<T>,
|
|
values: Vec<T>,
|
|
}
|
|
|
|
impl<T> Deref for Array2D<T> {
|
|
type Target = DeviceArray2D<T>;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.device
|
|
}
|
|
}
|
|
|
|
impl<T> DerefMut for Array2D<T> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.device
|
|
}
|
|
}
|
|
|
|
impl<T> Array2D<T> {
|
|
pub fn as_slice(&self) -> &[T] {
|
|
&self.values
|
|
}
|
|
|
|
fn from_vec(extent: Bounds2i, mut values: Vec<T>) -> Self {
|
|
let width = extent.p_max.x() - extent.p_min.x();
|
|
let device = DeviceArray2D {
|
|
extent,
|
|
values: values.as_mut_ptr().into(),
|
|
stride: width,
|
|
};
|
|
Self { device, values }
|
|
}
|
|
}
|
|
|
|
impl<T: Default + Clone> Array2D<T> {
|
|
pub fn new(extent: Bounds2i) -> Self {
|
|
let n = extent.area() as usize;
|
|
let storage = vec![T::default(); n];
|
|
Self::from_vec(extent, storage)
|
|
}
|
|
|
|
pub fn new_dims(nx: i32, ny: i32) -> Self {
|
|
let extent = Bounds2i::from_points(Point2i::new(0, 0), Point2i::new(nx, ny));
|
|
Self::new(extent)
|
|
}
|
|
|
|
pub fn new_filled(nx: i32, ny: i32, val: T) -> Self {
|
|
let extent = Bounds2i::from_points(Point2i::new(0, 0), Point2i::new(nx, ny));
|
|
let n = (nx * ny) as usize;
|
|
let storage = vec![val; n];
|
|
Self::from_vec(extent, storage)
|
|
}
|
|
}
|