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 c.set(b)
47 }
48 }
49
50 fn logic(&self) -> &L {
51 &self.logic
52 }
53
54 unsafe fn get(&self, index: usize, backend: &mut L::Backend) {
55 debug_assert!(backend.as_ref().len() == self.logic.backend_len());
56 let offset = index * self.logic.backend_len();
57 for (b, c) in backend
58 .iter_mut()
59 .zip(self.backend.as_ref()[offset..].iter())
60 {
61 *b = c.get();
62 }
63 }
64
65 unsafe fn clear(&self) {
66 self.backend.as_ref().iter().for_each(|c| c.set(W::ZERO))
67 }
68
69 fn len(&self) -> usize {
70 self.backend.as_ref().len() / self.logic.backend_len()
71 }
72}
73
74impl<L: SliceEstimationLogic<W>, W, S: AsRef<[W]>> SliceEstimatorArray<L, W, S> {
75 #[inline(always)]
77 pub fn len(&self) -> usize {
78 let backend = self.backend.as_ref();
79 debug_assert!(backend.len() % self.logic.backend_len() == 0);
80 backend.len() / self.logic.backend_len()
81 }
82
83 #[inline(always)]
85 pub fn is_empty(&self) -> bool {
86 self.backend.as_ref().is_empty()
87 }
88}
89
90impl<L: SliceEstimationLogic<W> + Clone + Sync, W: Word, S: AsMut<[W]>> AsSyncArray<L>
91 for SliceEstimatorArray<L, W, S>
92{
93 type SyncEstimatorArray<'a>
94 = SyncSliceEstimatorArray<L, W, &'a [SyncCell<W>]>
95 where
96 Self: 'a;
97
98 fn as_sync_array(&mut self) -> SyncSliceEstimatorArray<L, W, &[SyncCell<W>]> {
99 SyncSliceEstimatorArray {
100 logic: self.logic.clone(),
101 backend: self.backend.as_mut().as_sync_slice(),
102 _marker: std::marker::PhantomData,
103 }
104 }
105}
106
107impl<L, W, S: AsRef<[W]>> AsRef<[W]> for SliceEstimatorArray<L, W, S> {
108 fn as_ref(&self) -> &[W] {
109 self.backend.as_ref()
110 }
111}
112
113impl<L, W, S: AsMut<[W]>> AsMut<[W]> for SliceEstimatorArray<L, W, S> {
114 fn as_mut(&mut self) -> &mut [W] {
115 self.backend.as_mut()
116 }
117}
118
119impl<L: SliceEstimationLogic<W>, W: Word> SliceEstimatorArray<L, W, Box<[W]>> {
120 pub fn new(logic: L, len: usize) -> Self {
126 let num_backend_len = logic.backend_len();
127 let backend = vec![W::ZERO; len * num_backend_len].into();
128 Self {
129 logic,
130 backend,
131 _marker: std::marker::PhantomData,
132 }
133 }
134}
135
136impl<L: SliceEstimationLogic<W> + Clone, W: Word, S: AsRef<[W]>> EstimatorArray<L>
137 for SliceEstimatorArray<L, W, S>
138{
139 type Estimator<'a>
140 = DefaultEstimator<L, &'a L, &'a [W]>
141 where
142 Self: 'a;
143
144 #[inline(always)]
145 fn get_backend(&self, index: usize) -> &L::Backend {
146 let offset = index * self.logic.backend_len();
147 &self.backend.as_ref()[offset..][..self.logic.backend_len()]
148 }
149
150 #[inline(always)]
151 fn logic(&self) -> &L {
152 &self.logic
153 }
154
155 #[inline(always)]
156 fn get_estimator(&self, index: usize) -> Self::Estimator<'_> {
157 DefaultEstimator::new(&self.logic, self.get_backend(index))
158 }
159
160 #[inline(always)]
161 fn len(&self) -> usize {
162 self.len()
163 }
164}
165
166impl<L: SliceEstimationLogic<W> + Clone, W: Word, S: AsRef<[W]> + AsMut<[W]>> EstimatorArrayMut<L>
167 for SliceEstimatorArray<L, W, S>
168{
169 type EstimatorMut<'a>
170 = DefaultEstimator<L, &'a L, &'a mut [W]>
171 where
172 Self: 'a;
173
174 #[inline(always)]
175 fn get_backend_mut(&mut self, index: usize) -> &mut L::Backend {
176 let offset = index * self.logic.backend_len();
177 &mut self.backend.as_mut()[offset..][..self.logic.backend_len()]
178 }
179
180 #[inline(always)]
181 fn get_estimator_mut(&mut self, index: usize) -> Self::EstimatorMut<'_> {
182 let logic = &self.logic;
183 let offset = index * self.logic.backend_len();
186 let backend = &mut self.backend.as_mut()[offset..][..self.logic.backend_len()];
187
188 DefaultEstimator::new(logic, backend)
189 }
190
191 #[inline(always)]
192 fn clear(&mut self) {
193 self.backend.as_mut().iter_mut().for_each(|v| *v = W::ZERO)
194 }
195}