pub struct ColumnarQueryResult {
pub columns: Vec<String>,
pub data: Vec<TypedColumn>,
pub row_count: usize,
pub bytes_read: usize,
}Expand description
Columnar query result - SIMD-friendly format for analytics
Instead of row-oriented Vec<HashMap<String, SochValue>>, this returns
column-oriented Vec<TypedColumn> for efficient vectorized operations.
§Memory Layout
Row-oriented (standard):
Row 0: [id=1, name="Alice", score=85]
Row 1: [id=2, name="Bob", score=92]
Row 2: [id=3, name="Carol", score=78]Column-oriented (this format):
id: [1, 2, 3] ← contiguous i64 array (SIMD-friendly)
name: ["Alice", "Bob", "Carol"] ← Arrow-style string encoding
score: [85, 92, 78] ← contiguous i64 array§Performance Benefits
- SIMD: Column sums use vectorized instructions (~8× faster)
- Cache: Sequential access pattern maximizes L1/L2 cache hits
- Compression: Same-type data compresses better (5-10× typical)
- Filtering: Bitmap operations instead of row iteration
§Usage
let result = db.query(txn, "users")
.columns(&["id", "score"])
.as_columnar()?;
// SIMD sum
let total_score = result.column("score")
.map(|c| c.sum_i64())
.unwrap_or(0);
// Stats
println!("Rows: {}, Memory: {} bytes", result.row_count(), result.memory_size());Fields§
§columns: Vec<String>Column names in order
data: Vec<TypedColumn>Column data - each TypedColumn contains all values for one column
row_count: usizeNumber of rows
bytes_read: usizeBytes read from storage
Implementations§
Source§impl ColumnarQueryResult
impl ColumnarQueryResult
Sourcepub fn column(&self, name: &str) -> Option<&CoreTypedColumn>
pub fn column(&self, name: &str) -> Option<&CoreTypedColumn>
Get column by name
Sourcepub fn column_index(&self, name: &str) -> Option<usize>
pub fn column_index(&self, name: &str) -> Option<usize>
Get column index by name
Sourcepub fn column_count(&self) -> usize
pub fn column_count(&self) -> usize
Number of columns
Sourcepub fn memory_size(&self) -> usize
pub fn memory_size(&self) -> usize
Total memory size in bytes
Sourcepub fn row_view(&self, index: usize) -> Option<ColumnarRowView<'_>>
pub fn row_view(&self, index: usize) -> Option<ColumnarRowView<'_>>
Zero-allocation row access by index.
Returns a lightweight view that resolves column values on demand
from the underlying columnar arrays — no HashMap per row.
let result = query.as_columnar()?;
for i in 0..result.row_count() {
let row = result.row_view(i).unwrap();
let name = row.get("name"); // SochValue::Text(...)
}Sourcepub fn into_query_result(self) -> QueryResult
pub fn into_query_result(self) -> QueryResult
Convert to row-oriented QueryResult for backward compatibility.
This materialises one HashMap<String, SochValue> per row, so prefer
using row_view() or direct columnar access when performance matters.
Sourcepub fn column_stats(&self, column: &str) -> Option<&ColumnStats>
pub fn column_stats(&self, column: &str) -> Option<&ColumnStats>
Get column statistics (min, max, null count)
Trait Implementations§
Source§impl Clone for ColumnarQueryResult
impl Clone for ColumnarQueryResult
Source§fn clone(&self) -> ColumnarQueryResult
fn clone(&self) -> ColumnarQueryResult
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for ColumnarQueryResult
impl RefUnwindSafe for ColumnarQueryResult
impl Send for ColumnarQueryResult
impl Sync for ColumnarQueryResult
impl Unpin for ColumnarQueryResult
impl UnsafeUnpin for ColumnarQueryResult
impl UnwindSafe for ColumnarQueryResult
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