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: 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 identity: Hash,
10    pub label: Label,
11    pub width: u8,
12    pub codomain: Codomain,
13    pub rate: Option<u32>,
14    pub grid: Grid,
15    pub support: Extent,
16    /// The most seconds a read under it moved to land on a sample.
17    pub moved: f64,
18    pub readable: bool,
19    pub sampled: 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        file: Hash,
67        chunks: Vec<(String, Extent)>,
68        shift: i64,
69    },
70    /// As written: sample `n` is `key`'s sample `n + by`.
71    Of { key: Hash, by: i64 },
72}
73
74#[derive(Clone, Debug, PartialEq)]
75pub(crate) struct Laid {
76    pub(crate) rate: u32,
77    pub(crate) start: i64,
78    pub(crate) width: usize,
79    pub(crate) len: usize,
80    /// Its first byte.
81    pub(crate) at: u64,
82    pub(crate) sums: Vec<u64>,
83}
84
85impl Laid {
86    pub(crate) fn extent(&self) -> Extent {
87        Extent::new(self.start, self.start + self.len as i64)
88    }
89}
90
91impl Samples {
92    fn extents(&self) -> Vec<Extent> {
93        match self {
94            Samples::None | Samples::Of { .. } => Vec::new(),
95            Samples::Entry { runs, shift, .. } => runs
96                .iter()
97                .map(|run| run.extent().shifted(*shift))
98                .collect(),
99            Samples::Staged { chunks, shift, .. } => {
100                chunks.iter().map(|(_, e)| e.shifted(*shift)).collect()
101            }
102        }
103    }
104}
105
106impl Header {
107    pub(crate) fn new(stored: Stored, samples: Samples) -> Header {
108        let stored = stored.holding(samples.extents());
109        Header { stored, samples }
110    }
111
112    pub(crate) fn stored(&self) -> &Stored {
113        &self.stored
114    }
115
116    pub(crate) fn samples(&self) -> &Samples {
117        &self.samples
118    }
119
120    pub(crate) fn into_parts(self) -> (Stored, Samples) {
121        (self.stored, self.samples)
122    }
123
124    pub(crate) fn refers(&self) -> bool {
125        matches!(self.samples, Samples::Of { .. })
126    }
127}