Skip to main content

sva_engine/cache/
stored.rs

1// Concern: what a lookup answers of a stored node: its meta and where its samples lie | Non-concern: reading those samples, the bytes (codec.rs) | IO: (identity, rate) -> key; Stored -> 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) samples: Samples,
21}
22
23#[derive(Clone, Debug, Default, PartialEq)]
24pub(crate) enum Samples {
25    #[default]
26    None,
27    /// Its `n` is the file's `n - shift`.
28    Entry {
29        file: Hash,
30        runs: Vec<Laid>,
31        shift: i64,
32    },
33    Staged {
34        chunks: Vec<(String, Extent)>,
35        shift: i64,
36    },
37    /// As written: sample `n` is `key`'s sample `n + by`.
38    Of { key: Hash, by: i64 },
39}
40
41#[derive(Clone, Debug, PartialEq)]
42pub(crate) struct Laid {
43    pub(crate) rate: u32,
44    pub(crate) start: i64,
45    pub(crate) width: usize,
46    pub(crate) len: usize,
47    /// Its first byte.
48    pub(crate) at: u64,
49    pub(crate) sums: Vec<u64>,
50}
51
52impl Laid {
53    pub(crate) fn extent(&self) -> Extent {
54        Extent::new(self.start, self.start + self.len as i64)
55    }
56}
57
58impl Stored {
59    pub(crate) fn extents(&self) -> Vec<Extent> {
60        let mut out: Vec<Extent> = match &self.samples {
61            Samples::None | Samples::Of { .. } => Vec::new(),
62            Samples::Entry { runs, shift, .. } => runs
63                .iter()
64                .map(|run| run.extent().shifted(*shift))
65                .collect(),
66            Samples::Staged { chunks, shift } => {
67                chunks.iter().map(|(_, e)| e.shifted(*shift)).collect()
68            }
69        };
70        out.sort_by_key(|e| e.start);
71        out
72    }
73
74    pub(crate) fn referring(self, key: Hash, by: i64) -> Stored {
75        let samples = Samples::Of { key, by };
76        Stored { samples, ..self }
77    }
78
79    pub(crate) fn file(&self) -> Option<(Hash, i64)> {
80        match self.samples {
81            Samples::Entry { file, shift, .. } => Some((file, shift)),
82            _ => None,
83        }
84    }
85
86    pub(crate) fn refers(&self) -> bool {
87        matches!(self.samples, Samples::Of { .. })
88    }
89
90    pub(crate) fn holds(&self, over: Extent) -> bool {
91        let mut from = over.start;
92        for part in self.extents() {
93            if from >= over.end || part.start > from {
94                break;
95            }
96            from = from.max(part.end);
97        }
98        from >= over.end
99    }
100}
101
102/// Keyed by its source's identity, the rate and the profile.
103pub(crate) fn node_key(identity: Hash, rate: u32, profile: &sva_samples::Profile) -> Hash {
104    super::mixed(
105        identity,
106        &[
107            u64::from(rate),
108            profile.precision_bits as u64,
109            profile.ceiling_hz.to_bits(),
110            0x6e_6f_64_65_00_00_00_01,
111        ],
112    )
113}