apple_quant_algorithmic/hot/
fixed.rs1use std::{fmt::Debug, marker::PhantomData};
2
3use smallvec::SmallVec;
4
5use crate::{
6 aggregation::Aggregator,
7 instrument::{InstrumentData, InstrumentSpec},
8};
9
10#[derive(Debug)]
11pub struct FixedHotData<
12 'instrument_data,
13 'aggregated_data,
14 const COUNT: usize,
15 IS: InstrumentSpec,
16 AggregationData,
17 T: Aggregator<'instrument_data, 'aggregated_data, T, AggregationData, IS>
18 + 'aggregated_data
19 + Clone
20 + Debug,
21> {
22 data: SmallVec<[T; COUNT]>,
23
24 _aggregation_data: PhantomData<AggregationData>,
25 _instrument_spec: PhantomData<IS>,
26 _instrument_data: PhantomData<&'instrument_data ()>,
27 _a: PhantomData<&'aggregated_data ()>,
28}
29
30impl<
31 'instrument_data,
32 'aggregated_data,
33 const COUNT: usize,
34 IS: InstrumentSpec,
35 AggregationData,
36 T: Aggregator<'instrument_data, 'aggregated_data, T, AggregationData, IS>
37 + 'aggregated_data
38 + Clone
39 + Debug,
40> Default for FixedHotData<'instrument_data, 'aggregated_data, COUNT, IS, AggregationData, T>
41{
42 fn default() -> Self {
43 Self {
44 data: SmallVec::default(),
45
46 _aggregation_data: PhantomData::default(),
47 _instrument_spec: PhantomData::default(),
48 _instrument_data: PhantomData::default(),
49 _a: PhantomData::default(),
50 }
51 }
52}
53
54impl<
55 'instrument_data,
56 'aggregated_data,
57 const COUNT: usize,
58 IS: InstrumentSpec,
59 AggregationData,
60 T: Aggregator<'instrument_data, 'aggregated_data, T, AggregationData, IS>
61 + 'aggregated_data
62 + Clone
63 + Debug,
64> FixedHotData<'instrument_data, 'aggregated_data, COUNT, IS, AggregationData, T>
65{
66 pub fn len(&self) -> usize {
67 self.data.len()
68 }
69
70 pub fn capacity(&self) -> usize {
71 COUNT
72 }
73
74 pub fn is_empty(&self) -> bool {
75 self.data.is_empty()
76 }
77
78 pub fn clear(&mut self) {
79 self.data.clear();
80 }
81
82 pub fn remove_newest(&mut self) -> Option<T> {
83 self.data.pop()
84 }
85
86 pub fn newest(&self) -> Option<&T> {
87 self.data.last()
88 }
89
90 pub fn oldest(&self) -> Option<&T> {
91 self.data.first()
92 }
93
94 pub fn data_update(
95 &mut self,
96 instrument_data: &'instrument_data InstrumentData<'instrument_data, 'aggregated_data, IS>,
97 ) {
98 let aggregated_data: SmallVec<[T; 4]> = {
99 let aggregation_data = T::hot_data(
100 instrument_data,
101 self.iter_rev(),
102 );
103
104 T::aggregate_hot(&aggregation_data).collect()
105 };
106
107 self.append_manual(aggregated_data.into_iter());
108 }
109
110 pub fn append_manual(
111 &mut self,
112 append_data: impl ExactSizeIterator<Item = T>,
113 ) {
114 debug_assert!(self.data.len() <= COUNT);
115
116 let unused_capacity = COUNT - self.data.len();
117 let mut drain_count = append_data
118 .len()
119 .saturating_sub(unused_capacity)
120 .min(COUNT);
121
122 let data_skip_count = append_data
127 .len()
128 .saturating_sub(COUNT)
129 .min(COUNT);
130
131 drain_count = drain_count
132 .checked_sub(data_skip_count)
133 .unwrap();
134
135 self.data
141 .drain(0..drain_count);
142
143 self.data.extend(
144 append_data
145 .into_iter()
146 .take(COUNT)
147 .skip(data_skip_count),
148 );
149
150 debug_assert!(!self.data.spilled());
151 }
152
153 pub fn get(
154 &self,
155 idx: usize,
156 ) -> Option<&T> {
157 debug_assert!(idx < COUNT);
158
159 self.data.get(idx)
160 }
161
162 pub fn iter(&self) -> impl Iterator<Item = &T> {
163 self.data.iter()
164 }
165
166 pub fn iter_rev(&self) -> impl Iterator<Item = &T> + use<'_, COUNT, IS, AggregationData, T> {
167 self.data.iter().rev()
168 }
169
170 pub fn forward_slice_from<P: FnMut(&T) -> bool>(
171 &'aggregated_data self,
172 exclude: P,
173 ) -> &'aggregated_data [T] {
174 let Some(idx) = self
175 .data
176 .iter()
177 .rev()
178 .position(exclude)
179 else {
180 return &self.data;
181 };
182
183 let idx = idx + 1;
184
185 if idx >= self.data.len() {
186 return &self.data;
187 }
188
189 &self.data[idx..]
190 }
191
192 pub fn forward_slice(&'aggregated_data self) -> &'aggregated_data [T] {
193 &self.data
194 }
195}