Skip to main content

FourTables

Struct FourTables 

Source
pub struct FourTables { /* private fields */ }
Expand description

Four Arrow IPC sections — oid, byte extent, type, size — joined by row ordinal.

This is git’s own shape: .idx, .rev and the missing type/size files, each an independent artifact. A lookup resolves the oid to an ordinal and then indexes three further sections at that ordinal.

The name counts sections, which is this arm’s whole difference from OneTableFourColumns. It carries five payload columns: delta_base joined the schema afterwards and shares the extent section, for the reason given on [extent_schema].

Implementations§

Source§

impl FourTables

Source

pub fn ipc_section_lens(&self) -> [usize; 4]

Section order: oid, extent, type, size.

Source

pub fn oid_column(&self) -> &FixedSizeBinaryArray

The oid column, straight out of its own section — proof that “four tables” still gives a contiguous scannable column.

Source

pub fn column_is_inside_ipc(&self) -> bool

Every column’s bytes lie inside the section they were decoded from.

Trait Implementations§

Source§

impl ObjectIndex for FourTables

Source§

fn build(entries: &[IndexEntry]) -> Result<Self>

Source§

fn lookup(&self, oid: &[u8]) -> Option<IndexRow>

Resolve one oid. None for an absent oid and for an oid of the wrong width.
Source§

fn lookup_batch(&self, oids: &[&[u8]]) -> Vec<Option<IndexRow>>

The batch path, and the one that matters: have negotiation sends up to 1000 oids at a time, the push connectivity check sends thousands. Positional — out[i] answers oids[i]. Read more
Source§

fn ordinals_batch(&self, oids: &[&[u8]]) -> Vec<Option<u32>>

oid → ordinal and stop. No payload column is touched at all. Read more
Source§

fn extents_batch(&self, oids: &[&[u8]]) -> Vec<Option<(u64, u64)>>

The partial-row access pattern: byte extent only, two of the five facts. This is extents(&[oid]), what the wire path actually asks for when it is about to copy bytes out of a pack.
Source§

fn sum_uncompressed(&self) -> u64

Full column scan: total uncompressed bytes over every object. The quota gate. Reads one 8-byte fact per row and nothing else.
Source§

fn count_type(&self, t: ObjType) -> usize

Full column scan with a predicate: how many objects of this type. Reads one byte per row and nothing else — the most column-shaped query there is, and the one a row-packed layout should lose worst.
Source§

fn name(&self) -> &'static str

Source§

fn oid_at(&self, ordinal: u32) -> Vec<u8> ⓘ

The raw oid at ordinal. Every arm keeps a FixedSizeBinary oid column, so this is one bounds-checked slice, copied out — owned rather than borrowed so that a stack holding its projection behind a lock can answer it too. Positional, like Arrow’s own value(i): an ordinal past len() (or, on a stack, a tail-tagged one) is a programming error and panics rather than answering.
Source§

fn entry_at(&self, ordinal: u32) -> IndexEntry

Every fact of the row at ordinal, as the entry that would rebuild it. The fold’s merge reads the projection back through this.
Source§

fn extent_at(&self, ordinal: u32) -> (u64, u64)

(offset, len) of the row at ordinal — positional, no oid, no allocation. The crash-recovery diff scans the whole projection through this, so it must cost a column read and nothing more.
Source§

fn oids_raw(&self) -> Vec<u8> ⓘ

Every oid, back to back, in ordinal order — len() × oid_len bytes. This IS the ordinal space the derived tables address (__gunnar_reach__ bitmaps, the commit graph’s token), and on a persisted arm it is the oid column’s own bytes: the thing objects.ordinal used to cache in a file of its own, with a header and an epoch to validate it, is a contiguous buffer this index already holds. The default is the positional loop; the columnar arms hand back their column.
Source§

fn len(&self) -> usize

Source§

fn ipc_bytes(&self) -> usize

Total bytes of Arrow IPC this index holds resident. Four sections or one, this counts the same payload, so it is comparable across arms.
Source§

fn resident_bytes(&self) -> usize

IPC bytes plus the stree oid section — everything the index keeps alive, excluding the handful of Arc’d schema/metadata allocations.
Source§

fn is_empty(&self) -> bool

Source§

fn persists() -> bool
where Self: Sized,

Whether this arm has a single-buffer form the stack can write down and read back with from_persisted. An arm that answers false is never persisted: the stack then keeps every row in redb and rebuilds from it, which is the pre-2026-09-04 behaviour, kept as a correct fallback rather than made an error. Read more
Source§

fn persisted_bytes(&self) -> Option<&[u8]>

The bytes this index is persisted as — one self-contained Arrow IPC stream holding one record batch, or None for an arm with no such form.
Source§

fn from_persisted(buf: Buffer) -> Result<Self>
where Self: Sized,

Reconstruct this index from a buffer persisted_bytes produced — typically a memory-mapped objects.index, so every array is a view into the page cache rather than a copy of it. Refuses a buffer this arm did not write (a different arm’s layout, a different format stamp).
Source§

fn entries(&self) -> Vec<IndexEntry>

All rows, in ordinal (= oid) order. len() allocations of oid, which is the price of handing build a slice; the fold pays it once per fold and nothing on the read path calls it.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more