Skip to content

Commit 6470bb7

Browse files
authored
Merge pull request #76 from meilisearch/panic-at-search
Fix panic at search when the index is empty
2 parents 7d65b82 + 2128749 commit 6470bb7

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

src/reader.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ impl<'t, D: Distance> Reader<'t, D> {
203203
search_k: Option<NonZeroUsize>,
204204
candidates: Option<&RoaringBitmap>,
205205
) -> Result<Vec<(ItemId, f32)>> {
206+
if self.items.is_empty() {
207+
return Ok(Vec::new());
208+
}
206209
// Since the datastructure describes a kind of btree, the capacity is something in the order of:
207210
// The number of root nodes + log2 of the total number of vectors.
208211
let mut queue =

src/tests/reader.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,19 @@ fn filtering() {
203203
id(99): distance(99)
204204
"###);
205205
}
206+
207+
#[test]
208+
fn search_in_empty_database() {
209+
// See https://github.com/meilisearch/arroy/issues/74
210+
let handle = create_database::<Euclidean>();
211+
212+
let mut wtxn = handle.env.write_txn().unwrap();
213+
let writer = Writer::new(handle.database, 0, 2);
214+
writer.build(&mut wtxn, &mut rng(), None).unwrap();
215+
wtxn.commit().unwrap();
216+
217+
let rtxn = handle.env.read_txn().unwrap();
218+
let reader = Reader::open(&rtxn, 0, handle.database).unwrap();
219+
let ret = reader.nns_by_vector(&rtxn, &[0., 0.], 10, None, None).unwrap();
220+
insta::assert_debug_snapshot!(ret, @"[]");
221+
}

src/tests/writer.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rand::seq::SliceRandom;
33
use rand::Rng;
44

55
use super::{create_database, rng};
6-
use crate::distance::{DotProduct, Euclidean};
6+
use crate::distance::{Angular, DotProduct, Euclidean};
77
use crate::{Database, Reader, Writer};
88

99
#[test]
@@ -467,6 +467,43 @@ fn delete_one_leaf_in_a_split() {
467467
"###);
468468
}
469469

470+
#[test]
471+
fn delete_one_item_in_a_single_document_database() {
472+
let handle = create_database::<Angular>();
473+
let mut rng = rng();
474+
let mut wtxn = handle.env.write_txn().unwrap();
475+
let writer = Writer::new(handle.database, 0, 2);
476+
477+
// first, insert a bunch of elements
478+
writer.add_item(&mut wtxn, 0, &[0., 0.]).unwrap();
479+
writer.build(&mut wtxn, &mut rng, None).unwrap();
480+
wtxn.commit().unwrap();
481+
482+
insta::assert_display_snapshot!(handle, @r###"
483+
==================
484+
Dumping index 0
485+
Item 0: Leaf(Leaf { header: NodeHeaderAngular { norm: 0.0 }, vector: [0.0000, 0.0000] })
486+
Tree 0: Descendants(Descendants { descendants: [0] })
487+
Root: Metadata { dimensions: 2, items: RoaringBitmap<[0]>, roots: [0], distance: "angular" }
488+
updated_item_ids: RoaringBitmap<[]>
489+
"###);
490+
491+
let mut wtxn = handle.env.write_txn().unwrap();
492+
let writer = Writer::new(handle.database, 0, 2);
493+
494+
writer.del_item(&mut wtxn, 0).unwrap();
495+
496+
writer.build(&mut wtxn, &mut rng, None).unwrap();
497+
wtxn.commit().unwrap();
498+
499+
insta::assert_display_snapshot!(handle, @r###"
500+
==================
501+
Dumping index 0
502+
Root: Metadata { dimensions: 2, items: RoaringBitmap<[]>, roots: [], distance: "angular" }
503+
updated_item_ids: RoaringBitmap<[]>
504+
"###);
505+
}
506+
470507
#[test]
471508
fn delete_one_item() {
472509
let handle = create_database::<Euclidean>();

0 commit comments

Comments
 (0)