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