Skip to main content

apple_quant_algorithmic/binned_method/
flex.rs

1use std::collections::BTreeMap;
2
3use smallvec::SmallVec;
4
5use crate::binned_method::{BinnedDataError, FlexSectorDef, SectorDataIdx};
6
7/// Flexible collection of data binned by an index.
8pub struct FlexBinnedData<T: Ord> {
9	sectors: BTreeMap<u64, Vec<T>>,
10	last_sector_def: Option<FlexSectorDef>,
11}
12
13impl<T: Ord> FlexBinnedData<T> {
14	pub fn remove_last(
15		&mut self,
16	) -> Result<Option<T>, BinnedDataError> {
17		let Some(
18			last_sector_def,
19		) = self.last_sector_def else {
20			return Ok(None);
21		};
22
23		let sector = self.get_sector_mut(last_sector_def.sector_idx)?;
24
25		let Some(
26			data,
27		) = sector.pop() else {
28			return Err(BinnedDataError::InternalError);
29		};
30
31		if sector.is_empty() {
32			if last_sector_def.sector_idx == 0 {
33				self.last_sector_def = None;
34				self.sectors.remove(&last_sector_def.sector_idx);
35
36				return Ok(Some(data));
37			}
38
39			if self.get_sector(last_sector_def.sector_idx - 1).is_err() {
40				self.last_sector_def = None;
41				self.sectors.remove(&last_sector_def.sector_idx);
42
43				return Ok(Some(data));
44			}
45
46			self.last_sector_def = Some(FlexSectorDef {
47				sector_idx: last_sector_def.sector_idx - 1,
48			});
49
50			self.sectors.remove(&last_sector_def.sector_idx);
51			return Ok(Some(data));
52		}
53
54		Ok(Some(data))
55	}
56
57	pub fn insert_in_sector(
58		&mut self,
59		sector_idx: u64,
60		data: impl IntoIterator<Item = T>,
61	) -> Result<(), ()> {
62		let data = data.into_iter();
63
64		let appending_sector_def = self.last_sector_def.unwrap_or(FlexSectorDef {
65			sector_idx,
66		});
67
68		let sector = match self.get_sector_mut(appending_sector_def.sector_idx) {
69			Ok(
70				sector,
71			) => sector,
72			Err(BinnedDataError::InvalidSector {
73				sector_idx: _,
74			}) => {
75				self.sectors.insert(sector_idx, Vec::with_capacity(256));
76
77				let Ok(
78					sector,
79				) = self.get_sector_mut(sector_idx) else {
80					return Err(());
81				};
82
83				sector
84			},
85			Err(_) => unimplemented!(),
86		};
87
88		sector.extend(data);
89		sector.sort();
90
91		Ok(())
92	}
93
94	pub fn get_sector(
95		&self,
96		sector_idx: u64,
97	) -> Result<&Vec<T>, BinnedDataError> {
98		if let Some(
99			sector,
100		) = self.sectors.get(&sector_idx) {
101			return Ok(sector);
102		}
103
104		Err(BinnedDataError::InvalidSector { sector_idx })
105	}
106
107	fn get_sector_mut(
108		&mut self,
109		sector_idx: u64,
110	) -> Result<&mut Vec<T>, BinnedDataError> {
111		if let Some(
112			sector,
113		) = self.sectors.get_mut(&sector_idx) {
114			return Ok(sector);
115		}
116
117		Err(BinnedDataError::InvalidSector { sector_idx })
118	}
119
120	pub fn iter(
121		&self,
122		start_sector_idx: u64,
123		last_sector_idx: u64,
124		f_start_data: impl Fn(&T) -> bool,
125		f_last_data: impl Fn(&T) -> bool,
126	) -> Result<impl Iterator<Item = &T>, ()> {
127		let mut start_sector_ref_data_idx = None;
128
129		for sector_idx in start_sector_idx..=last_sector_idx {
130			let Ok(
131				start_sector,
132			) = self.get_sector(sector_idx) else {
133				continue;
134			};
135
136			let Some(
137				start_data_idx,
138			) = start_sector.iter().position(&f_start_data) else {
139				continue;
140			};
141
142			start_sector_ref_data_idx = Some(SectorDataIdx {
143				sector: start_sector,
144				sector_idx: sector_idx,
145				data_idx: start_data_idx,
146			});
147
148			break;
149		}
150
151		let mut last_sector_ref_data_idx = None;
152
153		for sector_idx in (start_sector_idx..=last_sector_idx).rev() {
154			let Ok(
155				last_sector,
156			) = self.get_sector(sector_idx) else {
157				continue;
158			};
159
160			let Some(
161				last_data_idx,
162			) = last_sector.iter().rposition(&f_last_data) else {
163				continue;
164			};
165
166			last_sector_ref_data_idx = Some(SectorDataIdx {
167				sector: last_sector,
168				sector_idx: sector_idx,
169				data_idx: last_data_idx,
170			});
171
172			break;
173		}
174
175		let mut sector_slices: SmallVec<[&[T]; 100]> = SmallVec::default();
176
177		if (
178			(start_sector_ref_data_idx.is_some() &&
179			last_sector_ref_data_idx.is_none()) ||
180			(start_sector_ref_data_idx.is_none() && last_sector_ref_data_idx.is_some())
181		) {
182			return Err(());
183		}
184
185		let Some(
186			start_sector_ref_data_idx,
187		) = start_sector_ref_data_idx else {
188			return Ok(sector_slices.into_iter().flatten());
189		};
190
191		let Some(
192			last_sector_ref_data_idx,
193		) = last_sector_ref_data_idx else {
194			return Ok(sector_slices.into_iter().flatten());
195		};
196
197		if last_sector_ref_data_idx.sector_idx < start_sector_ref_data_idx.sector_idx {
198			return Err(());
199		}
200
201		if start_sector_ref_data_idx.sector_idx == last_sector_ref_data_idx.sector_idx {
202			let sector = start_sector_ref_data_idx.sector;
203			let start_data_idx = start_sector_ref_data_idx.data_idx;
204			let last_data_idx = last_sector_ref_data_idx.data_idx;
205			let sector_slice = &sector[start_data_idx..=last_data_idx];
206
207			sector_slices.push(sector_slice);
208
209			return Ok(sector_slices.into_iter().flatten());
210		}
211
212		let start_sector_slice = &start_sector_ref_data_idx.sector[start_sector_ref_data_idx.data_idx..];
213
214		sector_slices.push(start_sector_slice);
215
216		// In between start and last sectors.
217		for sector_idx in (start_sector_ref_data_idx.sector_idx +
218			1)..last_sector_ref_data_idx.sector_idx
219		{
220			let Ok(
221				sector,
222			) = self.get_sector(sector_idx) else {
223				continue;
224			};
225
226			sector_slices.push(sector);
227		}
228
229		let last_sector_slice = &last_sector_ref_data_idx.sector[..last_sector_ref_data_idx.data_idx];
230
231		sector_slices.push(last_sector_slice);
232		Ok(sector_slices.into_iter().flatten())
233	}
234}
235
236impl<T: Ord> Default for FlexBinnedData<T> {
237	fn default() -> Self {
238		Self {
239			sectors: BTreeMap::default(),
240			last_sector_def: None,
241		}
242	}
243}