Skip to content

Commit ac7a3d3

Browse files
committed
add comment, hoist variables
1 parent 03520a0 commit ac7a3d3

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

columnar/src/block_accessor.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,25 @@ impl<T: PartialOrd + Copy + std::fmt::Debug + Send + Sync + 'static + Default>
1515
{
1616
#[inline]
1717
pub fn fetch_block<'a>(&'a mut self, docs: &'a [u32], accessor: &Column<T>) {
18-
if accessor.index.get_cardinality().is_full() {
19-
self.val_cache.resize(docs.len(), T::default());
18+
self.fetch_block_with_is_full(docs, accessor, accessor.index.get_cardinality().is_full());
19+
}
20+
21+
/// Like [`Self::fetch_block`] but takes the column's fullness instead of querying
22+
/// `accessor.index.get_cardinality()` each call — for callers that know it up front (e.g.
23+
/// checked once at construction). `is_full` must equal
24+
/// `accessor.index.get_cardinality().is_full()`.
25+
#[inline]
26+
pub fn fetch_block_with_is_full<'a>(
27+
&'a mut self,
28+
docs: &'a [u32],
29+
accessor: &Column<T>,
30+
is_full: bool,
31+
) {
32+
if is_full {
33+
// Skip the resize when already the right length (common case: fixed-size blocks).
34+
if self.val_cache.len() != docs.len() {
35+
self.val_cache.resize(docs.len(), T::default());
36+
}
2037
// When the docs form a contiguous ascending run we can fetch the values
2138
// as a single range. This lets codecs (e.g. bitpacked) bulk-decode the
2239
// slice instead of gathering value-by-value, and avoids per-value dynamic

src/aggregation/bucket/term_agg/term_histogram.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

7073
impl 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

Comments
 (0)