Skip to main content

NodeTable

Struct NodeTable 

Source
pub struct NodeTable {
    pub table_id: u64,
    pub name: String,
    pub columns: Vec<ColumnDefinition>,
    pub primary_key_column: usize,
    pub num_rows: u64,
    pub node_groups: Vec<NodeGroup>,
    pub hash_index: HashIndex<String>,
    pub art_index: Option<ArtPrimaryKeyIndex>,
    pub persistence_dirty: bool,
    /* private fields */
}
Expand description

A node table stores properties for a node label using NodeGroup-based columnar storage. Data is held in-memory as NodeGroups; when a group reaches NODE_GROUP_SIZE rows a new group is automatically created.

Primary key uniqueness is enforced via an in-memory HashIndex that maps PK values to row offsets. For persistent indexes, use OnDiskHashIndex alongside the L1 cache (see index.rs).

Optionally, an ArtPrimaryKeyIndex can be attached for range-scan support on the primary key column (see create_art_index).

Fields§

§table_id: u64§name: String§columns: Vec<ColumnDefinition>§primary_key_column: usize§num_rows: u64§node_groups: Vec<NodeGroup>

NodeGroup-based columnar storage. Each group holds up to NODE_GROUP_SIZE rows across all columns.

§hash_index: HashIndex<String>

In-memory hash index for primary key → row lookup and dedup. Stores the PK value (as a string representation) mapped to row offset.

§art_index: Option<ArtPrimaryKeyIndex>

Optional ART (Adaptive Radix Tree) index for PK range scans. When present, insert_row() also updates this index automatically.

§persistence_dirty: bool

Set when an UPDATE/DELETE touches the table. The durable column mirror (see persistence.rs) performs a full rewrite when this flag is set.

Implementations§

Source§

impl NodeTable

Source

pub fn new(table_id: u64, name: String, columns: Vec<ColumnDefinition>) -> Self

Source

pub fn set_spiller(&mut self, spiller: Option<Arc<Spiller>>)

Attach a spiller to this table so bulk inserts spill to disk once a NodeGroup’s buffer exceeds the memory threshold (P51.44).

Source

pub fn add_column(&mut self, column: ColumnDefinition)

Widen the table schema with a new column (ALTER TABLE ADD). Every existing row gets a NULL in the new column and all node groups are widened so scans emit it (P53.37). The main DDL catalog is updated by the caller; without this storage-side mirror the column silently vanishes from scans and the export/projection paths drift.

Source

pub fn insert_row(&mut self, values: Vec<Value>) -> Result<u64, StorageError>

Insert a row of values into the table.

Appends to the current NodeGroup; auto-creates a new group when the current one is full (reaches NODE_GROUP_SIZE rows).

If the table has a primary key column, checks for duplicates and rejects rows with already-existing PK values. The hash index is updated after a successful insert.

When txn_id is Some(...), the insert is recorded in VersionInfo for MVCC snapshot isolation.

Returns an error if the number of values doesn’t match the number of columns, or if a duplicate primary key value is detected.

Source

pub fn insert_row_with_txn( &mut self, values: Vec<Value>, txn_id: Option<u64>, ) -> Result<u64, StorageError>

Insert a row with an optional transaction ID for MVCC tracking.

Source

pub fn insert_rows_batch( &mut self, rows: &[Vec<Value>], ) -> Result<u64, StorageError>

Batch insert multiple rows efficiently. Validates PK uniqueness, pre-allocates node groups, and bulk-appends. When txn_id is Some(...), inserts are recorded in VersionInfo for MVCC.

Source

pub fn insert_rows_batch_with_txn( &mut self, rows: &[Vec<Value>], txn_id: Option<u64>, ) -> Result<u64, StorageError>

Batch insert with optional MVCC tracking.

Source

pub fn lookup_by_pk(&self, pk_value: &Value) -> Option<u64>

Look up a row offset by its primary key value.

Returns Some(row_offset) if the PK exists, or None if not found. Uses the in-memory hash index for O(1) lookup.

Source

pub fn lookup_by_pk_batch(&self, pk_values: &[Value]) -> Vec<Option<u64>>

Batch look up row offsets for multiple primary key values.

Returns a Vec<Option<u64>> parallel to the input, where each element is Some(row_offset) if the PK exists, or None if not found. Uses the in-memory hash index for O(1) per-key lookup, avoiding per-row method-call overhead by inlining the lookup logic.

Source

pub fn lookup_by_pk_range( &self, lower: Option<&Value>, lower_inclusive: bool, upper: Option<&Value>, upper_inclusive: bool, max_results: u64, ) -> Vec<u64>

Perform a range scan on the primary key column using the ART index.

Returns up to max_results row offsets for keys within [lower, upper] (respecting inclusivity flags). Returns an empty vec if no ART index exists or no keys match.

This is the bridge function called by PhysicalArtIndexRangeScan.

