Lakehouse Pipeline
The write-side modules of src/engine/: ingest.rs, splitter.rs, formats/core/parquet.rs (lake + gold writers), partition.rs, and memory.rs.
Ingest (br.lake.ingest)
Copies a source directory into a destination lake, preserving relative layout:
- Row-based formats (
csv, tsv, psv, txt, json, jsonl, ndjson, msgpack, xlsx) are converted to Parquet when normalization is on, either viaauto_normalize=Trueor theBR_INGEST_NORMALIZE=1environment variable. - Everything else is copied byte-for-byte.
Returns (files_ingested, rows_ingested).
Split (br.lake.split_file)
split_file_native() streams a file and writes fixed-size parts:
n = br.lake.split_file("big.csv", max_rows_per_file=100_000,
output_dir="./parts", format="parquet") # → number of parts
Output format can be any writable extension (e.g. parquet, csv). Parts are named <stem>_part_NNN.<format>.
Clean/Trash Lake Write (br.lake.process_and_write_lake)
Reads every Parquet file under input_dir in parallel (optionally narrowed by a Hive-style partition_filter), applies the static quality thresholds per batch, and writes two Parquet trees that mirror the input's relative layout:
sequenceDiagram
autonumber
participant IN as input_dir (Parquet files)
participant FL as static threshold filter
participant CL as clean_output_dir/
participant TR as trash_output_dir/
IN->>FL: each RecordBatch (Rayon parallel)
FL->>CL: passing rows (ZSTD Parquet)
FL->>TR: violating rows + audit_error_code
FL-->>IN: (total_files, total_rows, clean_rows, trash_rows)
Returns (total_files, total_rows, clean_rows, trash_rows). Trash files carry the same audit_error_code column as dynamic filtering. All parts are written with ZSTD compression; batch size adapts to the number of concurrent files.
Gold Table (br.lake.generate_gold_table)
Reads a clean Parquet directory back and republishes it as a versioned table:
- Output paths mirror
clean/'s relative layout undergold/(ZSTD compressed). - Writes
_gold_metadata.jsonnext to the data: table name, version, creation epoch, total files/rows. - Returns
(total_files_read, gold_rows_written, manifest_path).
Memory Budget & Runtimes
All streaming reads/writes share one budget from src/engine/memory.rs:
| Mechanism | Value |
|---|---|
| Per-stream row ceiling | BUDGET_BATCH_ROWS = 1 << 20 |
| Parallel scaling | each of N streams gets budget_batch_rows(N) rows |
| Total RAM cap | BASALTIC_RED_MAX_RAM_GB env var, default 2 GB |
| Safety factor | ×3.5 for transient mask/clean/trash buffers |
Two process-wide runtimes are created lazily: a multi-threaded tokio runtime (global_runtime(), used by DataFusion streams) and a sized Rayon pool (global_rayon_pool(threads)). Internally, budget_batch_rows(parallel_streams) dynamically sizes per-stream buffers to stay within the total memory budget.