1use std::{
2 cell::UnsafeCell,
3 collections::HashMap,
4 mem::{self, MaybeUninit},
5 ptr,
6};
7
8use crate::join::Index;
9
10pub trait RawStorage {
19 type Item;
20
21 unsafe fn get(&self, index: Index) -> &Self::Item;
26
27 unsafe fn get_mut(&self, index: Index) -> &mut Self::Item;
36
37 unsafe fn insert(&mut self, index: Index, value: Self::Item);
42
43 unsafe fn remove(&mut self, index: Index) -> Self::Item;
48}
49
50pub trait DenseStorage: RawStorage {
53 fn as_slice(&self) -> &[Self::Item];
54 fn as_mut_slice(&mut self) -> &mut [Self::Item];
55}
56
57pub struct VecStorage<T>(Vec<UnsafeCell<MaybeUninit<T>>>);
58
59unsafe impl<T: Send> Send for VecStorage<T> {}
60unsafe impl<T: Sync> Sync for VecStorage<T> {}
61
62impl<T> Default for VecStorage<T> {
63 fn default() -> Self {
64 Self(Vec::new())
65 }
66}
67
68impl<T> RawStorage for VecStorage<T> {
69 type Item = T;
70
71 unsafe fn get(&self, index: Index) -> &T {
72 &*(*self.0.get_unchecked(index as usize).get()).as_ptr()
73 }
74
75 unsafe fn get_mut(&self, index: Index) -> &mut T {
76 &mut *(*self.0.get_unchecked(index as usize).get()).as_mut_ptr()
77 }
78
79 unsafe fn insert(&mut self, index: Index, c: T) {
80 let index = index as usize;
81 if self.0.len() <= index {
82 let delta = index + 1 - self.0.len();
83 self.0.reserve(delta);
84 self.0.set_len(index + 1);
85 }
86 *self.0.get_unchecked_mut(index as usize) = UnsafeCell::new(MaybeUninit::new(c));
87 }
88
89 unsafe fn remove(&mut self, index: Index) -> T {
90 ptr::read((*self.0.get_unchecked(index as usize).get()).as_mut_ptr())
91 }
92}
93
94pub struct DenseVecStorage<T> {
95 data: Vec<MaybeUninit<Index>>,
96 values: Vec<UnsafeCell<T>>,
97 indexes: Vec<Index>,
98}
99
100unsafe impl<T: Send> Send for DenseVecStorage<T> {}
101unsafe impl<T: Sync> Sync for DenseVecStorage<T> {}
102
103impl<T> Default for DenseVecStorage<T> {
104 fn default() -> Self {
105 Self {
106 data: Vec::new(),
107 values: Vec::new(),
108 indexes: Vec::new(),
109 }
110 }
111}
112
113impl<T> RawStorage for DenseVecStorage<T> {
114 type Item = T;
115
116 unsafe fn get(&self, index: Index) -> &T {
117 let dind = *self.data.get_unchecked(index as usize).as_ptr();
118 &*self.values.get_unchecked(dind as usize).get()
119 }
120
121 unsafe fn get_mut(&self, index: Index) -> &mut T {
122 let dind = *self.data.get_unchecked(index as usize).as_ptr();
123 &mut *self.values.get_unchecked(dind as usize).get()
124 }
125
126 unsafe fn insert(&mut self, index: Index, c: T) {
127 if self.data.len() <= index as usize {
128 let delta = index as usize + 1 - self.data.len();
129 self.data.reserve(delta);
130 self.data.set_len(index as usize + 1);
131 }
132 self.indexes.reserve(1);
133 self.values.reserve(1);
134
135 self.data
136 .get_unchecked_mut(index as usize)
137 .as_mut_ptr()
138 .write(self.values.len() as Index);
139 self.indexes.push(index);
140 self.values.push(UnsafeCell::new(c));
141 }
142
143 unsafe fn remove(&mut self, index: Index) -> T {
144 let dind = *self.data.get_unchecked(index as usize).as_ptr();
145 let last_index = *self.indexes.get_unchecked(self.indexes.len() - 1);
146 self.data
147 .get_unchecked_mut(last_index as usize)
148 .as_mut_ptr()
149 .write(dind);
150 self.indexes.swap_remove(dind as usize);
151 self.values.swap_remove(dind as usize).into_inner()
152 }
153}
154
155impl<T> DenseStorage for DenseVecStorage<T> {
156 fn as_slice(&self) -> &[Self::Item] {
157 unsafe { mem::transmute::<&[UnsafeCell<T>], &[T]>(&self.values) }
158 }
159
160 fn as_mut_slice(&mut self) -> &mut [Self::Item] {
161 unsafe { mem::transmute::<&mut [UnsafeCell<T>], &mut [T]>(&mut self.values) }
162 }
163}
164
165pub struct HashMapStorage<T>(HashMap<Index, UnsafeCell<T>>);
166
167unsafe impl<T: Send> Send for HashMapStorage<T> {}
168unsafe impl<T: Sync> Sync for HashMapStorage<T> {}
169
170impl<T> Default for HashMapStorage<T> {
171 fn default() -> Self {
172 Self(HashMap::default())
173 }
174}
175
176impl<T> RawStorage for HashMapStorage<T> {
177 type Item = T;
178
179 unsafe fn get(&self, index: Index) -> &T {
180 &*self.0.get(&index).unwrap().get()
181 }
182
183 unsafe fn get_mut(&self, index: Index) -> &mut T {
184 &mut *self.0.get(&index).unwrap().get()
185 }
186
187 unsafe fn insert(&mut self, index: Index, v: T) {
188 self.0.insert(index, UnsafeCell::new(v));
189 }
190
191 unsafe fn remove(&mut self, index: Index) -> T {
192 self.0.remove(&index).unwrap().into_inner()
193 }
194}