Skip to main content

primase_core/pass/
memo.rs

1//! Optional memoization of pure pass work. The program supplies storage; core knows only keys and bytes.
2use std::sync::Arc;
3
4/// A content digest in an operation's versioned namespace. The producer owns the hashing contract.
5#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
6pub struct Key(pub [u8; 32]);
7
8/// Advisory storage for deterministic computations. A missing value or failed write costs recomputation only.
9/// Implementations verify stored bytes and account for storage failures; passes report hits and misses.
10pub trait Store: std::fmt::Debug + Send + Sync {
11    fn get(&self, key: &Key) -> Option<Vec<u8>>;
12    fn put(&self, key: &Key, value: &[u8]);
13}
14
15/// The run's caller-provided memo store (`core.pass_memo`). Absent: passes compute every result.
16/// Cloned worlds share this service, as they share other caller-provided execution services.
17///
18/// `build` is the program's statement of which code computed the entries: the primase revision it was built against.
19/// Passes mix it into every key, so a build with different code never reads another build's entries even when the
20/// pass's own version, options and inputs are unchanged. The library cannot know its revision; the program does.
21#[derive(Clone, Debug)]
22pub struct Memo {
23    pub store: Arc<dyn Store>,
24    pub build: String,
25}
26
27impl Memo {
28    /// A store and the build identity its entries are valid for. `build` must not be empty.
29    pub fn new(store: Arc<dyn Store>, build: impl Into<String>) -> Result<Self, String> {
30        let build = build.into();
31        if build.is_empty() {
32            return Err(
33                "a memo store needs the build identity (the primase revision) its entries are valid for"
34                    .into(),
35            );
36        }
37        Ok(Self { store, build })
38    }
39}
40
41impl crate::Resource for Memo {
42    const NAME: &'static str = "core.pass_memo";
43}