diff --git a/src/postings/mod.rs b/src/postings/mod.rs index 63071fc2b..4055f66b9 100644 --- a/src/postings/mod.rs +++ b/src/postings/mod.rs @@ -76,6 +76,58 @@ mod tests { assert!(read.len() <= 140); } + #[test] + pub fn test_skip_positions() { + let mut schema_builder = SchemaBuilder::new(); + let title = schema_builder.add_text_field("title", TEXT); + let schema = schema_builder.build(); + let index = Index::create_in_ram(schema); + let mut index_writer = index.writer_with_num_threads(1, 30_000_000).unwrap(); + index_writer.add_document(doc!(title => r#"abc abc abc"#)); + index_writer.add_document(doc!(title => r#"abc be be be be abc"#)); + for _ in 0..1_000 { + index_writer.add_document(doc!(title => r#"abc abc abc"#)); + } + index_writer.add_document(doc!(title => r#"abc be be be be abc"#)); + index_writer.commit().unwrap(); + index.load_searchers().unwrap(); + let searcher = index.searcher(); + let query = TermQuery::new(Term::from_field_text(title, "abc"), IndexRecordOption::WithFreqsAndPositions); + let weight = query.specialized_weight(&*searcher); + { + let mut scorer = weight.specialized_scorer(searcher.segment_reader(0u32)).unwrap(); + scorer.advance(); + assert_eq!(&[0,1,2], scorer.postings().positions()); + scorer.advance(); + assert_eq!(&[0,5], scorer.postings().positions()); + } + { + let mut scorer = weight.specialized_scorer(searcher.segment_reader(0u32)).unwrap(); + scorer.advance(); + scorer.advance(); + assert_eq!(&[0,5], scorer.postings().positions()); + } + { + let mut scorer = weight.specialized_scorer(searcher.segment_reader(0u32)).unwrap(); + assert_eq!(scorer.skip_next(1), SkipResult::Reached); + assert_eq!(scorer.doc(), 1); + assert_eq!(&[0,5], scorer.postings().positions()); + } + { + let mut scorer = weight.specialized_scorer(searcher.segment_reader(0u32)).unwrap(); + assert_eq!(scorer.skip_next(1002), SkipResult::Reached); + assert_eq!(scorer.doc(), 1002); + assert_eq!(&[0,5], scorer.postings().positions()); + } + { + let mut scorer = weight.specialized_scorer(searcher.segment_reader(0u32)).unwrap(); + assert_eq!(scorer.skip_next(100), SkipResult::Reached); + assert_eq!(scorer.skip_next(1002), SkipResult::Reached); + assert_eq!(scorer.doc(), 1002); + assert_eq!(&[0,5], scorer.postings().positions()); + } + } + #[test] pub fn test_position_and_fieldnorm1() { let mut schema_builder = SchemaBuilder::default(); diff --git a/src/postings/segment_postings.rs b/src/postings/segment_postings.rs index a69ae5e73..682fc82f6 100644 --- a/src/postings/segment_postings.rs +++ b/src/postings/segment_postings.rs @@ -40,7 +40,6 @@ impl PositionComputer { pub fn positions(&mut self, term_freq: usize) -> &[u32] { if let Some(num_skip) = self.position_to_skip { self.positions.resize(term_freq, 0u32); - self.positions_stream.skip(num_skip); self.positions_stream.read(&mut self.positions[..term_freq]); @@ -116,6 +115,7 @@ impl DocSet for SegmentPostings { #[inline] fn advance(&mut self) -> bool { loop { + self.position_add_skip(|| self.term_freq() as usize); self.cur += 1; if self.cur >= self.block_cursor.block_len() { self.cur = 0; @@ -124,7 +124,6 @@ impl DocSet for SegmentPostings { return false; } } - self.position_add_skip(|| self.term_freq() as usize); if !self.delete_bitset.is_deleted(self.doc()) { return true; }