Don't measure in-memory hw for full text indices (#6309)

* Don't measure in-memory full text index

* Clippy

* Fix mmap_postings conditioned counting
This commit is contained in:
Jojii
2025-04-03 19:43:32 +02:00
committed by GitHub
parent 821aa0a33d
commit bf706c21bc
8 changed files with 38 additions and 53 deletions
@@ -21,6 +21,16 @@ impl<'a> ConditionedCounter<'a> {
tmp: HardwareCounterCell::disposable(), // We manually accumulate collected values!
}
}
/// Never measure hardware.
pub fn never(parent: &'a HardwareCounterCell) -> Self {
Self::new(false, parent)
}
/// Always measure hardware.
pub fn always(parent: &'a HardwareCounterCell) -> Self {
Self::new(true, parent)
}
}
impl Deref for ConditionedCounter<'_> {
@@ -181,7 +181,7 @@ impl FieldIndex {
let query = full_text_index.parse_query(text, hw_counter);
for value in FullTextIndex::get_values(payload_value) {
let document = full_text_index.parse_document(&value, hw_counter);
if query.check_match(&document, hw_counter) {
if query.check_match(&document) {
return Some(true);
}
}
@@ -1,5 +1,5 @@
use bitpacking::BitPacker;
use common::counter::hardware_counter::HardwareCounterCell;
use common::counter::conditioned_counter::ConditionedCounter;
use common::types::PointOffsetType;
use crate::index::field_index::full_text_index::compressed_posting::compressed_common::{
@@ -11,7 +11,7 @@ pub struct ChunkReader<'a> {
chunks: &'a [CompressedPostingChunksIndex],
data: &'a [u8],
remainder_postings: &'a [PointOffsetType],
hw_counter: &'a HardwareCounterCell,
hw_counter: ConditionedCounter<'a>,
}
impl<'a> ChunkReader<'a> {
@@ -20,7 +20,7 @@ impl<'a> ChunkReader<'a> {
chunks: &'a [CompressedPostingChunksIndex],
data: &'a [u8],
reminder_postings: &'a [PointOffsetType],
hw_counter: &'a HardwareCounterCell,
hw_counter: ConditionedCounter<'a>,
) -> Self {
Self {
data,
@@ -1,4 +1,5 @@
use bitpacking::BitPacker;
use common::counter::conditioned_counter::ConditionedCounter;
use common::counter::hardware_counter::HardwareCounterCell;
use common::types::PointOffsetType;
@@ -41,7 +42,7 @@ impl CompressedPostingList {
&self.chunks,
&self.data,
&self.remainder_postings,
hw_counter,
ConditionedCounter::never(hw_counter),
)
}
@@ -1,7 +1,6 @@
use std::collections::HashMap;
use common::counter::hardware_counter::HardwareCounterCell;
use common::mmap_hashmap::BUCKET_OFFSET_OVERHEAD;
use common::types::PointOffsetType;
use super::inverted_index::InvertedIndex;
@@ -71,6 +70,8 @@ impl InvertedIndex for ImmutableInvertedIndex {
let posting_readers: Vec<_> = postings
.iter()
// We can safely pass hw_counter here because it's not measured.
// Due to lifetime issues, we can't return a disposable counter.
.map(|posting| posting.reader(hw_counter))
.collect();
@@ -81,16 +82,8 @@ impl InvertedIndex for ImmutableInvertedIndex {
intersect_compressed_postings_iterator(posting_readers, filter)
}
fn get_posting_len(
&self,
token_id: TokenId,
hw_counter: &HardwareCounterCell,
) -> Option<usize> {
let len = self.postings.get(token_id as usize).map(|p| p.len());
hw_counter
.payload_index_io_read_counter()
.incr_delta(size_of::<Option<CompressedPostingList>>());
len
fn get_posting_len(&self, token_id: TokenId, _: &HardwareCounterCell) -> Option<usize> {
self.postings.get(token_id as usize).map(|p| p.len())
}
fn vocab_with_postings_len_iter(&self) -> impl Iterator<Item = (&str, usize)> + '_ {
@@ -105,7 +98,7 @@ impl InvertedIndex for ImmutableInvertedIndex {
&self,
parsed_query: &ParsedQuery,
point_id: PointOffsetType,
hw_counter: &HardwareCounterCell,
_: &HardwareCounterCell,
) -> bool {
if parsed_query.tokens.contains(&None) {
return false;
@@ -114,6 +107,9 @@ impl InvertedIndex for ImmutableInvertedIndex {
if self.values_is_empty(point_id) {
return false;
}
let disposed_hw = HardwareCounterCell::disposable();
// Check that all tokens are in document
parsed_query
.tokens
@@ -121,7 +117,7 @@ impl InvertedIndex for ImmutableInvertedIndex {
// unwrap crash safety: all tokens exist in the vocabulary if it passes the above check
.all(|query_token| {
let postings = &self.postings[query_token.unwrap() as usize];
postings.reader(hw_counter).contains(point_id)
postings.reader(&disposed_hw).contains(point_id)
})
}
@@ -142,10 +138,7 @@ impl InvertedIndex for ImmutableInvertedIndex {
self.points_count
}
fn get_token_id(&self, token: &str, hw_counter: &HardwareCounterCell) -> Option<TokenId> {
hw_counter
.payload_index_io_read_counter()
.incr_delta(BUCKET_OFFSET_OVERHEAD + size_of::<TokenId>());
fn get_token_id(&self, token: &str, _: &HardwareCounterCell) -> Option<TokenId> {
self.vocab.get(token).copied()
}
}
@@ -44,15 +44,11 @@ pub struct ParsedQuery {
}
impl ParsedQuery {
pub fn check_match(&self, document: &Document, hw_counter: &HardwareCounterCell) -> bool {
pub fn check_match(&self, document: &Document) -> bool {
if self.tokens.contains(&None) {
return false;
}
hw_counter
.payload_index_io_read_counter()
.incr_delta((self.tokens.len() + document.tokens().len()) * size_of::<TokenId>());
// Check that all tokens are in document
self.tokens
.iter()
@@ -2,6 +2,7 @@ use std::io;
use std::io::Write;
use std::path::PathBuf;
use common::counter::conditioned_counter::ConditionedCounter;
use common::counter::hardware_counter::HardwareCounterCell;
use common::types::PointOffsetType;
use common::zeros::WriteZerosExt;
@@ -65,6 +66,7 @@ pub struct MmapPostings {
_path: PathBuf,
mmap: Mmap,
header: PostingsHeader,
on_disk: bool,
}
impl MmapPostings {
@@ -121,7 +123,7 @@ impl MmapPostings {
chunks,
data,
remainder_postings,
hw_counter,
ConditionedCounter::new(self.on_disk, hw_counter),
))
}
@@ -227,6 +229,7 @@ impl MmapPostings {
_path: path,
mmap,
header,
on_disk: !populate,
})
}
}
@@ -1,7 +1,6 @@
use std::collections::{BTreeSet, HashMap};
use common::counter::hardware_counter::HardwareCounterCell;
use common::mmap_hashmap::BUCKET_OFFSET_OVERHEAD;
use common::types::PointOffsetType;
use super::inverted_index::InvertedIndex;
@@ -147,9 +146,8 @@ impl InvertedIndex for MutableInvertedIndex {
fn filter(
&self,
query: ParsedQuery,
hw_counter: &HardwareCounterCell,
_hw_counter: &HardwareCounterCell,
) -> Box<dyn Iterator<Item = PointOffsetType> + '_> {
let hw_counter = hw_counter.payload_index_io_read_counter();
let postings_opt: Option<Vec<_>> = query
.tokens
.iter()
@@ -159,10 +157,6 @@ impl InvertedIndex for MutableInvertedIndex {
// dictionary. Posting list entry can be None but it exists.
Some(idx) => {
let postings = self.postings.get(idx as usize).unwrap().as_ref();
hw_counter.incr_delta(
size_of::<Option<PostingList>>()
+ postings.map(|i| i.len()).unwrap_or(0) * size_of::<PointOffsetType>(),
);
postings
}
})
@@ -179,21 +173,12 @@ impl InvertedIndex for MutableInvertedIndex {
intersect_postings_iterator(postings)
}
fn get_posting_len(
&self,
token_id: TokenId,
hw_counter: &HardwareCounterCell,
) -> Option<usize> {
let len = self
.postings
fn get_posting_len(&self, token_id: TokenId, _: &HardwareCounterCell) -> Option<usize> {
self.postings
.get(token_id as usize)
.and_then(|posting| posting.as_ref())
.as_ref()
.map(|x| x.len());
hw_counter.payload_index_io_read_counter().incr_delta(
size_of::<Option<PostingList>>() + len.unwrap_or(0) * size_of::<PointOffsetType>(),
);
len
.map(|x| x.len())
}
fn vocab_with_postings_len_iter(&self) -> impl Iterator<Item = (&str, usize)> + '_ {
@@ -210,10 +195,10 @@ impl InvertedIndex for MutableInvertedIndex {
&self,
parsed_query: &ParsedQuery,
point_id: PointOffsetType,
hw_counter: &HardwareCounterCell,
_: &HardwareCounterCell,
) -> bool {
if let Some(doc) = self.get_doc(point_id) {
parsed_query.check_match(doc, hw_counter)
parsed_query.check_match(doc)
} else {
false
}
@@ -232,10 +217,7 @@ impl InvertedIndex for MutableInvertedIndex {
self.points_count
}
fn get_token_id(&self, token: &str, hw_counter: &HardwareCounterCell) -> Option<TokenId> {
hw_counter
.payload_index_io_read_counter()
.incr_delta(BUCKET_OFFSET_OVERHEAD + size_of::<TokenId>());
fn get_token_id(&self, token: &str, _hw_counter: &HardwareCounterCell) -> Option<TokenId> {
self.vocab.get(token).copied()
}
}