Source

pub fn scan_column( &self, col_idx: usize, start: u64, count: u64, snapshot_ts: Option<u64>, commit_history: &HashMap<u64, u64>, ) -> Vec<Value>

Scan all values for a given column across all node groups.

Returns a flat Vec<Value> containing values from start to start + count (or fewer if the end of the table is reached).

If snapshot_ts is Some(...), performs MVCC snapshot isolation: rows inserted/deleted by transactions committed after snapshot_ts are excluded, and versioned updates are resolved.

Source

pub fn load_persisted_rows( &mut self, rows: Vec<Vec<Value>>, ) -> Result<(), StorageError>

Rebuild the table’s in-memory state from rows loaded off the durable column mirror (see persistence.rs).

Populates node_groups, num_rows, the PK hash index, and the ART index directly, bypassing PK uniqueness checks so that soft-deleted rows (whose PK is Null) can be restored at their original row offsets.

Source

pub fn update_cell( &mut self, row_idx: u64, col_idx: usize, value: Value, ) -> Result<(), StorageError>

Update a single cell (row, column) with a new value.

Source

pub fn delete_row(&mut self, row_idx: u64) -> Result<(), StorageError>

Delete a row by its index. Marks the row as null by setting all its column values to Value::Null. This is a soft delete — the row slot remains.

Source

pub fn delete_row_with_txn( &mut self, row_idx: u64, txn_id: Option<u64>, ) -> Result<(), StorageError>

Delete a row with optional MVCC tracking.

When txn_id is Some(...), the delete is recorded in VersionInfo for MVCC snapshot isolation.

Source

pub fn row_undo_bytes(&self, row_idx: u64) -> Vec<u8>

Capture the full row (all columns) as serialized undo bytes. Used by the write path to record UndoType::Delete records so a rollback can restore a soft-deleted row (P52.18).

Source

pub fn cell_undo_bytes(&self, row_idx: u64, col_idx: usize) -> Vec<u8>

Capture a single cell as serialized undo bytes. Used to record UndoType::Update records for SET rollback (P52.18).

Source

pub fn get_value(&self, row: usize, col: usize) -> Option<&Value>

Get a single value at (row, col) by locating the correct NodeGroup and ColumnChunk.

Source

pub fn get_value_with_snapshot( &self, row: usize, col: usize, snapshot_ts: Option<u64>, commit_history: &HashMap<u64, u64>, ) -> Option<&Value>

Get a single value with MVCC snapshot isolation.

Checks VersionInfo for insert/delete visibility and UpdateInfo version chains when snapshot_ts is provided.

Source

pub fn to_column_major_data(&self) -> Vec<Vec<Value>>

Reconstruct column-major data (Vec<Vec<Value>>) from all node groups.

Used by the processor (resolve_scan_data) for backward compatibility.

Source

pub fn to_column_major_data_with_predicate( &self, predicate: Option<(usize, &str, &Value)>, ) -> Vec<Vec<Value>>

Like to_column_major_data, but applies an optional zone map predicate (col_idx, op_string, val) to skip entire node groups.

Source

pub fn to_column_major_data_with_snapshot( &self, snapshot_ts: Option<u64>, commit_history: &HashMap<u64, u64>, ) -> Vec<Vec<Value>>

Like to_column_major_data, but with MVCC snapshot isolation.

When snapshot_ts is Some(...), rows inserted/deleted by transactions committed after snapshot_ts are excluded, and versioned updates are resolved to the value visible at that snapshot.

Source

pub fn to_column_major_data_with_snapshot_and_predicate( &self, predicate: Option<(usize, &str, &Value)>, snapshot_ts: Option<u64>, commit_history: &HashMap<u64, u64>, ) -> Vec<Vec<Value>>

Like to_column_major_data_with_snapshot, but applies an optional zone map predicate to skip entire node groups.

Source

pub fn to_column_major_data_with_predicate_and_ids( &self, predicate: Option<(usize, &str, &Value)>, ) -> (Vec<Vec<Value>>, Vec<u64>)

Like to_column_major_data_with_predicate, but additionally returns the internal node id (global row offset) for every emitted row, in the same order as the returned column data. This is the node id space used by the processor’s extend/insert/join operators (<var>._id).

Source

pub fn to_column_major_data_with_snapshot_and_predicate_and_ids( &self, predicate: Option<(usize, &str, &Value)>, snapshot_ts: Option<u64>, commit_history: &HashMap<u64, u64>, ) -> (Vec<Vec<Value>>, Vec<u64>)

Like to_column_major_data_with_snapshot_and_predicate, but additionally returns the internal node id (global row offset) for every emitted row, in the same order as the returned column data.

Trait Implementations§

Source§

impl Clone for NodeTable

Source§

fn clone(&self) -> NodeTable

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NodeTable

Source§

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

Formats the value using the given formatter. Read more

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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