diff --git a/src/indexer/index_writer.rs b/src/indexer/index_writer.rs index 66ab10e28..df6a47ca1 100644 --- a/src/indexer/index_writer.rs +++ b/src/indexer/index_writer.rs @@ -142,8 +142,7 @@ pub(crate) fn advance_deletes( return Ok(()); } - let mut delete_cursor = segment_entry.delete_cursor().clone(); - if segment_entry.delete_bitset().is_none() && delete_cursor.get().is_none() { + if segment_entry.delete_bitset().is_none() && segment_entry.delete_cursor().get().is_none() { // There has been no `DeleteOperation` between the segment status and `target_opstamp`. return Ok(()); } @@ -159,7 +158,7 @@ pub(crate) fn advance_deletes( compute_deleted_bitset( &mut delete_bitset, &segment_reader, - &mut delete_cursor, + segment_entry.delete_cursor(), &DocToOpstampMapping::None, target_opstamp, )?; diff --git a/src/lib.rs b/src/lib.rs index de3f2705a..5db79a1ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -940,4 +940,73 @@ mod tests { assert_eq!(fast_field_reader.get(0), 4f64) } } + + // motivated by #729 + #[test] + fn test_update_via_delete_insert() { + use crate::collector::Count; + use crate::indexer::NoMergePolicy; + use crate::query::AllQuery; + use crate::SegmentId; + use futures::executor::block_on; + + const DOC_COUNT: u64 = 2u64; + + let mut schema_builder = SchemaBuilder::default(); + let id = schema_builder.add_u64_field("id", INDEXED); + let schema = schema_builder.build(); + + let index = Index::create_in_ram(schema.clone()); + let index_reader = index.reader().unwrap(); + + let mut index_writer = index.writer(3_000_000).unwrap(); + index_writer.set_merge_policy(Box::new(NoMergePolicy)); + + for doc_id in 0u64..DOC_COUNT { + index_writer.add_document(doc!(id => doc_id)); + } + index_writer.commit().unwrap(); + + index_reader.reload().unwrap(); + let searcher = index_reader.searcher(); + + assert_eq!( + searcher.search(&AllQuery, &Count).unwrap(), + DOC_COUNT as usize + ); + + // update the 10 elements by deleting and re-adding + for doc_id in 0u64..DOC_COUNT { + index_writer.delete_term(Term::from_field_u64(id, doc_id)); + index_writer.commit().unwrap(); + index_reader.reload().unwrap(); + let doc = doc!(id => doc_id); + index_writer.add_document(doc); + index_writer.commit().unwrap(); + index_reader.reload().unwrap(); + let searcher = index_reader.searcher(); + // The number of document should be stable. + assert_eq!( + searcher.search(&AllQuery, &Count).unwrap(), + DOC_COUNT as usize + ); + } + + index_reader.reload().unwrap(); + let searcher = index_reader.searcher(); + let segment_ids: Vec = searcher + .segment_readers() + .into_iter() + .map(|reader| reader.segment_id()) + .collect(); + block_on(index_writer.merge(&segment_ids)).unwrap(); + + index_reader.reload().unwrap(); + let searcher = index_reader.searcher(); + + assert_eq!( + searcher.search(&AllQuery, &Count).unwrap(), + DOC_COUNT as usize + ); + } }