apple_quant_algorithmic/binned_method/
fixed.rs1use std::{array, collections::BTreeMap};
2
3use smallvec::SmallVec;
4
5use crate::binned_method::{BinnedDataError, FixedSectorDef};
6
7pub struct FixedBinnedData<
9 T: Clone,
10 const SECTOR_DATA_COUNT: usize,
11> {
12 sectors: BTreeMap<u64, [Option<T>; SECTOR_DATA_COUNT]>,
13 last_sector_def: Option<FixedSectorDef>,
14}
15
16impl<
17 T: Clone,
18 const SECTOR_DATA_COUNT: usize,
19> FixedBinnedData<T, SECTOR_DATA_COUNT> {
20 pub fn last_sector_def(
21 &self,
22 ) -> &Option<FixedSectorDef> {
23 &self.last_sector_def
24 }
25
26 pub fn remove_last(
27 &mut self,
28 ) -> Result<Option<T>, BinnedDataError> {
29 let Some(
30 last_sector_def,
31 ) = self.last_sector_def else {
32 return Ok(None);
33 };
34
35 let sector = self.get_sector_mut(last_sector_def.sector_idx)?;
36
37 #[cfg(debug_assertions)]
38 if last_sector_def.data_idx >= SECTOR_DATA_COUNT {
39 return Err(BinnedDataError::SectorDataOutOfRange {
40 data_index: last_sector_def.data_idx,
41 sector_data_count: SECTOR_DATA_COUNT,
42 });
43 }
44
45 let Some(
46 data,
47 ) = sector[last_sector_def.data_idx].take() else {
48 return Err(BinnedDataError::InternalError);
49 };
50
51 if last_sector_def.data_idx == 0 {
52 if last_sector_def.sector_idx == 0 {
53 self.last_sector_def = None;
54 self.sectors.remove(&last_sector_def.sector_idx);
55
56 return Ok(Some(data));
57 }
58
59 if self.get_sector(last_sector_def.sector_idx - 1).is_err() {
60 self.last_sector_def = None;
61 self.sectors.remove(&last_sector_def.sector_idx);
62
63 return Ok(Some(data));
64 }
65
66 self.last_sector_def = Some(FixedSectorDef {
67 sector_idx: last_sector_def.sector_idx - 1,
68 data_idx: SECTOR_DATA_COUNT - 1,
69 });
70
71 self.sectors.remove(&last_sector_def.sector_idx);
72 return Ok(Some(data));
73 }
74
75 self.last_sector_def = Some(FixedSectorDef {
76 sector_idx: last_sector_def.sector_idx,
77 data_idx: last_sector_def.data_idx - 1,
78 });
79
80 Ok(Some(data))
81 }
82
83 pub fn append(
84 &mut self,
85 first_sector_idx: u64,
86 data: impl IntoIterator<Item = T>,
87 ) -> Result<(), ()> {
88 let data = data.into_iter();
89
90 let mut appending_sector_def = self.last_sector_def.unwrap_or(FixedSectorDef {
91 sector_idx: first_sector_idx / SECTOR_DATA_COUNT as u64,
92 data_idx: (first_sector_idx -
93 ((first_sector_idx / SECTOR_DATA_COUNT as u64) *
94 SECTOR_DATA_COUNT as u64)) as usize,
95 });
96
97 let mut sector = match self.get_sector_mut(appending_sector_def.sector_idx) {
98 Ok(
99 sector,
100 ) => sector,
101 Err(BinnedDataError::InvalidSector {
102 sector_idx: _,
103 }) => {
104 self.sectors.insert(
105 appending_sector_def.sector_idx,
106 array::from_fn(|_| None),
107 );
108
109 let Ok(
110 sector,
111 ) = self.get_sector_mut(
112 appending_sector_def.sector_idx,
113 ) else {
114 return Err(());
115 };
116
117 sector
118 },
119 Err(_) => unimplemented!(),
120 };
121
122 for next_data in data {
123 appending_sector_def.data_idx += 1;
124
125 if appending_sector_def.data_idx == SECTOR_DATA_COUNT {
126 appending_sector_def.data_idx = 0;
127 appending_sector_def.sector_idx += 1;
128
129 self.sectors.insert(
130 appending_sector_def.sector_idx,
131 array::from_fn(|_| None),
132 );
133
134 let Ok(
135 new_sector,
136 ) = self.get_sector_mut(
137 appending_sector_def.sector_idx,
138 ) else {
139 return Err(());
140 };
141
142 sector = new_sector;
143 }
144
145 sector[appending_sector_def.data_idx] = Some(next_data);
146 }
147
148 Ok(())
149 }
150
151 pub fn get(
152 &mut self,
153 index: usize,
154 ) -> Result<&Option<T>, BinnedDataError> {
155 let sector_id = index / SECTOR_DATA_COUNT;
156 let data_idx = index - (sector_id * SECTOR_DATA_COUNT);
157 let sector = self.get_sector_mut(sector_id as u64)?;
158
159 Ok(§or[data_idx])
160 }
161
162 pub fn iter(
163 &mut self,
164 min_idx: usize,
165 max_idx: usize,
166 ) -> Result<impl Iterator<Item = &Option<T>>, BinnedDataError> {
167 if max_idx < min_idx {
168 return Err(BinnedDataError::InvalidMinMax {
169 min: min_idx as u64,
170 max: max_idx as u64,
171 });
172 }
173
174 let Some(
175 last_sector_def,
176 ) = &self.last_sector_def else {
177 return Err(BinnedDataError::InternalError);
178 };
179
180 let iter_len = max_idx - min_idx + 1;
181 let mut data = SmallVec::<[&Option<T>; 1024]>::with_capacity(iter_len);
182 let mut last_idx = min_idx;
183
184 loop {
185 let sector_id = last_idx / SECTOR_DATA_COUNT;
186 let data_min_idx = last_idx - (sector_id * SECTOR_DATA_COUNT);
187 let mut data_max_idx = (sector_id + 1) * SECTOR_DATA_COUNT - 1;
188 let sector_id = sector_id as u64;
189
190 let Ok(
191 sector,
192 ) = self.get_sector(sector_id) else {
193 break;
194 };
195
196 if last_sector_def.sector_idx == sector_id as u64 {
197 data_max_idx = last_sector_def.data_idx;
198 }
199
200 data.extend(sector.iter().take(data_max_idx + 1).skip(data_min_idx));
201 last_idx = data_max_idx + 1;
202 }
203
204 Ok(data.into_iter())
205 }
206
207 fn get_sector(
208 &self,
209 sector_idx: u64,
210 ) -> Result<&[Option<T>; SECTOR_DATA_COUNT], BinnedDataError> {
211 if let Some(
212 sector,
213 ) = self.sectors.get(§or_idx) {
214 return Ok(sector);
215 }
216
217 Err(BinnedDataError::InvalidSector { sector_idx })
218 }
219
220 fn get_sector_mut(
221 &mut self,
222 sector_idx: u64,
223 ) -> Result<&mut [Option<T>; SECTOR_DATA_COUNT], BinnedDataError> {
224 if let Some(
225 sector,
226 ) = self.sectors.get_mut(§or_idx) {
227 return Ok(sector);
228 }
229
230 Err(BinnedDataError::InvalidSector { sector_idx })
231 }
232}
233
234impl<
235 T: Clone,
236 const SECTOR_DATA_COUNT: usize,
237> Default for FixedBinnedData<T, SECTOR_DATA_COUNT> {
238 fn default() -> Self {
239 Self {
240 sectors: BTreeMap::default(),
241 last_sector_def: None,
242 }
243 }
244}