perf(tui): replace filter result Vec<usize> with bitmap#34
Conversation
Store filter matches as a packed bitmap (1 bit/packet) with a per-block cumulative popcount index for O(log n) rank/select. Convert sequential and parallel scan accumulators as well, cutting filter-result memory from 8 bytes/match to 1 bit/packet (~800MB to ~14MB for 100M packets at high match rates).
|
| Branch | tui-filter-bitmap |
| Testbed | ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result milliseconds (ms) (Result Δ%) | Upper Boundary milliseconds (ms) (Limit %) |
|---|---|---|---|
| target/release/dsct read bench_input.pcap | 📈 view plot 🚷 view threshold | 6.22 ms(+3.16%)Baseline: 6.03 ms | 6.94 ms (89.64%) |
| target/release/dsct stats bench_input.pcap | 📈 view plot 🚷 view threshold | 71.06 ms(+2.92%)Baseline: 69.05 ms | 85.64 ms (82.98%) |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #34 +/- ##
==========================================
+ Coverage 91.06% 91.22% +0.15%
==========================================
Files 79 80 +1
Lines 17678 18067 +389
==========================================
+ Hits 16099 16481 +382
- Misses 1579 1586 +7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Greptile SummaryReplaces
Confidence Score: 4/5Safe to merge; rank/select/iter logic is algorithmically correct and well-tested, with the only notable gap being a missed word-level fill optimisation in push_set_range. The bitmap data structure is correct throughout — block-index invariants hold, rank/select agree with the reference Vec tests, the sequential and parallel scan paths both call extend_universe(total) before finalization, and the live-capture universe-growth path handles the filter-active vs filter-inactive branches correctly. The one issue is that push_set_range (and therefore all_set) iterates bit-by-bit over contiguous ranges rather than filling entire u64 words, which means clearing a filter or loading a large file without a filter incurs O(n) bit-set operations instead of O(n/64) word writes. src/tui/filter_bitmap.rs — specifically the push_set_range implementation for large contiguous ranges Important Files Changed
Sequence DiagramsequenceDiagram
participant UI
participant App
participant FilterBitmap
participant ParallelScan
participant SeqScan
UI->>App: apply_filter()
alt empty filter
App->>FilterBitmap: all_set(indices.len())
FilterBitmap-->>App: filtered (every bit set)
else parallel-eligible filter
App->>ParallelScan: ParallelFilterScan::new()
loop drain()
ParallelScan-->>App: ScanPoll::Running
end
ParallelScan-->>App: ScanPoll::Complete(FilterBitmap)
App->>FilterBitmap: finalize_filter(bitmap)
else sequential filter
App->>SeqScan: "FilterProgress { results: FilterBitmap::new() }"
loop filter_tick() chunks
SeqScan->>FilterBitmap: push(matching_idx)
end
SeqScan->>FilterBitmap: extend_universe(total)
App->>FilterBitmap: finalize_filter(bitmap)
end
UI->>App: render packet list
App->>FilterBitmap: iter_from(offset).take(visible_rows)
FilterBitmap-->>App: packet indices
UI->>App: jump to packet N
App->>FilterBitmap: contains(N-1) → rank(N-1)
FilterBitmap-->>App: display position (O(1))
Reviews (1): Last reviewed commit: "perf(tui): replace filter result Vec<usi..." | Re-trigger Greptile |
Set contiguous ranges word-at-a-time instead of bit-by-bit, ~64x fewer operations for all_set on load and filter clear.
Summary
Replace the TUI filter result storage (
App::filtered_indices, a Vec of packet indices) with a packed bitmap (FilterBitmap, 1 bit per packet) plus a per-block cumulative popcount index. No new dependencies.select(n)(n-th filtered row → packet index): O(log blocks + 8 words), used for windowed rendering via oneselect+ cheap iterationrank(idx)(packet index → display row): O(1)-ish; jump-to-packet was O(n) beforecount_ones()(match count): O(1)FilterProgress::results) and parallel scan final concatenation are converted too, since they had the same allocation problemMemory (100M packets, high match rate)
Tests
filter_bitmap.rs: equivalence against a sorted-Vec reference (densities 0–100%, block boundaries, append growth,nearesttie-breaking)cargo test --all-targets --all-features, fmt, clippy-D warnings, doc, taplo clean