Fold:Done.init+reduceinstead of??initial-state pattern.fold by <fields> init { ... } reduce { ... }is the new syntax. Init is evaluated once at pipeline compile time to (a) seed every group without re-running VRL at runtime and (b) provide a concreteKindto the reduce block, so.count + 1type-checks without any?? 0noise.
-
SIMD-acceleratedDone (memchr::memmem).search "literal"stage. -
Chunked events on channels.Done (CHUNK_SIZE = 1024). -
Per-chunk shard batching in fold.Done. Events are bucketed by target shard before locking; each shard's mutex is taken exactly once per chunk.fold by [](single shard) drops from O(events-per-chunk) lock acquisitions to O(1). -
Stage fusion for adjacent pure-CPU stages.Done. Adjacent search / filter / map / since / until stages run inside one fused worker pool. Channel hops collapse N → 1, VRL scratch allocates once per fused worker, and events are retained in place between ops so a drop in op 1 skips op 2..N. Measured 8.9× faster than Python on a chained workload (vs 3.5× for single-filter count-error). -
countfold primitive / no-VRL fast path. The most common accumulator (.count = .count + 1with an integer init) could bypass VRL entirely — the fold stage recognises the shape at compile time and runs a pure Rustu64 += 1per event under the shard lock. Useful both as a perf win and as a stepping stone for fused accumulators.
-
Sort / top-K stage.Done.sort by <path> [desc] [limit N], with VRL-compiled path extraction so.state.countworks. Full sort today; bounded heap for top-K deferred until a workload justifies it. -
Done.countsugar.countandcount by <fields>lower to the canonical counter fold at parse time so downstream optimisations (init pre-eval, shard batching) apply automatically. -
Simpler in-flight accounting (per-stage events_in == events_out). Today the compiler has to know which
fusedstages are pre- vs post-discover so it can hand them the right counter (monitored vs unmonitored). The boundary distinction is load-bearing for correctness but ugly — it leaks the discover-termination invariant into the compiler's stage-emit loop. Alternative: every stage already maintainsevents_in/events_outatomics viaStageStats. The monitor could poll a different invariant — "for every stage, events_in == events_out" — which is equivalent to pipeline-wide quiescence and doesn't care about where discover sits. Needs a clean no-poll wake path (same notify-on-zero trick, but signalled whenever a stage's delta reaches zero) and a cheap check across the stats vector. -
Filename-timestamp early drop. Log files commonly carry date/time tokens in their names (
app.log.2024-01-15,access_log_20240115,2024/01/15/access.log,app-2024-01-15T10-30-00.log). A pipeline withsince/untilcan use that to prune entire files at the glob / read boundary — never open or mmap them at all. For a year of daily logs on a "last 24 h" query, this turns 365 file reads into 1. Either a heuristic (find a date-ish pattern in the path) or a user-suppliedfilename_ts "%Y-%m-%d"hint passed to glob / read_lines. Composes with the existing per-linesincebyte-scan: files that straddle the boundary still get line-level filtering. -
Time-window filter.Done.since/untilstages with four extractor forms:.field(JSON needle scan),@leading(unix-int or ISO prefix),@bracketed(first[...]), and@clf(Apache CLF). Relative ("1h ago") and absolute time values resolved once at pipeline compile time. Per-event cost ~5 ns on the text corpus. Syslog (Mon DD HH:MM:SS, no year) and custom strftime formats left for later.
Stage::Discovercurrentlytodo!()s — planned Phase 4.