Skip to main content

sva_engine/cache/
stored.rs

1// Concern: what the tier answers of a node, and where a disk entry lays its samples | Non-concern: reading them, the bytes (codec.rs) | IO: (identity, rate) -> key; Header -> extents
2
3use sva_formula::{Codomain, Hash};
4use sva_samples::{Extent, Grid, Label};
5
6#[derive(Clone, Debug, PartialEq)]
7pub struct Stored {
8    pub key: Hash,
9    pub label: Label,
10    pub width: u8,
11    pub codomain: Codomain,
12    pub rate: Option<u32>,
13    pub grid: Grid,
14    pub support: Extent,
15    /// Flops it and all under it cost.
16    pub priced: u128,
17    /// The most seconds a read under it moved to land on a sample.
18    pub moved: f64,
19    pub readable: bool,
20    pub(crate) held: Vec<Extent>,
21}
22
23impl Stored {
24    pub(crate) fn extents(&self) -> &[Extent] {
25        &self.held
26    }
27
28    pub(crate) fn holds(&self, over: Extent) -> bool {
29        let mut from = over.start;
30        for part in &self.held {
31            if from >= over.end || part.start > from {
32                break;
33            }
34            from = from.max(part.end);
35        }
36        from >= over.end
37    }
38
39    pub(crate) fn holding(&self, mut held: Vec<Extent>) -> Stored {
40        held.sort_by_key(|e| e.start);
41        Stored {
42            held,
43            ..self.clone()
44        }
45    }
46}
47
48/// Only the disk tier and the memory tier read a layout. What it holds is its layout's alone.
49#[derive(Clone, Debug, PartialEq)]
50pub(crate) struct Header {
51    stored: Stored,
52    samples: Samples,
53}
54
55#[derive(Clone, Debug, Default, PartialEq)]
56pub(crate) enum Samples {
57    #[default]
58    None,
59    /// Its `n` is the file's `n - shift`.
60    Entry {
61        file: Hash,
62        runs: Vec<Laid>,
63        shift: i64,
64    },
65    Staged {
66        chunks: Vec<(String, Extent)>,
67        shift: i64,
68    },
69    /// As written: sample `n` is `key`'s sample `n + by`.
70    Of { key: Hash, by: i64 },
71}
72
73#[derive(Clone, Debug, PartialEq)]
74pub(crate) struct Laid {
75    pub(crate) rate: u32,
76    pub(crate) start: i64,
77    pub(crate) width: usize,
78    pub(crate) len: usize,
79    /// Its first byte.
80    pub(crate) at: u64,
81    pub(crate) sums: Vec<u64>,
82}
83
84impl Laid {
85    pub(crate) fn extent(&self) -> Extent {
86        Extent::new(self.start, self.start + self.len as i64)
87    }
88}
89
90impl Samples {
91    fn extents(&self) -> Vec<Extent> {
92        match self {
93            Samples::None | Samples::Of { .. } => Vec::new(),
94            Samples::Entry { runs, shift, .. } => runs
95                .iter()
96                .map(|run| run.extent().shifted(*shift))
97                .collect(),
98            Samples::Staged { chunks, shift } => {
99                chunks.iter().map(|(_, e)| e.shifted(*shift)).collect()
100            }
101        }
102    }
103}
104
105impl Header {
106    pub(crate) fn new(stored: Stored, samples: Samples) -> Header {
107        let stored = stored.holding(samples.extents());
108        Header { stored, samples }
109    }
110
111    pub(crate) fn stored(&self) -> &Stored {
112        &self.stored
113    }
114
115    pub(crate) fn samples(&self) -> &Samples {
116        &self.samples
117    }
118
119    pub(crate) fn into_parts(self) -> (Stored, Samples) {
120        (self.stored, self.samples)
121    }
122
123    pub(crate) fn refers(&self) -> bool {
124        matches!(self.samples, Samples::Of { .. })
125    }
126}
127
128/// Keyed by its source's identity, the rate and the profile.
129pub(crate) fn node_key(identity: Hash, rate: u32, profile: &sva_samples::Profile) -> Hash {
130    super::mixed(
131        identity,
132        &[
133            u64::from(rate),
134            profile.precision_bits as u64,
135            profile.ceiling_hz.to_bits(),
136            0x6e_6f_64_65_00_00_00_01,
137        ],
138    )
139}