Conversation
…on-only columns Signed-off-by: Tanvir Alam <tanvralm@amazon.com>
Signed-off-by: Tanvir Alam <tanvralm@amazon.com>
Signed-off-by: Tanvir Alam <tanvralm@amazon.com>
Signed-off-by: Tanvir Alam <tanvralm@amazon.com>
Remove LiquidCacheParquetRef from the private use statement (line 18) since it's already made available via pub use (line 24). Having it in both causes E0252 (name defined multiple times). Also consolidate both pub use statements into a single line. Signed-off-by: Bukhtawar Khan <bukhtawa@amazon.com>
Fix re-export conflict: LiquidCacheParquetRef defined twice
Two fixes for the OpenSearch indexed-table integration path where predicate=None (filtering is handled externally by the BoolNode evaluator): 1. When no row filter is present, treat all projected columns as cacheable (predicate_column_ids = cache_column_ids). Previously, an empty predicate_column_ids meant is_predicate_column=false for all columns, causing get/insert to always bail out — the cache was effectively a no-op passthrough with pure overhead. 2. Move cache insert (Arrow→Liquid transcoding) into tokio::spawn so it runs asynchronously. The query batch is returned immediately without waiting for cache population. This ensures cache MISS has near-zero overhead vs the non-LC path. Together these ensure: repeated numeric queries get cache HITs (served from in-memory Arrow arrays), first execution has minimal overhead, and string columns are still correctly rejected by the is_string_type guard. Signed-off-by: Bukhtawar Khan <bukhtawa@amazon.com>
Fix cache disabled without predicate and make insert async
Two fixes for the OpenSearch indexed-table integration path where predicate=None (filtering is handled externally by the BoolNode evaluator): 1. When no row filter is present, treat all projected columns as cacheable (predicate_column_ids = cache_column_ids). Previously, an empty predicate_column_ids meant is_predicate_column=false for all columns, causing get/insert to always bail out — the cache was effectively a no-op passthrough with pure overhead. 2. Move cache insert (Arrow→Liquid transcoding) into tokio::spawn so it runs asynchronously. The query batch is returned immediately without waiting for cache population. This ensures cache MISS has near-zero overhead vs the non-LC path. Together these ensure: repeated numeric queries get cache HITs (served from in-memory Arrow arrays), first execution has minimal overhead, and string columns are still correctly rejected by the is_string_type guard. Signed-off-by: Bukhtawar Khan <bukhtawa@amazon.com>
Refactor read_from_cache: phase 1/phase 2 for future split-projection
Two fixes for the OpenSearch indexed-table integration path where predicate=None (filtering is handled externally by the BoolNode evaluator): 1. When no row filter is present, treat all projected columns as cacheable (predicate_column_ids = cache_column_ids). Previously, an empty predicate_column_ids meant is_predicate_column=false for all columns, causing get/insert to always bail out — the cache was effectively a no-op passthrough with pure overhead. 2. Move cache insert (Arrow→Liquid transcoding) into tokio::spawn so it runs asynchronously. The query batch is returned immediately without waiting for cache population. This ensures cache MISS has near-zero overhead vs the non-LC path. Together these ensure: repeated numeric queries get cache HITs (served from in-memory Arrow arrays), first execution has minimal overhead, and string columns are still correctly rejected by the is_string_type guard. Signed-off-by: Bukhtawar Khan <bukhtawa@amazon.com>
Selectivity-gated LC with metadata passthrough and all-cols-cacheable
Up to standards ✅🟢 Issues
|
| Category | Results |
|---|---|
| Security | 6 high |
🟢 Metrics 279 complexity · 13 duplication
Metric Results Complexity 279 Duplication 13
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
|
||
| let metadata_size_hint = partitioned_file.metadata_size_hint; | ||
| let has_predicate = self.predicate.is_some(); | ||
| log::info!( |
There was a problem hiding this comment.
Sure we can change the log level from info to debug
| // Estimate selectivity from row_selection: how many rows survived | ||
| // RG pruning + page index pruning vs total rows in selected RGs. | ||
| let total_rows: usize = row_group_indexes | ||
| .iter() | ||
| .map(|&idx| rg_metadata[idx].num_rows() as usize) | ||
| .sum(); | ||
| let selected_rows = row_selection.as_ref() | ||
| .map(|sel| sel.row_count()) | ||
| .unwrap_or(total_rows); | ||
| let estimated_selectivity = if total_rows > 0 { | ||
| selected_rows as f64 / total_rows as f64 | ||
| } else { | ||
| 1.0 | ||
| }; |
There was a problem hiding this comment.
Lets generalize this as a generic policy that can be pushed
There was a problem hiding this comment.
Done — extracted into a CacheEngagementPolicy trait. Consumers can push custom policies through
.with_engagement_policy(threshold)
f30dc3a to
fdcfca8
Compare
fdcfca8 to
8a85077
Compare
04a6d4a to
1d5a668
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #505 +/- ##
===========================================
- Coverage 83.10% 29.43% -53.68%
===========================================
Files 86 78 -8
Lines 19613 13309 -6304
Branches 19613 13309 -6304
===========================================
- Hits 16300 3917 -12383
- Misses 2974 9226 +6252
+ Partials 339 166 -173 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
0160083 to
1d5a668
Compare
Adds a method that sets the predicate for row_filter (per-row filtering during decode) and RG-level pruning predicate, but deliberately skips page_pruning_predicate. This is used by the indexed path where the BoolNode's RowSelection is authoritative and page-level statistics must not override it.
9de5160 to
1c258b7
Compare
1c258b7 to
9de5160
Compare
Related : #500
Summary
Liquid Cache currently wraps every ParquetSource unconditionally. This causes severe regressions on string-heavy queries (cache misses force full parquet reads) and queries where decode cost is already minimal. This PR makes LC aware of when it can and cannot help, and gracefully opts out when engagement would hurt.
Changes
1. Selective column caching
(`cache/column.rs`)
Cache only numeric predicate columns. String and binary columns are never inserted into LC — they cannot be efficiently encoded and their misses force full parquet reads that negate any cache benefit.
2. LRU eviction policy with type-aware queues
(`cache/policies/cache/lru.rs`, `cache/policies/cache/mod.rs`)
New LRU eviction policy that manages Arrow, Liquid-encoded, and squeezed entries in separate queues. Allows bounded memory usage with predictable eviction behavior under concurrent load.
3. Dynamic budget resize
(`cache/budget.rs`, `cache/core.rs`)
Cache memory and disk budgets can be resized at runtime via `set_max_memory_bytes` / `set_max_disk_bytes`. Enables live tuning without requiring a restart.
4. Builder API extensions
(`datafusion-local/src/lib.rs`)
5. Optimizer gating: skip uncacheable queries
(`optimizers/mod.rs`)
The `LocalModeOptimizer` now skips LC wrapping when:
6. Selectivity-based delegation in the opener
(`reader/plantime/opener.rs`, `reader/plantime/source.rs`)
When the opener estimates that fewer than 50% of rows survive pruning AND a predicate is present, it delegates to plain parquet instead of using the LC stream. Few matching rows means decode cost is already minimal — LC overhead would dominate.
Also adds:
7. Two-phase cache read with batched fallback
(`reader/runtime/liquid_cache_reader.rs`)
Previously, each column miss triggered an independent parquet read. Now:
8. Fix: cache disabled when no predicate
(`reader/runtime/liquid_stream.rs`)
When no predicate is present, `predicate_column_ids` was empty, causing `create_row_group` to treat all columns as non-predicate (uncacheable). Fixed to use `cache_column_ids` as the predicate set when no filter exists — so all projected columns become cacheable.
Benchmark Results (100M row ClickBench, 3 runs, warm cache)