@@ -65,6 +65,9 @@ pub(crate) struct SegmentTermHistogramCollector {
6565 hist_block : ColumnBlockAccessor < u64 > ,
6666 /// No hard bounds, so every doc is in-bounds.
6767 all_docs_in_bounds : bool ,
68+ /// Both columns are full (fused-path precondition); cached so `collect` skips the per-block
69+ /// cardinality lookup in `fetch_block`.
70+ is_full : bool ,
6871}
6972
7073impl SegmentAggregationCollector for SegmentTermHistogramCollector {
@@ -132,9 +135,9 @@ impl SegmentAggregationCollector for SegmentTermHistogramCollector {
132135 // single `agg_data` scratch accessor). The collector owns all its inputs, so `collect`
133136 // doesn't touch `agg_data`.
134137 self . term_block
135- . fetch_block ( docs, & self . terms_req_data . accessor ) ;
138+ . fetch_block_with_is_full ( docs, & self . terms_req_data . accessor , self . is_full ) ;
136139 self . hist_block
137- . fetch_block ( docs, & self . hist_req_data . accessor ) ;
140+ . fetch_block_with_is_full ( docs, & self . hist_req_data . accessor , self . is_full ) ;
138141
139142 // Hoist the loop-invariant fields into locals: the optimizer can't prove the
140143 // `self.counts`/`self.term_counts` writes don't alias these `self` fields, so it can't keep
@@ -223,6 +226,7 @@ pub(super) fn maybe_build_collector(
223226 // using too much memory. We could check the maximum theoretical buckets up-front and pass
224227 // them down.
225228 let fuseable = is_top_level
229+ // TODO: We can easily support this
226230 && terms_req_data. allowed_term_ids . is_none ( )
227231 && terms_req_data. accessor . get_cardinality ( ) . is_full ( )
228232 // The flat counters are `u32`, bumped once per value, so no count can exceed the column's
@@ -273,6 +277,7 @@ pub(super) fn maybe_build_collector(
273277 term_block : ColumnBlockAccessor :: default ( ) ,
274278 hist_block : ColumnBlockAccessor :: default ( ) ,
275279 all_docs_in_bounds,
280+ is_full : terms_req_data. accessor . get_cardinality ( ) . is_full ( ) ,
276281 } ) ) )
277282}
278283
0 commit comments