Expand description
Live Arrow tables: rows identified by a key, updated by record batches, and views that stay sorted and filtered as the rows change.
LiveTable takes Arrow RecordBatches from a feed, a
query engine or a file, and upserts them by a key column; ViewSpec describes a view
(a Filter and sort columns), which the table keeps up to date incrementally instead of
recomputing it; GroupSpec does the same for grouped aggregates (count, sum, min, max,
mean), grouped by key columns or by buckets of one (counts per minute,
GroupSpec::group_by_time). A view’s rows are RowRefs into
LiveTable::batches, so a display layer (such as densa-arrow’s grid) reads values
straight from the Arrow arrays. Each key’s row is a RecordId while the key lives: a
selection can follow it through updates, compactions and re-sorted views
(View::position). LiveTable::snapshot hands the live rows to anything else that
reads Arrow, such as a SQL engine. A Window keeps a table to its recent rows, by a
time column.
This crate has no user-interface dependency.
use std::sync::Arc;
use arrow_array::{ArrayRef, Float64Array, RecordBatch, StringArray};
use densa_data::{CompareOp, Filter, LiveTable, Order, Scalar, ViewSpec};
let quotes = |symbols: Vec<&str>, prices: Vec<f64>| {
RecordBatch::try_from_iter([
("symbol", Arc::new(StringArray::from(symbols)) as ArrayRef),
("price", Arc::new(Float64Array::from(prices)) as ArrayRef),
])
};
let mut table = LiveTable::new(quotes(vec![], vec![])?.schema(), "symbol")?;
let expensive = table.add_view(
ViewSpec::new()
.filter(Filter::compare("price", CompareOp::Gt, Scalar::Float(100.0)))
.sort_by("price", Order::Descending),
)?;
table.upsert(quotes(vec!["AAA", "BBB", "CCC"], vec![150.0, 90.0, 120.0])?)?;
table.upsert(quotes(vec!["BBB"], vec![200.0])?)?; // BBB rises: it enters the view
let view = table.view(expensive).unwrap();
assert_eq!(view.len(), 3); // BBB 200, AAA 150, CCC 120Re-exports§
pub use arrow_array;pub use arrow_schema;
Structs§
- Aggregate
- One aggregate column of a
GroupSpec: what it computes, over which column, and its name in the result. - Changes
- What an upsert or delete did.
- Group
Spec - Groups of rows with equal key values, and aggregates over each group.
- Groups
- The groups of a
GroupSpec, ordered by key. Cheap to get. - Groups
Id - Identifies grouped aggregates of one
LiveTable(and of clones made after they were added, as forViewId). - Live
Table - A table of rows identified by a key column, updated by Arrow record batches, with views (filtered, sorted) that follow every change.
- Record
Id - A record: one key’s row for as long as the key is live, through updates, compactions and
view changes. Deleting the key ends the record; inserting the key again starts a new one.
Get one with
LiveTable::record_of_keyorView::record, find its row withLiveTable::row_ofand its place in a view withView::position. - RowRef
- Where a row’s values are:
table.batches()[batch], rowrow. Valid until the next compaction, whichLiveTable::upsertandLiveTable::deletemay run: compareLiveTable::generationbefore reusing one. - Table
Options - How a
LiveTablemanages its storage. - View
- The rows of a view, in its order. Cheap to get; reading never allocates.
- ViewId
- Identifies a view of one
LiveTable. A clone of the table copies its views, so the id of a view added before cloning works on both; one added afterwards, only on its table. - View
Spec - What a view shows: an optional filter and sort columns.
- Window
- Keeps a
LiveTableto its recent rows: those whose value in a time column is within a span of the newest. Set it withLiveTable::set_window.
Enums§
- Compare
Op - How a column compares with a literal.
- Data
Error - Why a table or view operation was refused. Nothing changes when one is returned.
- Filter
- Which rows a view shows. Dates, times, timestamps and durations compare as their integer
count of units (milliseconds since the epoch for
Timestamp(Millisecond)). - Order
- Sort direction.
- Scalar
- A literal value a column is compared with.