rajat315315 opened a new issue, #16477:
URL: https://github.com/apache/lucene/issues/16477

   ### Description
   
   ## Background & Case
   Currently, Apache Lucene relies on `SortedSetDocValues` for faceting and 
aggregating multi-valued keyword fields. When a query executes, the aggregation 
engine iterates through the matched `docIDs`, performs random-access lookups 
into the DocValues column, retrieves the segment ordinals for each document, 
and increments the corresponding bucket counts.
   
   ---
   
   ## Problem Statement
   While `SortedSetDocValues` is the standard for multi-valued fields, it 
introduces a severe performance bottleneck for high-cardinality datasets (e.g., 
100,000+ unique ordinals) when query match densities are high:
   
   1. **Cache Misses & Memory Latency:** For a query matching millions of 
documents, the engine executes millions of non-contiguous random-access memory 
lookups. The time complexity is strictly bounded by $O(\text{MatchingDocs})$.
   2. **Multi-Value Vectorization Penalty:** Because documents contain variable 
numbers of ordinals per row, vectorizing the retrieval stream using SIMD is 
difficult without expensive flattening and intermediate buffering.
   
   ---
   
   ## Motivation
   High-performance analytical engines achieve sub-millisecond grouped 
aggregations over high-cardinality data by replacing row-based ordinal lookups 
with compressed bitmap intersections. By supporting an opt-in bitmap structure 
optimized for high-cardinality multi-valued fields, Lucene can eliminate 
$O(\text{MatchingDocs})$ random-access overhead and perform aggregations using 
block-level skipping and bitwise arithmetic.
   
   ---
   
   ## Proposed Solution
   Introduce an opt-in index configuration (e.g., 
`index_options="roaring_bitmap"`) for keyword fields to build an array of 
Roaring Bitmaps at index time:
   
   1. **Storage Layout:** Transpose the field representation into an array of 
Roaring Bitmaps indexed by global ordinal, where each bitset represents 
matching `docIDs`. Multi-valued documents set their `docID` bit across multiple 
category bitsets.
   2. **Block-Level Execution:** Divide the Query Result Bitset ($Q$) into 
64k-document blocks during search execution.
   3. **Zero-Cycle Skipping:** If a 64k block in $Q$ contains zero matching 
documents, skip the intersection entirely across all category bitsets for that 
block.
   4. **SIMD Acceleration:** For active blocks, utilize Panama Vector API / 
HotSpot C2 auto-vectorization to execute SIMD `VPOPCNTDQ` instructions over the 
bitsets:
   ```math
      \text{Count}(C_k) += \text{POPCNT}(Q_{\text{block}} \ \& \ 
C_{k\text{\_block}})
   ```
   
   ---
   
   ## Expected Speedup
   * **5x – 20x Latency Reduction for High Match Densities:** Direct 
hardware-level `AND` + `POPCNT` vector execution eliminates non-contiguous 
memory access and L3 CPU cache misses associated with DocValues pointer 
traversal.
   * **Up to 50x+ Latency Reduction for Sparse/Filtered Queries:** Block-level 
skipping bypasses empty 64k document chunks entirely, avoiding bitset 
evaluations across large non-matching document ranges.
   * **Heap Overhead Reduction:** Off-heap bitset scanning eliminates object 
allocation churn during the collection phase.
   
   ---
   
   ## Implementation Plan & Expected File Changes
   
   ### 1. Indexing & Storage Layer
   
   * 
**`core/src/java/org/apache/lucene/codecs/roaring/RoaringDocValuesFormat.java` 
(NEW)**
     * Entry point for the new codec extending `DocValuesFormat`.
     * Provides `fieldsConsumer` and `fieldsProducer` methods to read and write 
the Roaring Bitmap structures.
   * 
**`core/src/java/org/apache/lucene/codecs/roaring/RoaringDocValuesConsumer.java`
 (NEW)**
     * Write-path implementation extending `DocValuesConsumer`.
     * Overrides `addSortedSetField()`. Instead of writing ordinals 
sequentially per document, buffers `docIDs` into off-heap Roaring Bitmaps (one 
per ordinal) and flushes them to `.dvd` (data) and `.dvm` (meta) files.
   * 
**`core/src/java/org/apache/lucene/codecs/roaring/RoaringDocValuesProducer.java`
 (NEW)**
     * Read-path implementation extending `DocValuesProducer`.
     * Exposes `getBitsets(FieldInfo field)` to access memory-mapped bitset 
streams with $O(1)$ offset lookups per ordinal.
   
   ### 2. Aggregation & Execution Layer
   
   * 
**`facet/src/java/org/apache/lucene/facet/sortedset/RoaringBitmapFacetCounts.java`
 (NEW)**
     * Specialized facet collector implementing the 64k block-skipping logic 
and delegating SIMD vector reductions.
   * **`core/src/java/org/apache/lucene/util/VectorUtil.java` (MODIFICATION)**
     * Add `bitwiseAndPopcnt(long[] qBlock, long[] catBlock, int length)` 
utilizing Panama Vector API (`LongVector`) for hardware `VPOPCNTDQ` operations.
   * **`facet/src/java/org/apache/lucene/facet/FacetsConfig.java` 
(MODIFICATION)**
     * Add auto-routing logic to dispatch queries to `RoaringBitmapFacetCounts` 
when the field codec matches `RoaringDocValuesFormat`.
   
   ---
   
   ## Execution Flow
   
   1. **Index Time:** `RoaringDocValuesConsumer` transposes incoming 
multi-valued doc fields into inverted Roaring Bitmaps and writes compressed 64k 
chunk streams to disk off-heap.
   2. **Query Time:** `IndexSearcher` executes the boolean query and provides 
the matching `docIDs` bitset ($Q$) to `FacetsCollector`.
   3. **Routing & Collection:** `FacetsConfig` routes execution to 
`RoaringBitmapFacetCounts`, which slices $Q$ into 64k blocks.
   4. **Hardware Intersections:** Active 64k blocks undergo SIMD `AND` + 
`POPCNT` accumulation via `VectorUtil`, skipping inactive chunks automatically.
   
   ---
   
   ## Dependencies & Technical Considerations
   * Leverages **Panama Vector API** (`jdk.incubator.vector`) for SIMD 
operations.
   * Buffer structures should adhere to standard Roaring Bitmap specification 
semantics, maintaining off-heap allocation during indexing to avoid GC pressure.
   
   ---
   
   ## Request for Review
   I would appreciate feedback from the community and stakeholders on the 
feasibility of introducing this as a specialized, opt-in `DocValuesFormat` or 
`PostingsFormat`. Specifically, I would like to ask @jpountz and @mikemccand 
for their thoughts on integration points for block-level skipping within the 
current facet collection architecture and the best path forward for off-heap 
SIMD integration.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to