Skip to main content

Catalog

Struct Catalog 

Source
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>

Source

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 via Pager::set_root_catalog, and commits.
§Errors
  • Error::Corruption if an existing catalog’s reserved row is missing or malformed.
  • Pager / B-tree errors propagated as-is.
Source

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
Source

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
Source

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
Source

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::InvalidArgument if name is empty.
  • Error::Corruption if the descriptor’s collection_id disagrees with the catalog’s record (defensive check — indicates a caller bug).
  • Pager / B-tree / postcard errors propagated.
Source

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
Source

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 specs and absent from the descriptor are declared (new Active descriptor + empty B+tree).
  • Active descriptors absent from specs are flipped to DroppedPending.
  • 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
Source

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
Source

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
Source

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

Trait Implementations§

Source§

impl<F: Debug + FileBackend> Debug for Catalog<F>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<F> Freeze for Catalog<F>

§

impl<F> RefUnwindSafe for Catalog<F>

§

impl<F> Send for Catalog<F>

§

impl<F> Sync for Catalog<F>

§

impl<F> Unpin for Catalog<F>

§

impl<F> UnsafeUnpin for Catalog<F>

§

impl<F> UnwindSafe for Catalog<F>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V