Browse Source

chore: more suitable data storage via fixed size arrays for our use case

Berke 1 năm trước cách đây
mục cha
commit
df52b0d9b8
1 tập tin đã thay đổi với 20 bổ sung32 xóa
  1. 20 32
      src/charts/heatmap.rs

+ 20 - 32
src/charts/heatmap.rs

@@ -11,8 +11,8 @@ use super::{Chart, CommonChartData, Message, chart_button, Interaction, AxisLabe
 
 #[derive(Debug, Clone, Default)]
 pub struct GroupedDepth {
-    pub bids: Vec<Order>, 
-    pub asks: Vec<Order>,
+    pub bids: Box<[Order]>,
+    pub asks: Box<[Order]>,
 }
 pub struct GroupedTrade {
     pub is_sell: bool,
@@ -30,7 +30,7 @@ struct QtyScale {
 
 pub struct HeatmapChart {
     chart: CommonChartData,
-    data_points: VecDeque<(i64, (GroupedDepth, Vec<GroupedTrade>))>,
+    data_points: VecDeque<(i64, (GroupedDepth, Box<[GroupedTrade]>))>,
     tick_size: f32,
     y_scaling: i32,
     size_filter: f32,
@@ -63,7 +63,7 @@ impl HeatmapChart {
         }
     }
 
-    fn group_by_price(&self, orders: &[Order], is_bid: bool) -> Vec<Order> {
+    fn group_by_price(&self, orders: &[Order], is_bid: bool) -> Box<[Order]> {
         let mut grouped: HashMap<i64, f32> = HashMap::new();
 
         for &order in orders {
@@ -140,6 +140,13 @@ impl HeatmapChart {
         self.render_start();
     }
 
+    fn visible_data_iter(
+        &self, 
+        earliest: i64, latest: i64
+    ) -> impl Iterator<Item = &(i64, (GroupedDepth, Box<[GroupedTrade]>))> {
+        self.data_points.iter().filter(move |(time, _)| *time >= earliest && *time <= latest)
+    }
+
     fn calculate_scales(&self) -> (i64, i64, f32, f32, QtyScale) {
         //let start = Instant::now();
 
@@ -156,38 +163,22 @@ impl HeatmapChart {
         let (autoscale, y_scaling) = (self.chart.autoscale, self.y_scaling as f32);
         let tick_size = self.tick_size;
 
-        for (time, (depth, _)) in self.data_points.iter() {
-            if *time < earliest || *time > latest {
-                continue;
-            }
-
+        for (_, (depth, _)) in self.visible_data_iter(earliest, latest) {
             let mid_price = (
-                depth.bids.last().map(|order| order.price).unwrap_or(0.0) 
+                depth.bids.last().map(|order| order.price).unwrap_or(0.0)
                 + depth.asks.first().map(|order| order.price).unwrap_or(0.0)
             ) / 2.0;
-
+    
             if autoscale {
-                highest = highest.max(
-                    mid_price + (100.0 * tick_size)
-                );
-                lowest = lowest.min(
-                    mid_price - (100.0 * tick_size)
-                );
+                highest = highest.max(mid_price + (100.0 * tick_size));
+                lowest = lowest.min(mid_price - (100.0 * tick_size));
             } else {
-                highest = highest.max(
-                    mid_price + (y_scaling * tick_size)
-                );
-                lowest = lowest.min(
-                    mid_price - (y_scaling * tick_size)
-                );
+                highest = highest.max(mid_price + (y_scaling * tick_size));
+                lowest = lowest.min(mid_price - (y_scaling * tick_size));
             }
         }
 
-        for (time, (depth, trades)) in self.data_points.iter() {
-            if *time < earliest || *time > latest {
-                continue;
-            }
-
+        for (_, (depth, trades)) in self.visible_data_iter(earliest, latest) {
             let (mut buy_volume, mut sell_volume) = (0.0, 0.0);
 
             for trade in trades.iter() {
@@ -653,10 +644,7 @@ impl canvas::Program<Message> for HeatmapChart {
 
             let mut prev_x_position: Option<f32> = None;
 
-            for (time, (depth, trades)) in self.data_points.iter() {
-                if *time < earliest || *time > latest {
-                    continue;
-                }
+            for (time, (depth, trades)) in self.visible_data_iter(earliest, latest) {
                 let x_position = ((time - earliest) as f32 / (latest - earliest) as f32) * bounds.width;
 
                 if x_position.is_nan() {