card_est_array/impls/
slice_estimator_array.rs1use super::DefaultEstimator;
9use crate::traits::*;
10use sux::traits::Word;
11use sync_cell_slice::{SyncCell, SyncSlice};
12
13pub struct SliceEstimatorArray<L, W, S> {
19 pub(super) logic: L,
20 pub(super) backend: S,
21 _marker: std::marker::PhantomData<W>,
22}
23
24pub struct SyncSliceEstimatorArray<L, W, S> {
26 pub(super) logic: L,
27 pub(super) backend: S,
28 _marker: std::marker::PhantomData<W>,
29}
30
31unsafe impl<L, W, S> Sync for SyncSliceEstimatorArray<L, W, S>
32where
33 L: Sync,
34 W: Sync,
35 S: Sync,
36{
37}
38
39impl<L: SliceEstimationLogic<W> + Sync, W: Word, S: AsRef<[SyncCell<W>]> + Sync>
40 SyncEstimatorArray<L> for SyncSliceEstimatorArray<L, W, S>
41{
42 unsafe fn set(&self, index: usize, content: &L::Backend) {
43 debug_assert!(content.as_ref().len() == self.logic.backend_len());
44 let offset = index * self.logic.backend_len();
45 for (c, &b) in self.backend.as_ref()[offset..].iter().zip(content.as_ref()) {
46 unsafe { c.set(b) }
48 }
49 }
50
51 fn logic(&self) -> &L {
52 &self.logic
53 }
54
55 unsafe fn get(&self, index: usize, backend: &mut L::Backend) {
56 debug_assert!(backend.as_ref().len() == self.logic.backend_len());
57 let offset = index * self.logic.backend_len();
58 for (b, c) in backend
59 .iter_mut()
60 .zip(self.backend.as_ref()[offset..].iter())
61 {
62 *b = unsafe { c.get() }
64 }
65 }
66
67 unsafe fn clear(&self) {
68 self.backend
69 .as_ref()
70 .iter()
71 .for_each(|c| unsafe { c.set(W::ZERO) })
72 }
73
74 fn len(&self) -> usize {
75 self.backend.as_ref().len() / self.logic.backend_len()
76 }
77}
78
79impl<L: SliceEstimationLogic<W>, W, S: AsRef<[W]>> SliceEstimatorArray<L, W, S> {
80 #[inline(always)]
82 pub fn len(&self) -> usize {
83 let backend = self.backend.as_ref();
84 debug_assert!(backend.len() % self.logic.backend_len() == 0);
85 backend.len() / self.logic.backend_len()
86 }
87
88 #[inline(always)]
90 pub fn is_empty(&self) -> bool {
91 self.backend.as_ref().is_empty()
92 }
93}
94
95impl<L: SliceEstimationLogic<W> + Clone + Sync, W: Word, S: AsMut<[W]>> AsSyncArray<L>
96 for SliceEstimatorArray<L, W, S>
97{
98 type SyncEstimatorArray<'a>
99 = SyncSliceEstimatorArray<L, W, &'a [SyncCell<W>]>
100 where
101 Self: 'a;
102
103 fn as_sync_array(&mut self) -> SyncSliceEstimatorArray<L, W, &[SyncCell<W>]> {
104 SyncSliceEstimatorArray {
105 logic: self.logic.clone(),
106 backend: self.backend.as_mut().as_sync_slice(),
107 _marker: std::marker::PhantomData,
108 }
109 }
110}
111
112impl<L, W, S: AsRef<[W]>> AsRef<[W]> for SliceEstimatorArray<L, W, S> {
113 fn as_ref(&self) -> &[W] {
114 self.backend.as_ref()
115 }
116}
117
118impl<L, W, S: AsMut<[W]>> AsMut<[W]> for SliceEstimatorArray<L, W, S> {
119 fn as_mut(&mut self) -> &mut [W] {
120 self.backend.as_mut()
121 }
122}
123
124impl<L: SliceEstimationLogic<W>, W: Word> SliceEstimatorArray<L, W, Box<[W]>> {
125 pub fn new(logic: L, len: usize) -> Self {
131 let num_backend_len = logic.backend_len();
132 let backend = vec![W::ZERO; len * num_backend_len].into();
133 Self {
134 logic,
135 backend,
136 _marker: std::marker::PhantomData,
137 }
138 }
139}
140
141impl<L: SliceEstimationLogic<W> + Clone, W: Word, S: AsRef<[W]>> EstimatorArray<L>
142 for SliceEstimatorArray<L, W, S>
143{
144 type Estimator<'a>
145 = DefaultEstimator<L, &'a L, &'a [W]>
146 where
147 Self: 'a;
148
149 #[inline(always)]
150 fn get_backend(&self, index: usize) -> &L::Backend {
151 let offset = index * self.logic.backend_len();
152 &self.backend.as_ref()[offset..][..self.logic.backend_len()]
153 }
154
155 #[inline(always)]
156 fn logic(&self) -> &L {
157 &self.logic
158 }
159
160 #[inline(always)]
161 fn get_estimator(&self, index: usize) -> Self::Estimator<'_> {
162 DefaultEstimator::new(&self.logic, self.get_backend(index))
163 }
164
165 #[inline(always)]
166 fn len(&self) -> usize {
167 self.len()
168 }
169}
170
171impl<L: SliceEstimationLogic<W> + Clone, W: Word, S: AsRef<[W]> + AsMut<[W]>> EstimatorArrayMut<L>
172 for SliceEstimatorArray<L, W, S>
173{
174 type EstimatorMut<'a>
175 = DefaultEstimator<L, &'a L, &'a mut [W]>
176 where
177 Self: 'a;
178
179 #[inline(always)]
180 fn get_backend_mut(&mut self, index: usize) -> &mut L::Backend {
181 let offset = index * self.logic.backend_len();
182 &mut self.backend.as_mut()[offset..][..self.logic.backend_len()]
183 }
184
185 #[inline(always)]
186 fn get_estimator_mut(&mut self, index: usize) -> Self::EstimatorMut<'_> {
187 let logic = &self.logic;
188 let offset = index * self.logic.backend_len();
191 let backend = &mut self.backend.as_mut()[offset..][..self.logic.backend_len()];
192
193 DefaultEstimator::new(logic, backend)
194 }
195
196 #[inline(always)]
197 fn clear(&mut self) {
198 self.backend.as_mut().iter_mut().for_each(|v| *v = W::ZERO)
199 }
200}