Skip to main content

densa_data/
lib.rs

1//! Live Arrow tables: rows identified by a key, updated by record batches, and views that
2//! stay sorted and filtered as the rows change.
3//!
4//! [`LiveTable`] takes Arrow [`RecordBatch`](arrow_array::RecordBatch)es from a feed, a
5//! query engine or a file, and upserts them by a key column; [`ViewSpec`] describes a view
6//! (a [`Filter`] and sort columns), which the table keeps up to date incrementally instead of
7//! recomputing it; [`GroupSpec`] does the same for grouped aggregates (count, sum, min, max,
8//! mean). A view's rows are [`RowRef`]s into [`LiveTable::batches`], so a display
9//! layer (such as `densa-arrow`'s grid) reads values straight from the Arrow arrays. Each
10//! key's row is a [`RecordId`] while the key lives: a selection can follow it through
11//! updates, compactions and re-sorted views ([`View::position`]). [`LiveTable::snapshot`]
12//! hands the live rows to anything else that reads Arrow, such as a SQL engine.
13//!
14//! This crate has no user-interface dependency.
15//!
16//! ```
17//! use std::sync::Arc;
18//! use arrow_array::{ArrayRef, Float64Array, RecordBatch, StringArray};
19//! use densa_data::{CompareOp, Filter, LiveTable, Order, Scalar, ViewSpec};
20//!
21//! let quotes = |symbols: Vec<&str>, prices: Vec<f64>| {
22//!     RecordBatch::try_from_iter([
23//!         ("symbol", Arc::new(StringArray::from(symbols)) as ArrayRef),
24//!         ("price", Arc::new(Float64Array::from(prices)) as ArrayRef),
25//!     ])
26//! };
27//! let mut table = LiveTable::new(quotes(vec![], vec![])?.schema(), "symbol")?;
28//! let expensive = table.add_view(
29//!     ViewSpec::new()
30//!         .filter(Filter::compare("price", CompareOp::Gt, Scalar::Float(100.0)))
31//!         .sort_by("price", Order::Descending),
32//! )?;
33//!
34//! table.upsert(quotes(vec!["AAA", "BBB", "CCC"], vec![150.0, 90.0, 120.0])?)?;
35//! table.upsert(quotes(vec!["BBB"], vec![200.0])?)?; // BBB rises: it enters the view
36//!
37//! let view = table.view(expensive).unwrap();
38//! assert_eq!(view.len(), 3); // BBB 200, AAA 150, CCC 120
39//! # Ok::<(), Box<dyn std::error::Error>>(())
40//! ```
41
42mod dictionary;
43mod error;
44mod filter;
45mod group;
46mod key;
47mod snapshot;
48mod sorted;
49mod table;
50mod value;
51mod view;
52
53pub use arrow_array;
54pub use arrow_schema;
55pub use error::DataError;
56pub use filter::{CompareOp, Filter, Scalar};
57pub use group::{Aggregate, GroupSpec, Groups};
58pub use table::{Changes, GroupsId, LiveTable, RecordId, RowRef, TableOptions, View, ViewId};
59pub use view::{Order, ViewSpec};
60
61/// A row's internal identity: stable for as long as its key is live.
62type RowId = u32;