diff --git a/src/indexer/merger.rs b/src/indexer/merger.rs index 65b9594cb..9fd394dc3 100644 --- a/src/indexer/merger.rs +++ b/src/indexer/merger.rs @@ -1263,54 +1263,6 @@ mod tests { Ok(()) } - #[test] - fn test_fuzzy_index_merger_with_deletes() -> crate::Result<()> { - let mut schema_builder = schema::Schema::builder(); - let id_field = schema_builder.add_u64_field("id", INDEXED | FAST | STORED); - let title_field = schema_builder.add_text_field("title", TEXT | STORED); - let schema = schema_builder.build(); - - let index = Index::create_in_ram(schema); - let index_reader = index.reader().unwrap(); - let mut index_writer = index.writer(50_000_000).unwrap(); - - let create_doc = |id: u64| -> Document { - let mut doc = Document::default(); - doc.add_text(title_field, format!("Hello world {}", id)); - doc.add_u64(id_field, id); - doc - }; - - let mut created = 0; - let mut deleted = 0; - let count_docs = || -> usize { - let searcher = index_reader.searcher(); - searcher.search(&AllQuery, &Count).unwrap() - }; - - for i in 0..50 { - let start_id = i * 1000; - - for a in 0..1000 { - let doc = create_doc(start_id + a); - index_writer.add_document(doc); - created += 1; - } - index_writer.commit().unwrap(); - - for a in 10..980 { - index_writer.delete_term(Term::from_field_u64(id_field, start_id + a)); - deleted += 1; - } - index_writer.commit().unwrap(); - } - - index_reader.reload().unwrap(); - assert_eq!(created - deleted, count_docs()); - - Ok(()) - } - #[test] fn test_index_merger_with_deletes() -> crate::Result<()> { let mut schema_builder = schema::Schema::builder(); diff --git a/src/store/mod.rs b/src/store/mod.rs index e5803f9f7..860407bcf 100644 --- a/src/store/mod.rs +++ b/src/store/mod.rs @@ -57,6 +57,7 @@ pub mod tests { use futures::executor::block_on; use super::*; + use crate::fastfield::DeleteBitSet; use crate::schema::{self, FieldValue, TextFieldIndexing, STORED, TEXT}; use crate::schema::{Document, TextOptions}; use crate::{ @@ -107,15 +108,51 @@ pub mod tests { schema } + const NUM_DOCS: usize = 1_000; + #[test] + fn test_doc_store_iter_with_delete_bug_1077() -> crate::Result<()> { + // this will cover deletion of the first element in a checkpoint + let deleted_docids = (200..300).collect::>(); + let delete_bitset = DeleteBitSet::for_test(&deleted_docids, NUM_DOCS as u32); + + let path = Path::new("store"); + let directory = RamDirectory::create(); + let store_wrt = directory.open_write(path)?; + let schema = write_lorem_ipsum_store(store_wrt, NUM_DOCS, Compressor::Lz4); + let field_title = schema.get_field("title").unwrap(); + let store_file = directory.open_read(path)?; + let store = StoreReader::open(store_file)?; + for i in 0..NUM_DOCS as u32 { + assert_eq!( + *store + .get(i)? + .get_first(field_title) + .unwrap() + .text() + .unwrap(), + format!("Doc {}", i) + ); + } + for (_, doc) in store.iter(Some(&delete_bitset)).enumerate() { + let doc = doc?; + let title_content = doc.get_first(field_title).unwrap().text().unwrap(); + if !title_content.starts_with("Doc ") { + panic!("unexpected title_content {}", title_content); + } + } + + Ok(()) + } + fn test_store(compressor: Compressor) -> crate::Result<()> { let path = Path::new("store"); let directory = RamDirectory::create(); let store_wrt = directory.open_write(path)?; - let schema = write_lorem_ipsum_store(store_wrt, 1_000, compressor); + let schema = write_lorem_ipsum_store(store_wrt, NUM_DOCS, compressor); let field_title = schema.get_field("title").unwrap(); let store_file = directory.open_read(path)?; let store = StoreReader::open(store_file)?; - for i in 0..1_000 { + for i in 0..NUM_DOCS as u32 { assert_eq!( *store .get(i)?