pub struct Index {
pub level: IndexLevel,
pub records: Vec<IndexRecord>,
pub child_counts: BTreeMap<PathBuf, usize>,
}Expand description
A built (or being-built) catalog for one IndexLevel, with both rendered
artifacts available. Pure data until written via Index::write_level.
Fields§
§level: IndexLevelWhich level this catalog is for.
records: Vec<IndexRecord>The complete record set for this level (type-folder level; empty for root/layer rollups, which carry only counts).
child_counts: BTreeMap<PathBuf, usize>Per-child counts for root/layer rollups (child path → file count).
Implementations§
Source§impl Index
impl Index
Sourcepub fn build_type_folder(store: &Store, type_folder: &Path) -> Result<Index>
pub fn build_type_folder(store: &Store, type_folder: &Path) -> Result<Index>
Build a type-folder catalog by aggregating across date-shards, producing
both artifacts. index.md selection is recency (updated desc, ties by
path asc; cap 500 with a ## More footer over the cap); index.jsonl
holds every file. A file missing summary gets a placeholder + a
validate-detectable issue (the index never invents summaries).
Sourcepub fn build_layer(store: &Store, layer: Layer) -> Result<Index>
pub fn build_layer(store: &Store, layer: Layer) -> Result<Index>
Build a layer catalog: every non-empty type-folder under the layer with
(N) counts and a newest-file summary preview (≤ 80 chars), plus the
loose records that live directly at the layer root (files with no
type-folder between them and the layer). The type-folder rollup is the
index.md; the loose records are the layer’s own index.jsonl (so
structured reads — query, dedup, graph — see a loose file the same
way they see a canonical one). A layer with no loose files carries no
index.jsonl, so existing stores are byte-unchanged.
Sourcepub fn build_root(store: &Store) -> Result<Index>
pub fn build_root(store: &Store) -> Result<Index>
Build the store-wide root catalog: one heading per non-empty layer with
total count + bulleted per-type sub-entries with (N) counts.
Sourcepub fn to_markdown(&self) -> String
pub fn to_markdown(&self) -> String
Render this catalog as a canonical index.md.
Sourcepub fn to_jsonl(&self) -> String
pub fn to_jsonl(&self) -> String
Render this catalog’s records as the complete index.jsonl (one JSON
object per file, stable key order so diffs stay minimal). Used at the
type-folder level for its files, and at the layer level for the loose
files that live directly at the layer root. The root rollup carries no
records, so it never produces a jsonl.
Source§impl Index
impl Index
Sourcepub fn on_write(store: &Store, file: &Path) -> Result<()>
pub fn on_write(store: &Store, file: &Path) -> Result<()>
Write-through (loop, O(changed)). Upsert a new/updated content file.
Reads the affected type-folder’s index.jsonl (the sanctioned per-folder
sidecar read — never a whole-store walk), applies the change, and
atomically rewrites that folder’s index.md + index.jsonl plus the
parent layer + root rollups so the artifacts equal a rebuild_all over
the same end state.
Sourcepub fn on_rename(store: &Store, old: &Path, new: &Path) -> Result<()>
pub fn on_rename(store: &Store, old: &Path, new: &Path) -> Result<()>
Write-through (loop, O(changed)). Move a file’s entry between
type-folder indexes (or within, if the same folder) in both index.md
and index.jsonl, fixing counts on both sides.
Sourcepub fn on_remove(store: &Store, file: &Path) -> Result<()>
pub fn on_remove(store: &Store, file: &Path) -> Result<()>
Write-through (loop, O(changed)). Drop a file’s entry from both
index.md and index.jsonl; decrement counts; if the browse view drops
below the cap, the next-most-recent is already present in the complete
jsonl record set and re-renders into the md automatically.
Sourcepub fn rebuild_all(store: &Store) -> Result<()>
pub fn rebuild_all(store: &Store) -> Result<()>
SWEEP repair. Walk the store once and atomically (re)write root +
every non-empty layer + every non-empty type-folder index.md and
index.jsonl (compacting the jsonl). Also runs Index::cleanup.
Sourcepub fn rebuild_folder(store: &Store, folder: &Path) -> Result<()>
pub fn rebuild_folder(store: &Store, folder: &Path) -> Result<()>
Rebuild ONE type-folder’s index.md/index.jsonl from a fresh walk, then
cascade the new child count up to the layer and root rollups — so a
scoped dbmd index rebuild --folder leaves the hierarchy consistent,
exactly like rebuild_all and the loop-path on_write already do.
(Writing only the folder, as the CLI used to, left stale layer/root
counts that validate would then flag as an index desync.)
Sourcepub fn write_level(store: &Store, level: &IndexLevel) -> Result<()>
pub fn write_level(store: &Store, level: &IndexLevel) -> Result<()>
Atomically write a single level’s artifact(s) to disk.
Sourcepub fn render_dry_run(store: &Store, level: &IndexLevel) -> Result<String>
pub fn render_dry_run(store: &Store, level: &IndexLevel) -> Result<String>
Render the generated indexes to a string with --- <path> ---
separators instead of writing them (--dry-run).
Sourcepub fn cleanup(store: &Store) -> Result<()>
pub fn cleanup(store: &Store) -> Result<()>
Cleanup pass (part of Index::rebuild_all): delete index.md /
index.jsonl in non-canonical folders (date-shards that should carry
none). Symmetric with index creation.
Only deletes generated catalog artifacts, never user content. Two guards keep this from eating data:
min_depth(2)so the walk starts below the type-folder root — the canonical<type-folder>/index.md+index.jsonlare never targeted here (they are rewritten by the per-folder builders, or removed only when the folder is genuinely empty, in the dedicated branch below). The oldmin_depth(1)deleted them up front, so a rebuild aborted by one malformed file left every type-folder catalog destroyed.- [
is_deletable_catalog_artifact] confirms a shard-levelindex.mdis an actual generated catalog (or stale/garbage leftover), NOT a content file a user wrote at that name (e.g.dbmd write …/index.md --type email, plausible when mirroring a website/doc export). Matching by filename alone silently deleted such records on the next rebuild.