diff --git a/quickwit/quickwit-search/src/collector.rs b/quickwit/quickwit-search/src/collector.rs index 8ec9faf31ac..b674616ebdf 100644 --- a/quickwit/quickwit-search/src/collector.rs +++ b/quickwit/quickwit-search/src/collector.rs @@ -502,10 +502,11 @@ enum AggregationSegmentCollectors { pub struct QuickwitSegmentCollector { timestamp_filter_opt: Option, segment_top_k_collector: Option, - // Caches for block fetching - filtered_docs: Box<[DocId; 64]>, aggregation: Option, num_hits: u64, + // Caches for block fetching + filtered_docs: Box<[DocId; 64]>, + timestamps_buffer: Box<[Option; 64]>, } impl QuickwitSegmentCollector { @@ -786,18 +787,20 @@ fn compute_filtered_block<'a>( timestamp_filter_opt: &Option, docs: &'a [DocId], filtered_docs_buffer: &'a mut [DocId; COLLECT_BLOCK_BUFFER_LEN], + timestamps_buffer: &'a mut [Option; COLLECT_BLOCK_BUFFER_LEN], ) -> &'a [DocId] { let Some(timestamp_filter) = ×tamp_filter_opt else { return docs; }; + timestamp_filter.fetch_timestamps(docs, timestamps_buffer); let mut len = 0; - for &doc in docs { - filtered_docs_buffer[len] = doc; - len += if timestamp_filter.is_within_range(doc) { - 1 + for (doc, date) in docs.iter().zip(timestamps_buffer.iter()) { + filtered_docs_buffer[len] = *doc; + len += if let Some(ts) = date { + timestamp_filter.contains(ts) as usize } else { 0 - }; + } } &filtered_docs_buffer[..len] } @@ -811,6 +814,7 @@ impl SegmentCollector for QuickwitSegmentCollector { &self.timestamp_filter_opt, unfiltered_docs, &mut self.filtered_docs, + &mut self.timestamps_buffer, ); // Update results @@ -1118,6 +1122,7 @@ impl Collector for QuickwitCollector { segment_top_k_collector, aggregation, filtered_docs: Box::new([0; 64]), + timestamps_buffer: Box::new([None; 64]), }) } diff --git a/quickwit/quickwit-search/src/filters.rs b/quickwit/quickwit-search/src/filters.rs index 2a37e7efcc7..9a47493d877 100644 --- a/quickwit/quickwit-search/src/filters.rs +++ b/quickwit/quickwit-search/src/filters.rs @@ -33,10 +33,20 @@ pub struct TimestampFilter { } impl TimestampFilter { + #[inline] + pub fn fetch_timestamps<'a>(&self, docs: &'a [DocId], dates: &'a mut [Option]) { + self.timestamp_column + .first_vals(docs, &mut dates[..docs.len()]); + } + #[inline] + pub fn contains(&self, ts: &DateTime) -> bool { + self.time_range.contains(ts) + } + #[inline] pub fn is_within_range(&self, doc_id: DocId) -> bool { if let Some(ts) = self.timestamp_column.first(doc_id) { - self.time_range.contains(&ts) + self.contains(&ts) } else { false }