1mod codec;
4mod index;
5pub(crate) mod log;
6mod memory;
7mod persist;
8mod stats;
9mod stored;
10mod tier;
11mod watch;
12
13pub use codec::STORE_FORMAT;
14pub use memory::{Counters, DEFAULT_CACHE_BYTES, DEFAULT_MARK_EVERY};
15pub(crate) use memory::{Facts, Keep, Known, Memory, Offered};
16pub use persist::{Backend, DEFAULT_STORE_BYTES, INDEX_NAME, Opening, Persisted, Store};
17pub(crate) use stats::Recording;
18pub use stats::{CacheStats, Lookup, Outcome, Tally};
19pub use stored::{Cut, Stored};
20pub use sva_formula::Hash;
21pub(crate) use tier::now;
22pub use tier::{FETCH_READS, Nothing, Tier};
23pub use watch::{
24 Boot, BootPhase, Call, CallStats, EngineStats, Gauge, Kind, Phase, Progress, StoreBoot, Typed,
25 Worked,
26};
27
28use std::collections::BTreeMap;
29use std::sync::Arc;
30
31use sva_samples::{Buffer, Frames, Grid, Label, MachineState, Profile, Rows};
32
33#[derive(Clone, Debug, PartialEq)]
36pub enum Payload {
37 Segments(Vec<Arc<Buffer>>),
38 Frames(Arc<Frames>),
39 Run(Arc<Run>),
40 Rows(Arc<Built>),
41}
42
43#[derive(Debug)]
46pub struct Built {
47 pub rows: Rows,
48 pub period: Option<i64>,
49}
50
51impl PartialEq for Built {
53 fn eq(&self, other: &Built) -> bool {
54 std::ptr::eq(self, other)
55 }
56}
57
58#[derive(Clone, Copy, Debug, PartialEq, Eq)]
59pub enum PayloadKind {
60 Segments,
61 Frames,
62 Run,
63 Rows,
64}
65
66#[derive(Clone)]
68pub struct Run {
69 pub samples: Arc<Buffer>,
70 pub marks: BTreeMap<i64, MachineState>,
71 pub parent: Option<Hash>,
72}
73
74impl Run {
75 pub fn end(&self) -> i64 {
76 self.samples.extent().end
77 }
78
79 pub fn bytes(&self) -> usize {
80 let marks: usize = self.marks.values().map(MachineState::bytes).sum();
81 self.samples.len() * self.samples.width() * size_of::<f64>() + marks
82 }
83}
84
85impl PartialEq for Run {
87 fn eq(&self, other: &Run) -> bool {
88 self.samples == other.samples
89 }
90}
91
92impl std::fmt::Debug for Run {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 f.debug_struct("Run")
95 .field("samples", &self.samples.extent())
96 .finish()
97 }
98}
99
100#[derive(Clone, Copy, Debug, PartialEq, Eq)]
102pub enum Expected {
103 Segments { rate: u32, width: usize },
104 Frames,
105 Run { rate: u32, width: usize },
106 Rows,
107}
108
109impl Expected {
110 pub(crate) fn kind(self) -> PayloadKind {
111 match self {
112 Expected::Segments { .. } => PayloadKind::Segments,
113 Expected::Frames => PayloadKind::Frames,
114 Expected::Run { .. } => PayloadKind::Run,
115 Expected::Rows => PayloadKind::Rows,
116 }
117 }
118}
119
120#[derive(Clone, Debug, PartialEq)]
121pub struct Entry {
122 pub payload: Payload,
123 pub label: Option<Label>,
125}
126
127impl Payload {
128 pub fn run(self) -> Option<Arc<Run>> {
129 match self {
130 Payload::Run(run) => Some(run),
131 _ => None,
132 }
133 }
134
135 pub fn kind(&self) -> PayloadKind {
136 match self {
137 Payload::Segments(_) => PayloadKind::Segments,
138 Payload::Frames(_) => PayloadKind::Frames,
139 Payload::Run(_) => PayloadKind::Run,
140 Payload::Rows(_) => PayloadKind::Rows,
141 }
142 }
143
144 pub fn bytes(&self) -> usize {
145 match self {
146 Payload::Segments(parts) => parts
147 .iter()
148 .map(|b| b.len() * b.width() * size_of::<f64>())
149 .sum(),
150 Payload::Frames(f) => f.width * f.frames * f.bins * 2 * size_of::<f64>(),
151 Payload::Run(run) => run.bytes(),
152 Payload::Rows(built) => built.rows.bytes(),
153 }
154 }
155
156 pub fn answers(&self, expected: Expected) -> bool {
157 match (self, expected) {
158 (Payload::Segments(parts), Expected::Segments { rate, width }) => {
159 parts.iter().all(|b| b.rate == rate && b.width() == width)
160 }
161 (Payload::Frames(_), Expected::Frames) | (Payload::Rows(_), Expected::Rows) => true,
162 (Payload::Run(run), Expected::Run { rate, width }) => {
163 run.samples.rate == rate && run.samples.width() == width
164 }
165 _ => false,
166 }
167 }
168}
169
170#[derive(Clone, Copy, Debug)]
171pub(crate) struct Question<'p> {
172 pub(crate) grid: Grid,
173 pub(crate) width: usize,
174 pub(crate) profile: &'p Profile,
175 pub(crate) shape: Shape,
176}
177
178#[derive(Clone, Copy, Debug, PartialEq, Eq)]
179pub(crate) enum Shape {
180 Samples,
181 Frames { window: usize, hop: usize },
182 Rows,
183}
184
185pub(crate) fn key(identity: Hash, question: &Question) -> Hash {
187 let Question {
188 grid,
189 width,
190 profile,
191 shape,
192 } = *question;
193 let asked = [
194 grid.a as u64,
195 grid.d as u64,
196 u64::from(grid.rate),
197 width as u64,
198 ];
199 let shape = match shape {
200 Shape::Samples => [0, 0, 0],
201 Shape::Frames { window, hop } => [1, window as u64, hop as u64],
202 Shape::Rows => [2, 0, 0],
203 };
204 let tag = [0x6b_65_79_00_00_00_00_01];
205 mixed(
206 identity,
207 &[&asked[..], &profile.deciding(), &shape, &tag].concat(),
208 )
209}
210
211pub(crate) fn mixed(seed: Hash, parts: &[u64]) -> Hash {
212 let mut hasher = sva_formula::ContentHasher::new(sva_formula::HashDomain::CacheAddress);
213 hasher.hash(seed);
214 for part in parts {
215 hasher.word(*part);
216 }
217 hasher.finish()
218}
219
220pub(crate) fn joined(parts: &mut Vec<Arc<Buffer>>, more: Vec<Arc<Buffer>>) {
223 for part in more {
224 parts.push(part);
225 }
226 parts.sort_by_key(|b| b.start);
227 let mut out: Vec<Arc<Buffer>> = Vec::with_capacity(parts.len());
228 for part in parts.drain(..) {
229 match out.last_mut() {
230 Some(last) if last.extent().end >= part.start => {
231 let from = (last.extent().end - part.start) as usize;
232 if from < part.len() {
233 let last = Arc::make_mut(last);
234 for (held, more) in last.planes.iter_mut().zip(&part.planes) {
235 held.extend_from_slice(&more[from.min(more.len())..]);
236 }
237 }
238 }
239 _ => out.push(part),
240 }
241 }
242 *parts = out;
243}