Skip to main content

somatize_data/
lib.rs

1//! Where the data comes from, and what it is once it arrives.
2//!
3//! **A source is a node**, and there is no `Source` trait: a source takes
4//! something and answers with something, which is
5//! [`Node`](somatize_core::Node), and a second trait with a method that does
6//! what `forward` does is both a hole with one tenant and the `E0034` the rules
7//! warn about. Being a node is the point — `.at()`, `.cached()`, `.mapped()`,
8//! the record and the figure all reach a dataset with nothing written here.
9//!
10//! What the graph is handed is a **coordinate** and not a batch, because the
11//! input is the one value a cache hashes by content. Measured on 24 August 2026,
12//! release build, one node returning a constant so only the input grows:
13//!
14//! | what is handed to `forward` | with a store behind it |
15//! |---|---|
16//! | 1 MB of tensor | 6,1 ms |
17//! | 19 MB of tensor (32×3×224×224) | **121 ms**, every step, hit or miss |
18//! | a [`Span`] | **0,027 ms** |
19//!
20//! Nothing there is pathological — `torch.save` is 1 ms/MB and sha256 2 ms/MB —
21//! which is why the answer is not a faster hash.
22//!
23//! The other half of the name is the dataset's version, and a source has to
24//! state it **without reading itself**. Against a
25//! [`Store`](somatize_store::Store) that is free: a name resolves to a digest
26//! and the digest **is** the content hash, so [`Parquet::version`] costs one
27//! `resolve` and no bytes.
28//!
29//! Not here: **SQL**, decided rather than delayed, since every Rust driver worth
30//! using carries a runtime and `Store` is synchronous on purpose; and **ranged
31//! reads**, which need the store to learn to read a range first.
32
33mod frame;
34mod ipc;
35mod parquet;
36mod span;
37
38pub use frame::{Frame, FrameError};
39pub use ipc::Ipc;
40pub use parquet::{Parquet, ParquetError};
41pub use span::{Span, SpanError};