Line data Source code
1 : use std::time::SystemTime;
2 :
3 : use crate::tenant::{remote_timeline_client::index::IndexLayerMetadata, storage_layer::LayerName};
4 :
5 : use serde::{Deserialize, Serialize};
6 : use serde_with::{serde_as, DisplayFromStr, TimestampSeconds};
7 :
8 : use utils::{generation::Generation, id::TimelineId};
9 :
10 0 : #[derive(Serialize, Deserialize)]
11 : pub(super) struct HeatMapTenant {
12 : /// Generation of the attached location that uploaded the heatmap: this is not required
13 : /// for correctness, but acts as a hint to secondary locations in order to detect thrashing
14 : /// in the unlikely event that two attached locations are both uploading conflicting heatmaps.
15 : pub(super) generation: Generation,
16 :
17 : pub(super) timelines: Vec<HeatMapTimeline>,
18 : }
19 :
20 : #[serde_as]
21 0 : #[derive(Serialize, Deserialize)]
22 : pub(crate) struct HeatMapTimeline {
23 : #[serde_as(as = "DisplayFromStr")]
24 : pub(super) timeline_id: TimelineId,
25 :
26 : pub(super) layers: Vec<HeatMapLayer>,
27 : }
28 :
29 : #[serde_as]
30 0 : #[derive(Serialize, Deserialize)]
31 : pub(crate) struct HeatMapLayer {
32 : pub(super) name: LayerName,
33 : pub(super) metadata: IndexLayerMetadata,
34 :
35 : #[serde_as(as = "TimestampSeconds<i64>")]
36 : pub(super) access_time: SystemTime,
37 : // TODO: an actual 'heat' score that would let secondary locations prioritize downloading
38 : // the hottest layers, rather than trying to simply mirror whatever layers are on-disk on the primary.
39 : }
40 :
41 : impl HeatMapLayer {
42 0 : pub(crate) fn new(
43 0 : name: LayerName,
44 0 : metadata: IndexLayerMetadata,
45 0 : access_time: SystemTime,
46 0 : ) -> Self {
47 0 : Self {
48 0 : name,
49 0 : metadata,
50 0 : access_time,
51 0 : }
52 0 : }
53 : }
54 :
55 : impl HeatMapTimeline {
56 0 : pub(crate) fn new(timeline_id: TimelineId, layers: Vec<HeatMapLayer>) -> Self {
57 0 : Self {
58 0 : timeline_id,
59 0 : layers,
60 0 : }
61 0 : }
62 : }
63 :
64 : pub(crate) struct HeatMapStats {
65 : pub(crate) bytes: u64,
66 : pub(crate) layers: usize,
67 : }
68 :
69 : impl HeatMapTenant {
70 0 : pub(crate) fn get_stats(&self) -> HeatMapStats {
71 0 : let mut stats = HeatMapStats {
72 0 : bytes: 0,
73 0 : layers: 0,
74 0 : };
75 0 : for timeline in &self.timelines {
76 0 : for layer in &timeline.layers {
77 0 : stats.layers += 1;
78 0 : stats.bytes += layer.metadata.file_size;
79 0 : }
80 : }
81 :
82 0 : stats
83 0 : }
84 : }
|