Store
store
¶
Persistence of snapshots into the local store, and reads back out of it.
A snapshot is written under datasets/<dataset_id>/ as its full JSON
payload, a one-line append to log.jsonl, and an updated HEAD. The
three are written in that order so a crash never leaves HEAD
pointing at a snapshot that was not fully written. Re-tracking a source whose
recorded path matches an existing dataset's latest snapshot continues that
dataset's lineage rather than creating a new one.
The three writes are not a single atomic transaction, so two safeguards keep
readers consistent. A store-wide advisory lock serializes
the whole resolve-parent-then-write sequence, so concurrent writers cannot read
the same HEAD as their parent nor mint two datasets for one path. And
HEAD -- written last -- is the single source of truth for what is committed:
recovery and path matching read the log entry that HEAD names rather than
trusting the final line, so a log.jsonl left one entry ahead by a crash
between the append and the HEAD write is ignored.
Reading history back is therefore reachability-based, not positional.
read_log_entries returns every line a dataset's log holds, including
entries no HEAD ever named; walk_lineage then follows
parent_snapshot_id links back from HEAD to select the ones that are
actually committed. Neither "read every line" nor "read every line up to
HEAD" is correct: a crash between the append and the HEAD write leaves
an uncommitted entry behind, and the next successful write appends after it,
stranding it in the middle of the file rather than at the end. Only
reachability from HEAD tells the two apart.
Classes:
| Name | Description |
|---|---|
DatasetSummary |
A dataset in the store, described by its latest committed snapshot. |
LogEntry |
One snapshot as recorded in a dataset's |
SnapshotWriteResult |
Outcome of writing one snapshot into the store. |
Functions:
| Name | Description |
|---|---|
dataset_exists |
Return whether the store holds a dataset with this id. |
dataset_log_path |
Return the path of a dataset's |
list_dataset_ids |
Return the id of every dataset in the store, sorted. |
read_head |
Return the id of the snapshot a dataset's |
read_log_entries |
Return every entry in a dataset's |
walk_lineage |
Select the snapshots reachable from |
write_snapshot |
Write |
DatasetSummary(dataset_id, head)
dataclass
¶
LogEntry(snapshot_id, parent_snapshot_id, created_at, created_by, dataset_name, dataset_path, num_rows, num_columns)
dataclass
¶
One snapshot as recorded in a dataset's log.jsonl.
The lightweight per-snapshot record, mirroring
log fields rather than the full
snapshots/<snapshot_id>.json payload.
Every field except snapshot_id is optional. Log lines are written with
payload.get(key) (see write_snapshot),
so a snapshot built without a field records it as JSON null, and a line
written by a different version of dstrack may omit it entirely.
Attributes:
| Name | Type | Description |
|---|---|---|
snapshot_id |
str
|
Identifier of the snapshot. Always present: an entry is
only ever reached via |
parent_snapshot_id |
str | None
|
Snapshot this one succeeds, or |
created_at |
str | None
|
ISO-8601 UTC timestamp, kept as the raw recorded string. Deliberately not parsed here: an unparsable value is a display concern, not a reason to fail a read. |
created_by |
str | None
|
Recorded author, or |
dataset_name |
str | None
|
Human-readable name at snapshot time, or |
dataset_path |
str | None
|
POSIX path relative to the path root in force at
snapshot time, or |
num_rows |
int | None
|
Row count, or |
num_columns |
int | None
|
Column count, or |
SnapshotWriteResult(dataset_id, snapshot_id, snapshot_path, parent_snapshot_id, is_new_dataset)
dataclass
¶
Outcome of writing one snapshot into the store.
Attributes:
| Name | Type | Description |
|---|---|---|
dataset_id |
str
|
Dataset whose lineage the snapshot joined, whether it was passed in, matched by path, or minted by this write. |
snapshot_id |
str
|
Identifier of the snapshot that was written, copied from the snapshot payload. |
snapshot_path |
Path
|
Path of the written |
parent_snapshot_id |
str | None
|
Snapshot this one succeeds, i.e. the dataset's
|
is_new_dataset |
bool
|
Whether this write minted a new |
dataset_exists(dataset_id, *, store_root)
¶
Return whether the store holds a dataset with this id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
str
|
The dataset id, which may come from the user. |
required |
store_root
|
Path
|
Path to the |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
it has been snapshotted yet. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
dataset_log_path(dataset_id, *, store_root)
¶
Return the path of a dataset's log.jsonl. Need not exist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
str
|
Dataset whose log to locate. |
required |
store_root
|
Path
|
Path to the |
required |
Returns:
| Type | Description |
|---|---|
Path
|
The path of the dataset's append-only log. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
list_dataset_ids(*, store_root)
¶
Return the id of every dataset in the store, sorted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store_root
|
Path
|
Path to the |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
Each dataset's id, i.e. its directory name under |
list[str]
|
if the store holds no datasets yet. |
read_head(dataset_id, *, store_root)
¶
Return the id of the snapshot a dataset's HEAD names.
HEAD is the single source of truth for what a dataset has committed,
so callers that derive history from it should read it before reading
log.jsonl: a snapshot's log line is appended before the HEAD write
that names it, so any HEAD observed at a given moment is guaranteed to
have its whole ancestry already on disk. Reading them the other way round
can observe a HEAD naming a snapshot whose line was appended after the
log was read, which looks indistinguishable from corruption.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
str
|
Dataset whose |
required |
store_root
|
Path
|
Path to the |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
The latest committed snapshot's id, or |
str | None
|
not exist or has never been snapshotted. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
read_log_entries(dataset_id, *, store_root)
¶
Return every entry in a dataset's log.jsonl, in file order.
Includes entries that no HEAD ever named, so the result is what the
log says, not what the dataset has committed. Pass the result through
walk_lineage to select the committed
lineage.
A trailing line that is not valid JSON and is not newline-terminated is
treated as an interrupted append and dropped, not reported as corruption:
the log is appended to before HEAD moves, so a torn final line is a
snapshot that was never committed and is expected after a crash. A
malformed line anywhere else was written completely and is corruption.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
str
|
Dataset whose log to read. |
required |
store_root
|
Path
|
Path to the |
required |
Returns:
| Type | Description |
|---|---|
list[LogEntry]
|
One entry per log line, oldest first. Empty if the dataset does not |
list[LogEntry]
|
exist or has no log yet. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
StoreCorruptionError
|
If a complete log line is not a valid JSON
object, or records a |
OSError
|
If the log cannot be read. |
walk_lineage(index, head)
¶
Select the snapshots reachable from head, newest first.
Follows parent_snapshot_id links back from head, which is what
makes a history committed rather than merely recorded. Entries the
walk does not reach are ignored: a crash between a log append and the
HEAD write (see write_snapshot) leaves
an entry the store never committed, and a later successful write appends
after it, stranding it mid-file rather than at the end. Reachability is
the only thing that tells such an entry apart from a real snapshot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
Mapping[str, LogEntry]
|
Every entry the dataset's log holds, keyed by |
required |
head
|
str
|
Id of the snapshot to walk back from, i.e. the dataset's
|
required |
Returns:
| Type | Description |
|---|---|
list[LogEntry]
|
The lineage |
list[LogEntry]
|
snapshot with no parent. |
Raises:
| Type | Description |
|---|---|
StoreCorruptionError
|
If the lineage names a snapshot |
write_snapshot(snapshot, *, store_root, dataset_id=None)
¶
Write snapshot into the store and update the dataset's history.
Resolves which dataset the snapshot belongs to, then writes the full
payload, appends the lightweight log.jsonl line, and moves HEAD
onto the new snapshot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
snapshot
|
dict[str, Any]
|
A snapshot dict as produced by
SnapshotBuilder. Must contain
|
required |
store_root
|
Path
|
Path to the |
required |
dataset_id
|
str | None
|
Continue this dataset's lineage explicitly. The dataset must
already exist. When |
None
|
Returns:
| Type | Description |
|---|---|
SnapshotWriteResult
|
A SnapshotWriteResult describing |
SnapshotWriteResult
|
where the snapshot landed and which lineage it joined. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If |
ValueError
|
If |
DatasetNotFoundError
|
If |
StoreCorruptionError
|
If an existing dataset's |
OSError
|
If the store cannot be written to. |