pub struct Catalog<F: FileBackend = FileHandle> { /* private fields */ }Expand description
The catalog handle.
Owns the catalog B+tree’s root page-id; mutating methods take
&mut Pager<F> to advance the underlying B-tree through
copy-on-write.
Implementations§
Source§impl<F: FileBackend> Catalog<F>
impl<F: FileBackend> Catalog<F>
Sourcepub fn open_or_init(pager: &mut Pager<F>) -> Result<Self>
pub fn open_or_init(pager: &mut Pager<F>) -> Result<Self>
Open the catalog, creating it on first call.
Reads the file header’s root_catalog field via
Pager::root_catalog:
- If non-zero, attaches to the existing catalog B-tree and loads the next-collection-id watermark from the reserved row.
- If zero, allocates a fresh B+tree root, seeds the reserved
row with
1, persists the root viaPager::set_root_catalog, and commits.
§Errors
Error::Corruptionif an existing catalog’s reserved row is missing or malformed.- Pager / B-tree errors propagated as-is.
Sourcepub fn get(
&self,
pager: &mut Pager<F>,
name: &str,
) -> Result<Option<CollectionDescriptor>>
pub fn get( &self, pager: &mut Pager<F>, name: &str, ) -> Result<Option<CollectionDescriptor>>
Get the descriptor for the named collection. Returns
Ok(None) if no such collection exists.
§Errors
Error::InvalidArgumentifnameis empty.- Pager / B-tree / postcard errors propagated as-is.
Sourcepub fn lookup_via_snapshot(
pager: &Pager<F>,
snapshot: &ReaderSnapshot<F>,
name: &str,
) -> Result<Option<CollectionDescriptor>>
pub fn lookup_via_snapshot( pager: &Pager<F>, snapshot: &ReaderSnapshot<F>, name: &str, ) -> Result<Option<CollectionDescriptor>>
Look up a collection descriptor as-of a ReaderSnapshot’s
pinned LSN — i.e. observe the catalog state the reader’s
snapshot pinned, NOT the writer’s live Catalog.tree.root.
Walks the catalog B+tree rooted at snapshot.root_catalog()
(the value captured by Pager::reader_snapshot at pin time;
see M6 #51). Every page read goes through
ReaderSnapshot::read_page, which consults the snapshot’s
frozen WAL view first and falls through to the main file —
bypassing the live WAL overlay that may have been advanced by
a concurrent writer since pin time. This is the M6 #53 fix:
without it, a reader’s catalog descend can land on a freelist-
recycled page-id whose state.view contents are no longer a
valid B+tree node, surfacing as Error::Corruption { page_id: 0 } from the codec.
When snapshot.root_catalog() == 0 the catalog did not exist
at the snapshot’s pinned LSN; Ok(None) is returned and the
caller should surface that as Error::CollectionNotFound.
§Errors
Error::InvalidArgumentifnameis empty.Error::BTreeDepthExceededif the catalog B+tree exceedsMAX_BTREE_DEPTH(Rule 1 bound on the descend stack).Error::Corruption/Error::Codecpropagated from the snapshot read and postcard decode.
Sourcepub fn insert(
&mut self,
pager: &mut Pager<F>,
name: &str,
descriptor: CollectionDescriptor,
) -> Result<u32>
pub fn insert( &mut self, pager: &mut Pager<F>, name: &str, descriptor: CollectionDescriptor, ) -> Result<u32>
Register a new collection.
Allocates the next collection_id, sets it on descriptor,
re-persists the next-collection-id watermark, and inserts
the descriptor into the catalog B-tree. The descriptor that
the caller passes in has its collection_id field
ignored — the catalog assigns the canonical value.
Call Pager::commit after this to make the registration
durable.
§Errors
Error::InvalidArgumentifnameis empty.Error::CollectionAlreadyExistsifnameis already registered.Error::IdSpaceExhaustedif theu32collection_idspace is exhausted.- Pager / B-tree / postcard errors propagated.
Sourcepub fn update(
&mut self,
pager: &mut Pager<F>,
name: &str,
descriptor: &CollectionDescriptor,
) -> Result<()>
pub fn update( &mut self, pager: &mut Pager<F>, name: &str, descriptor: &CollectionDescriptor, ) -> Result<()>
Update an existing collection’s descriptor in place.
Used when next_id advances, type_version is bumped, or
secondary indexes change. The on-disk collection_id is
preserved across the update; callers should not change it.
§Errors
Error::InvalidArgumentifnameis empty.Error::Corruptionif the descriptor’scollection_iddisagrees with the catalog’s record (defensive check — indicates a caller bug).- Pager / B-tree / postcard errors propagated.
Sourcepub fn declare_index(
&mut self,
pager: &mut Pager<F>,
collection: &str,
spec: &IndexSpec,
) -> Result<u32>
pub fn declare_index( &mut self, pager: &mut Pager<F>, collection: &str, spec: &IndexSpec, ) -> Result<u32>
Declare a new secondary index on the named collection.
Allocates a fresh index_id, an empty index B+tree (M4),
and appends a new IndexDescriptor { status: Active } to
the collection’s indexes vector. The mutation rides inside
the caller’s WAL transaction; on rollback the descriptor +
the empty B+tree are both discarded.
spec is validated before any state mutation; an invalid
spec surfaces as Error::InvalidArgument before the
catalog touches the pager.
§Errors
Error::InvalidArgumentifspec.validate()rejects the spec.Error::CollectionNotFoundifcollectionis not registered.Error::IndexKindMismatchif anActivedescriptor of the same name has a different(kind, key_paths).Error::IdSpaceExhaustedonu32index_idwraparound (defense-in-depth — practically unreachable).- Pager / B-tree / postcard errors propagated.
Sourcepub fn reconcile_indexes(
&mut self,
pager: &mut Pager<F>,
collection: &str,
specs: &[IndexSpec],
) -> Result<Vec<IndexDescriptor>>
pub fn reconcile_indexes( &mut self, pager: &mut Pager<F>, collection: &str, specs: &[IndexSpec], ) -> Result<Vec<IndexDescriptor>>
Reconcile the runtime IndexSpec set for a collection
against the catalog’s stored descriptors.
- Specs present in
specsand absent from the descriptor are declared (newActivedescriptor + empty B+tree). Activedescriptors absent fromspecsare flipped toDroppedPending.- Matching
(name, kind, key_paths)pairs are left alone — reconciliation is idempotent.
Returns the descriptor’s post-reconciliation index roster (a
Vec<IndexDescriptor> clone) so the caller can build its
maintenance plan without re-querying the catalog.
§Errors
Error::IndexKindMismatch/Error::IndexKeyPathsMismatchon per-name structural disagreement.Error::IdSpaceExhaustedonu32index_idwraparound.- Pager / B-tree / postcard errors propagated.
Sourcepub fn drop_index(
&mut self,
pager: &mut Pager<F>,
collection: &str,
index_name: &str,
) -> Result<()>
pub fn drop_index( &mut self, pager: &mut Pager<F>, collection: &str, index_name: &str, ) -> Result<()>
Drop the named index from the named collection — flips the
descriptor’s status to IndexStatus::DroppedPending.
The descriptor stays in the catalog so its index_id is not
reused. The index B+tree pages are reclaimed on the next
Pager::checkpoint pass (deferred reclamation: a
concurrent reader’s snapshot may still need to walk the
pages until its pin is released).
§Errors
Error::CollectionNotFoundifcollectionis not registered.Error::IndexNotFoundifindex_nameis not a known descriptor on the collection.
Sourcepub fn next_id(&mut self, pager: &mut Pager<F>, name: &str) -> Result<Id>
pub fn next_id(&mut self, pager: &mut Pager<F>, name: &str) -> Result<Id>
Allocate the next Id for the named collection,
persisting the bumped next_id watermark inside the
catalog row.
Re-reads the descriptor, bumps next_id, writes the new
descriptor back via Catalog::update, and returns the
just-issued id.
The id-bump is staged through the WAL exactly like every
other catalog mutation; if the caller’s surrounding
transaction is later rolled back (no Pager::commit), the
allocation is rolled back with it — the next open will
re-issue the same id.
§Errors
Error::InvalidArgumentifnameis empty or not registered.Error::IdSpaceExhaustedonu64wraparound.- Pager / B-tree errors propagated.
Sourcepub fn list_collections(
&self,
pager: &mut Pager<F>,
) -> Result<Vec<(String, CollectionDescriptor)>>
pub fn list_collections( &self, pager: &mut Pager<F>, ) -> Result<Vec<(String, CollectionDescriptor)>>
List every registered collection.
Scans the full catalog B-tree. Bounded by
MAX_COLLECTIONS (Rule 2). The reserved next-collection-id
row is filtered out.
§Errors
Error::BTreeScanLimitExceededif the catalog has more thanMAX_COLLECTIONSentries.- Pager / B-tree / postcard errors propagated.