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: boolSet 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
impl NodeTable
pub fn new(table_id: u64, name: String, columns: Vec<ColumnDefinition>) -> Self
Sourcepub fn set_spiller(&mut self, spiller: Option<Arc<Spiller>>)
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).
Sourcepub fn add_column(&mut self, column: ColumnDefinition)
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.
Sourcepub fn insert_row(&mut self, values: Vec<Value>) -> Result<u64, StorageError>
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.
Sourcepub fn insert_row_with_txn(
&mut self,
values: Vec<Value>,
txn_id: Option<u64>,
) -> Result<u64, StorageError>
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.
Sourcepub fn insert_rows_batch(
&mut self,
rows: &[Vec<Value>],
) -> Result<u64, StorageError>
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.
Sourcepub fn insert_rows_batch_with_txn(
&mut self,
rows: &[Vec<Value>],
txn_id: Option<u64>,
) -> Result<u64, StorageError>
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.
Sourcepub fn lookup_by_pk(&self, pk_value: &Value) -> Option<u64>
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.
Sourcepub fn lookup_by_pk_batch(&self, pk_values: &[Value]) -> Vec<Option<u64>>
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.
Sourcepub fn lookup_by_pk_range(
&self,
lower: Option<&Value>,
lower_inclusive: bool,
upper: Option<&Value>,
upper_inclusive: bool,
max_results: u64,
) -> Vec<u64>
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.
Sourcepub fn scan_column(
&self,
col_idx: usize,
start: u64,
count: u64,
snapshot_ts: Option<u64>,
commit_history: &HashMap<u64, u64>,
) -> Vec<Value>
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.
Sourcepub fn load_persisted_rows(
&mut self,
rows: Vec<Vec<Value>>,
) -> Result<(), StorageError>
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.
Sourcepub fn update_cell(
&mut self,
row_idx: u64,
col_idx: usize,
value: Value,
) -> Result<(), StorageError>
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.
Sourcepub fn delete_row(&mut self, row_idx: u64) -> Result<(), StorageError>
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.
Sourcepub fn delete_row_with_txn(
&mut self,
row_idx: u64,
txn_id: Option<u64>,
) -> Result<(), StorageError>
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.
Sourcepub fn row_undo_bytes(&self, row_idx: u64) -> Vec<u8> ⓘ
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).
Sourcepub fn cell_undo_bytes(&self, row_idx: u64, col_idx: usize) -> Vec<u8> ⓘ
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).
Sourcepub fn get_value(&self, row: usize, col: usize) -> Option<&Value>
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.
Sourcepub fn get_value_with_snapshot(
&self,
row: usize,
col: usize,
snapshot_ts: Option<u64>,
commit_history: &HashMap<u64, u64>,
) -> Option<&Value>
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.
Sourcepub fn to_column_major_data(&self) -> Vec<Vec<Value>>
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.
Sourcepub fn to_column_major_data_with_predicate(
&self,
predicate: Option<(usize, &str, &Value)>,
) -> Vec<Vec<Value>>
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.
Sourcepub fn to_column_major_data_with_snapshot(
&self,
snapshot_ts: Option<u64>,
commit_history: &HashMap<u64, u64>,
) -> Vec<Vec<Value>>
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.
Sourcepub 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>>
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.
Sourcepub fn to_column_major_data_with_predicate_and_ids(
&self,
predicate: Option<(usize, &str, &Value)>,
) -> (Vec<Vec<Value>>, Vec<u64>)
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).
Sourcepub 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>)
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§
Auto Trait Implementations§
impl Freeze for NodeTable
impl RefUnwindSafe for NodeTable
impl Send for NodeTable
impl Sync for NodeTable
impl Unpin for NodeTable
impl UnsafeUnpin for NodeTable
impl UnwindSafe for NodeTable
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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