Skip to main content

apple_quant_algorithmic/binned_method/
fixed.rs

1use std::{array, collections::BTreeMap};
2
3use smallvec::SmallVec;
4
5use crate::binned_method::{BinnedDataError, FixedSectorDef};
6
7/// Fixed collection of data binned by an index.
8pub 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(&sector[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(&sector_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(&sector_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}