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