Add more tests and allow disabling of soft-deletion outside of tests

Also allow disabling soft-deletion in the IndexDocumentsConfig
This commit is contained in:
Loïc Lecrenier
2022-12-05 10:33:31 +01:00
parent d3731dda48
commit f2cf981641
89 changed files with 2171 additions and 54 deletions

View File

@ -66,6 +66,9 @@ impl<'t, 'u, 'i> PrefixWordPairsProximityDocids<'t, 'u, 'i> {
common_prefix_fst_words: &[&'a [String]],
del_prefix_fst_words: &HashSet<Vec<u8>>,
) -> Result<()> {
println!("{new_prefix_fst_words:?}");
println!("{common_prefix_fst_words:?}");
println!("{del_prefix_fst_words:?}");
index_word_prefix_database(
self.wtxn,
self.index.word_pair_proximity_docids,
@ -156,30 +159,40 @@ pub fn write_into_lmdb_database_without_merging(
#[cfg(test)]
mod tests {
use std::io::Cursor;
use std::iter::FromIterator;
use roaring::RoaringBitmap;
use crate::db_snap;
use crate::documents::{DocumentsBatchBuilder, DocumentsBatchReader};
use crate::index::tests::TempIndex;
use crate::update::{DeleteDocuments, IndexDocumentsMethod};
fn documents_with_enough_different_words_for_prefixes(prefixes: &[&str]) -> Vec<crate::Object> {
fn documents_with_enough_different_words_for_prefixes(
prefixes: &[&str],
start_id: usize,
) -> Vec<crate::Object> {
let mut documents = Vec::new();
let mut id = start_id;
for prefix in prefixes {
for i in 0..50 {
documents.push(
serde_json::json!({
"id": id,
"text": format!("{prefix}{i:x}"),
})
.as_object()
.unwrap()
.clone(),
)
);
id += 1;
}
}
documents
}
#[test]
fn test_update() {
fn add_new_documents() {
let mut index = TempIndex::new();
index.index_documents_config.words_prefix_threshold = Some(50);
index.index_documents_config.autogenerate_docids = true;
@ -198,10 +211,11 @@ mod tests {
DocumentsBatchReader::from_reader(Cursor::new(builder.into_inner().unwrap())).unwrap()
};
let mut documents = documents_with_enough_different_words_for_prefixes(&["a", "be"]);
let mut documents = documents_with_enough_different_words_for_prefixes(&["a", "be"], 0);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
documents.push(
serde_json::json!({
"id": "9000",
"text": "At an amazing and beautiful house"
})
.as_object()
@ -210,6 +224,7 @@ mod tests {
);
documents.push(
serde_json::json!({
"id": "9001",
"text": "The bell rings at 5 am"
})
.as_object()
@ -221,10 +236,12 @@ mod tests {
index.add_documents(documents).unwrap();
db_snap!(index, word_prefix_pair_proximity_docids, "initial");
db_snap!(index, prefix_word_pair_proximity_docids, "initial");
let mut documents = documents_with_enough_different_words_for_prefixes(&["am", "an"]);
let mut documents = documents_with_enough_different_words_for_prefixes(&["am", "an"], 100);
documents.push(
serde_json::json!({
"id": "9002",
"text": "At an extraordinary house"
})
.as_object()
@ -239,7 +256,7 @@ mod tests {
db_snap!(index, prefix_word_pair_proximity_docids, "update");
}
#[test]
fn test_batch_bug_3043() {
fn batch_bug_3043() {
// https://github.com/meilisearch/meilisearch/issues/3043
let mut index = TempIndex::new();
index.index_documents_config.words_prefix_threshold = Some(50);
@ -259,7 +276,7 @@ mod tests {
DocumentsBatchReader::from_reader(Cursor::new(builder.into_inner().unwrap())).unwrap()
};
let mut documents = documents_with_enough_different_words_for_prefixes(&["y"]);
let mut documents = documents_with_enough_different_words_for_prefixes(&["y"], 0);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
documents.push(
serde_json::json!({
@ -285,4 +302,291 @@ mod tests {
db_snap!(index, word_prefix_pair_proximity_docids);
db_snap!(index, prefix_word_pair_proximity_docids);
}
#[test]
fn hard_delete_and_reupdate() {
let mut index = TempIndex::new();
index.index_documents_config.words_prefix_threshold = Some(50);
index
.update_settings(|settings| {
settings.set_primary_key("id".to_owned());
settings.set_searchable_fields(vec!["text".to_owned()]);
})
.unwrap();
let batch_reader_from_documents = |documents| {
let mut builder = DocumentsBatchBuilder::new(Vec::new());
for object in documents {
builder.append_json_object(&object).unwrap();
}
DocumentsBatchReader::from_reader(Cursor::new(builder.into_inner().unwrap())).unwrap()
};
let mut documents = documents_with_enough_different_words_for_prefixes(&["a"], 0);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
documents.push(
serde_json::json!({
"id": 9000,
"text": "At an amazing and beautiful house"
})
.as_object()
.unwrap()
.clone(),
);
documents.push(
serde_json::json!({
"id": 9001,
"text": "The bell rings at 5 am"
})
.as_object()
.unwrap()
.clone(),
);
let documents = batch_reader_from_documents(documents);
index.add_documents(documents).unwrap();
db_snap!(index, documents_ids, "initial");
db_snap!(index, word_docids, "initial");
db_snap!(index, word_prefix_pair_proximity_docids, "initial");
db_snap!(index, prefix_word_pair_proximity_docids, "initial");
let mut wtxn = index.write_txn().unwrap();
let mut delete = DeleteDocuments::new(&mut wtxn, &index).unwrap();
delete.disable_soft_deletion(true);
delete.delete_documents(&RoaringBitmap::from_iter([50]));
delete.execute().unwrap();
wtxn.commit().unwrap();
db_snap!(index, documents_ids, "first_delete");
db_snap!(index, word_docids, "first_delete");
db_snap!(index, word_prefix_pair_proximity_docids, "first_delete");
db_snap!(index, prefix_word_pair_proximity_docids, "first_delete");
let mut wtxn = index.write_txn().unwrap();
let mut delete = DeleteDocuments::new(&mut wtxn, &index).unwrap();
delete.disable_soft_deletion(true);
delete.delete_documents(&RoaringBitmap::from_iter(0..50));
delete.execute().unwrap();
wtxn.commit().unwrap();
db_snap!(index, documents_ids, "second_delete");
db_snap!(index, word_docids, "second_delete");
db_snap!(index, word_prefix_pair_proximity_docids, "second_delete");
db_snap!(index, prefix_word_pair_proximity_docids, "second_delete");
let documents = documents_with_enough_different_words_for_prefixes(&["b"], 1000);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
index.add_documents(batch_reader_from_documents(documents)).unwrap();
db_snap!(index, documents_ids, "reupdate");
db_snap!(index, word_docids, "reupdate");
db_snap!(index, word_prefix_pair_proximity_docids, "reupdate");
db_snap!(index, prefix_word_pair_proximity_docids, "reupdate");
}
#[test]
fn soft_delete_and_reupdate() {
let mut index = TempIndex::new();
index.index_documents_config.words_prefix_threshold = Some(50);
index
.update_settings(|settings| {
settings.set_primary_key("id".to_owned());
settings.set_searchable_fields(vec!["text".to_owned()]);
})
.unwrap();
let batch_reader_from_documents = |documents| {
let mut builder = DocumentsBatchBuilder::new(Vec::new());
for object in documents {
builder.append_json_object(&object).unwrap();
}
DocumentsBatchReader::from_reader(Cursor::new(builder.into_inner().unwrap())).unwrap()
};
let mut documents = documents_with_enough_different_words_for_prefixes(&["a"], 0);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
documents.push(
serde_json::json!({
"id": 9000,
"text": "At an amazing and beautiful house"
})
.as_object()
.unwrap()
.clone(),
);
documents.push(
serde_json::json!({
"id": 9001,
"text": "The bell rings at 5 am"
})
.as_object()
.unwrap()
.clone(),
);
let documents = batch_reader_from_documents(documents);
index.add_documents(documents).unwrap();
db_snap!(index, documents_ids, "initial");
db_snap!(index, word_docids, "initial");
db_snap!(index, word_prefix_pair_proximity_docids, "initial");
db_snap!(index, prefix_word_pair_proximity_docids, "initial");
let mut wtxn = index.write_txn().unwrap();
let mut delete = DeleteDocuments::new(&mut wtxn, &index).unwrap();
delete.delete_documents(&RoaringBitmap::from_iter([50]));
delete.execute().unwrap();
wtxn.commit().unwrap();
db_snap!(index, documents_ids, "first_delete");
db_snap!(index, word_docids, "first_delete");
db_snap!(index, word_prefix_pair_proximity_docids, "first_delete");
db_snap!(index, prefix_word_pair_proximity_docids, "first_delete");
let mut wtxn = index.write_txn().unwrap();
let mut delete = DeleteDocuments::new(&mut wtxn, &index).unwrap();
delete.delete_documents(&RoaringBitmap::from_iter(0..50));
delete.execute().unwrap();
wtxn.commit().unwrap();
db_snap!(index, documents_ids, "second_delete");
db_snap!(index, word_docids, "second_delete");
db_snap!(index, word_prefix_pair_proximity_docids, "second_delete");
db_snap!(index, prefix_word_pair_proximity_docids, "second_delete");
let documents = documents_with_enough_different_words_for_prefixes(&["b"], 1000);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
index.add_documents(batch_reader_from_documents(documents)).unwrap();
db_snap!(index, documents_ids, "reupdate");
db_snap!(index, word_docids, "reupdate");
db_snap!(index, word_prefix_pair_proximity_docids, "reupdate");
db_snap!(index, prefix_word_pair_proximity_docids, "reupdate");
}
#[test]
fn replace_soft_deletion() {
let mut index = TempIndex::new();
index.index_documents_config.words_prefix_threshold = Some(50);
index.index_documents_config.update_method = IndexDocumentsMethod::ReplaceDocuments;
index
.update_settings(|settings| {
settings.set_primary_key("id".to_owned());
settings.set_searchable_fields(vec!["text".to_owned()]);
})
.unwrap();
let batch_reader_from_documents = |documents| {
let mut builder = DocumentsBatchBuilder::new(Vec::new());
for object in documents {
builder.append_json_object(&object).unwrap();
}
DocumentsBatchReader::from_reader(Cursor::new(builder.into_inner().unwrap())).unwrap()
};
let mut documents = documents_with_enough_different_words_for_prefixes(&["a"], 0);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
documents.push(
serde_json::json!({
"id": 9000,
"text": "At an amazing house"
})
.as_object()
.unwrap()
.clone(),
);
documents.push(
serde_json::json!({
"id": 9001,
"text": "The bell rings"
})
.as_object()
.unwrap()
.clone(),
);
let documents = batch_reader_from_documents(documents);
index.add_documents(documents).unwrap();
db_snap!(index, documents_ids, "initial");
db_snap!(index, word_docids, "initial");
db_snap!(index, word_prefix_pair_proximity_docids, "initial");
db_snap!(index, prefix_word_pair_proximity_docids, "initial");
let documents = documents_with_enough_different_words_for_prefixes(&["b"], 0);
index.add_documents(batch_reader_from_documents(documents)).unwrap();
db_snap!(index, documents_ids, "replaced");
db_snap!(index, word_docids, "replaced");
db_snap!(index, word_prefix_pair_proximity_docids, "replaced");
db_snap!(index, prefix_word_pair_proximity_docids, "replaced");
db_snap!(index, soft_deleted_documents_ids, "replaced", @"[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ]");
}
#[test]
fn replace_hard_deletion() {
let mut index = TempIndex::new();
index.index_documents_config.words_prefix_threshold = Some(50);
index.index_documents_config.disable_soft_deletion = true;
index.index_documents_config.update_method = IndexDocumentsMethod::ReplaceDocuments;
index
.update_settings(|settings| {
settings.set_primary_key("id".to_owned());
settings.set_searchable_fields(vec!["text".to_owned()]);
})
.unwrap();
let batch_reader_from_documents = |documents| {
let mut builder = DocumentsBatchBuilder::new(Vec::new());
for object in documents {
builder.append_json_object(&object).unwrap();
}
DocumentsBatchReader::from_reader(Cursor::new(builder.into_inner().unwrap())).unwrap()
};
let mut documents = documents_with_enough_different_words_for_prefixes(&["a"], 0);
// now we add some documents where the text should populate the word_prefix_pair_proximity_docids database
documents.push(
serde_json::json!({
"id": 9000,
"text": "At an amazing house"
})
.as_object()
.unwrap()
.clone(),
);
documents.push(
serde_json::json!({
"id": 9001,
"text": "The bell rings"
})
.as_object()
.unwrap()
.clone(),
);
let documents = batch_reader_from_documents(documents);
index.add_documents(documents).unwrap();
db_snap!(index, documents_ids, "initial");
db_snap!(index, word_docids, "initial");
db_snap!(index, word_prefix_pair_proximity_docids, "initial");
db_snap!(index, prefix_word_pair_proximity_docids, "initial");
let documents = documents_with_enough_different_words_for_prefixes(&["b"], 0);
index.add_documents(batch_reader_from_documents(documents)).unwrap();
db_snap!(index, documents_ids, "replaced");
db_snap!(index, word_docids, "replaced");
db_snap!(index, word_prefix_pair_proximity_docids, "replaced");
db_snap!(index, prefix_word_pair_proximity_docids, "replaced");
db_snap!(index, soft_deleted_documents_ids, "replaced", @"[]");
}
}

View File

@ -0,0 +1,20 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [101, ]
1 a amazing [100, ]
1 a an [100, ]
1 a and [100, ]
1 a beautiful [100, ]
1 b house [100, ]
1 b rings [101, ]
1 be house [100, ]
1 be rings [101, ]
2 a am [101, ]
2 a amazing [100, ]
2 a and [100, ]
2 a beautiful [100, ]
2 a house [100, ]
2 b at [101, ]
2 be at [101, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, ]

View File

@ -0,0 +1,6 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [51, ]
2 a am [51, ]

View File

@ -0,0 +1,60 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5 [51, ]
a0 [0, ]
a1 [1, ]
a10 [16, ]
a11 [17, ]
a12 [18, ]
a13 [19, ]
a14 [20, ]
a15 [21, ]
a16 [22, ]
a17 [23, ]
a18 [24, ]
a19 [25, ]
a1a [26, ]
a1b [27, ]
a1c [28, ]
a1d [29, ]
a1e [30, ]
a1f [31, ]
a2 [2, ]
a20 [32, ]
a21 [33, ]
a22 [34, ]
a23 [35, ]
a24 [36, ]
a25 [37, ]
a26 [38, ]
a27 [39, ]
a28 [40, ]
a29 [41, ]
a2a [42, ]
a2b [43, ]
a2c [44, ]
a2d [45, ]
a2e [46, ]
a2f [47, ]
a3 [3, ]
a30 [48, ]
a31 [49, ]
a4 [4, ]
a5 [5, ]
a6 [6, ]
a7 [7, ]
a8 [8, ]
a9 [9, ]
aa [10, ]
ab [11, ]
ac [12, ]
ad [13, ]
ae [14, ]
af [15, ]
am [51, ]
at [51, ]
bell [51, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,11 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 5 a [51, ]
1 rings a [51, ]
2 at a [51, ]
2 bell a [51, ]
3 rings a [51, ]
3 the a [51, ]
4 bell a [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, ]

View File

@ -0,0 +1,14 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [51, ]
1 a amazing [50, ]
1 a an [50, ]
1 a and [50, ]
1 a beautiful [50, ]
2 a am [51, ]
2 a amazing [50, ]
2 a and [50, ]
2 a beautiful [50, ]
2 a house [50, ]

View File

@ -0,0 +1,65 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5 [51, ]
a0 [0, ]
a1 [1, ]
a10 [16, ]
a11 [17, ]
a12 [18, ]
a13 [19, ]
a14 [20, ]
a15 [21, ]
a16 [22, ]
a17 [23, ]
a18 [24, ]
a19 [25, ]
a1a [26, ]
a1b [27, ]
a1c [28, ]
a1d [29, ]
a1e [30, ]
a1f [31, ]
a2 [2, ]
a20 [32, ]
a21 [33, ]
a22 [34, ]
a23 [35, ]
a24 [36, ]
a25 [37, ]
a26 [38, ]
a27 [39, ]
a28 [40, ]
a29 [41, ]
a2a [42, ]
a2b [43, ]
a2c [44, ]
a2d [45, ]
a2e [46, ]
a2f [47, ]
a3 [3, ]
a30 [48, ]
a31 [49, ]
a4 [4, ]
a5 [5, ]
a6 [6, ]
a7 [7, ]
a8 [8, ]
a9 [9, ]
aa [10, ]
ab [11, ]
ac [12, ]
ad [13, ]
ae [14, ]
af [15, ]
am [51, ]
amazing [50, ]
an [50, ]
and [50, ]
at [50, 51, ]
beautiful [50, ]
bell [51, ]
house [50, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,16 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 5 a [51, ]
1 amazing a [50, ]
1 an a [50, ]
1 at a [50, ]
1 rings a [51, ]
2 an a [50, ]
2 at a [50, 51, ]
2 bell a [51, ]
3 at a [50, ]
3 rings a [51, ]
3 the a [51, ]
4 bell a [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, ]

View File

@ -0,0 +1,6 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 b rings [51, ]
2 b at [51, ]

View File

@ -0,0 +1,60 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5 [51, ]
am [51, ]
at [51, ]
b0 [0, ]
b1 [1, ]
b10 [16, ]
b11 [17, ]
b12 [18, ]
b13 [19, ]
b14 [20, ]
b15 [21, ]
b16 [22, ]
b17 [23, ]
b18 [24, ]
b19 [25, ]
b1a [26, ]
b1b [27, ]
b1c [28, ]
b1d [29, ]
b1e [30, ]
b1f [31, ]
b2 [2, ]
b20 [32, ]
b21 [33, ]
b22 [34, ]
b23 [35, ]
b24 [36, ]
b25 [37, ]
b26 [38, ]
b27 [39, ]
b28 [40, ]
b29 [41, ]
b2a [42, ]
b2b [43, ]
b2c [44, ]
b2d [45, ]
b2e [46, ]
b2f [47, ]
b3 [3, ]
b30 [48, ]
b31 [49, ]
b4 [4, ]
b5 [5, ]
b6 [6, ]
b7 [7, ]
b8 [8, ]
b9 [9, ]
ba [10, ]
bb [11, ]
bc [12, ]
bd [13, ]
be [14, ]
bell [51, ]
bf [15, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,5 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 the b [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[51, ]

View File

@ -0,0 +1,6 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [51, ]
2 a am [51, ]

View File

@ -0,0 +1,10 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5 [51, ]
am [51, ]
at [51, ]
bell [51, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,11 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 5 a [51, ]
1 rings a [51, ]
2 at a [51, ]
2 bell a [51, ]
3 rings a [51, ]
3 the a [51, ]
4 bell a [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, ]

View File

@ -0,0 +1,9 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a amazing [50, ]
1 a an [50, ]
1 a house [50, ]
2 a amazing [50, ]
2 a house [50, ]

View File

@ -0,0 +1,61 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
a0 [0, ]
a1 [1, ]
a10 [16, ]
a11 [17, ]
a12 [18, ]
a13 [19, ]
a14 [20, ]
a15 [21, ]
a16 [22, ]
a17 [23, ]
a18 [24, ]
a19 [25, ]
a1a [26, ]
a1b [27, ]
a1c [28, ]
a1d [29, ]
a1e [30, ]
a1f [31, ]
a2 [2, ]
a20 [32, ]
a21 [33, ]
a22 [34, ]
a23 [35, ]
a24 [36, ]
a25 [37, ]
a26 [38, ]
a27 [39, ]
a28 [40, ]
a29 [41, ]
a2a [42, ]
a2b [43, ]
a2c [44, ]
a2d [45, ]
a2e [46, ]
a2f [47, ]
a3 [3, ]
a30 [48, ]
a31 [49, ]
a4 [4, ]
a5 [5, ]
a6 [6, ]
a7 [7, ]
a8 [8, ]
a9 [9, ]
aa [10, ]
ab [11, ]
ac [12, ]
ad [13, ]
ae [14, ]
af [15, ]
amazing [50, ]
an [50, ]
at [50, ]
bell [51, ]
house [50, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,7 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 an a [50, ]
1 at a [50, ]
2 at a [50, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, ]

View File

@ -0,0 +1,5 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 b rings [51, ]

View File

@ -0,0 +1,61 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
amazing [50, ]
an [50, ]
at [50, ]
b0 [52, ]
b1 [53, ]
b10 [68, ]
b11 [69, ]
b12 [70, ]
b13 [71, ]
b14 [72, ]
b15 [73, ]
b16 [74, ]
b17 [75, ]
b18 [76, ]
b19 [77, ]
b1a [78, ]
b1b [79, ]
b1c [80, ]
b1d [81, ]
b1e [82, ]
b1f [83, ]
b2 [54, ]
b20 [84, ]
b21 [85, ]
b22 [86, ]
b23 [87, ]
b24 [88, ]
b25 [89, ]
b26 [90, ]
b27 [91, ]
b28 [92, ]
b29 [93, ]
b2a [94, ]
b2b [95, ]
b2c [96, ]
b2d [97, ]
b2e [98, ]
b2f [99, ]
b3 [55, ]
b30 [100, ]
b31 [101, ]
b4 [56, ]
b5 [57, ]
b6 [58, ]
b7 [59, ]
b8 [60, ]
b9 [61, ]
ba [62, ]
bb [63, ]
bc [64, ]
bd [65, ]
be [66, ]
bell [51, ]
bf [67, ]
house [50, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,5 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 the b [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, ]

View File

@ -0,0 +1,9 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a amazing [50, ]
1 a an [50, ]
1 a house [50, ]
2 a amazing [50, ]
2 a house [50, ]

View File

@ -0,0 +1,61 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
a0 [0, ]
a1 [1, ]
a10 [16, ]
a11 [17, ]
a12 [18, ]
a13 [19, ]
a14 [20, ]
a15 [21, ]
a16 [22, ]
a17 [23, ]
a18 [24, ]
a19 [25, ]
a1a [26, ]
a1b [27, ]
a1c [28, ]
a1d [29, ]
a1e [30, ]
a1f [31, ]
a2 [2, ]
a20 [32, ]
a21 [33, ]
a22 [34, ]
a23 [35, ]
a24 [36, ]
a25 [37, ]
a26 [38, ]
a27 [39, ]
a28 [40, ]
a29 [41, ]
a2a [42, ]
a2b [43, ]
a2c [44, ]
a2d [45, ]
a2e [46, ]
a2f [47, ]
a3 [3, ]
a30 [48, ]
a31 [49, ]
a4 [4, ]
a5 [5, ]
a6 [6, ]
a7 [7, ]
a8 [8, ]
a9 [9, ]
aa [10, ]
ab [11, ]
ac [12, ]
ad [13, ]
ae [14, ]
af [15, ]
amazing [50, ]
an [50, ]
at [50, ]
bell [51, ]
house [50, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,7 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 an a [50, ]
1 at a [50, ]
2 at a [50, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, ]

View File

@ -0,0 +1,10 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a amazing [50, ]
1 a an [50, ]
1 a house [50, ]
1 b rings [51, ]
2 a amazing [50, ]
2 a house [50, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5f6443e54fae188aa96d4f27fce28939

View File

@ -0,0 +1,8 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 an a [50, ]
1 at a [50, ]
1 the b [51, ]
2 at a [50, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, ]

View File

@ -0,0 +1,14 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [51, ]
1 a amazing [50, ]
1 a an [50, ]
1 a and [50, ]
1 a beautiful [50, ]
2 a am [51, ]
2 a amazing [50, ]
2 a and [50, ]
2 a beautiful [50, ]
2 a house [50, ]

View File

@ -0,0 +1,65 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5 [51, ]
a0 [0, ]
a1 [1, ]
a10 [16, ]
a11 [17, ]
a12 [18, ]
a13 [19, ]
a14 [20, ]
a15 [21, ]
a16 [22, ]
a17 [23, ]
a18 [24, ]
a19 [25, ]
a1a [26, ]
a1b [27, ]
a1c [28, ]
a1d [29, ]
a1e [30, ]
a1f [31, ]
a2 [2, ]
a20 [32, ]
a21 [33, ]
a22 [34, ]
a23 [35, ]
a24 [36, ]
a25 [37, ]
a26 [38, ]
a27 [39, ]
a28 [40, ]
a29 [41, ]
a2a [42, ]
a2b [43, ]
a2c [44, ]
a2d [45, ]
a2e [46, ]
a2f [47, ]
a3 [3, ]
a30 [48, ]
a31 [49, ]
a4 [4, ]
a5 [5, ]
a6 [6, ]
a7 [7, ]
a8 [8, ]
a9 [9, ]
aa [10, ]
ab [11, ]
ac [12, ]
ad [13, ]
ae [14, ]
af [15, ]
am [51, ]
amazing [50, ]
an [50, ]
and [50, ]
at [50, 51, ]
beautiful [50, ]
bell [51, ]
house [50, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,16 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 5 a [51, ]
1 amazing a [50, ]
1 an a [50, ]
1 at a [50, ]
1 rings a [51, ]
2 an a [50, ]
2 at a [50, 51, ]
2 bell a [51, ]
3 at a [50, ]
3 rings a [51, ]
3 the a [51, ]
4 bell a [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, ]

View File

@ -0,0 +1,14 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [51, ]
1 a amazing [50, ]
1 a an [50, ]
1 a and [50, ]
1 a beautiful [50, ]
2 a am [51, ]
2 a amazing [50, ]
2 a and [50, ]
2 a beautiful [50, ]
2 a house [50, ]

View File

@ -0,0 +1,65 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5 [51, ]
a0 [0, ]
a1 [1, ]
a10 [16, ]
a11 [17, ]
a12 [18, ]
a13 [19, ]
a14 [20, ]
a15 [21, ]
a16 [22, ]
a17 [23, ]
a18 [24, ]
a19 [25, ]
a1a [26, ]
a1b [27, ]
a1c [28, ]
a1d [29, ]
a1e [30, ]
a1f [31, ]
a2 [2, ]
a20 [32, ]
a21 [33, ]
a22 [34, ]
a23 [35, ]
a24 [36, ]
a25 [37, ]
a26 [38, ]
a27 [39, ]
a28 [40, ]
a29 [41, ]
a2a [42, ]
a2b [43, ]
a2c [44, ]
a2d [45, ]
a2e [46, ]
a2f [47, ]
a3 [3, ]
a30 [48, ]
a31 [49, ]
a4 [4, ]
a5 [5, ]
a6 [6, ]
a7 [7, ]
a8 [8, ]
a9 [9, ]
aa [10, ]
ab [11, ]
ac [12, ]
ad [13, ]
ae [14, ]
af [15, ]
am [51, ]
amazing [50, ]
an [50, ]
and [50, ]
at [50, 51, ]
beautiful [50, ]
bell [51, ]
house [50, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,16 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 5 a [51, ]
1 amazing a [50, ]
1 an a [50, ]
1 at a [50, ]
1 rings a [51, ]
2 an a [50, ]
2 at a [50, 51, ]
2 bell a [51, ]
3 at a [50, ]
3 rings a [51, ]
3 the a [51, ]
4 bell a [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, ]

View File

@ -0,0 +1,17 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [51, ]
1 a amazing [50, ]
1 a an [50, ]
1 a and [50, ]
1 a beautiful [50, ]
1 b house [50, ]
1 b rings [51, ]
2 a am [51, ]
2 a amazing [50, ]
2 a and [50, ]
2 a beautiful [50, ]
2 a house [50, ]
2 b at [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
9f4866b80177e321a33ce434992022b5

View File

@ -0,0 +1,21 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 5 a [51, ]
1 amazing a [50, ]
1 an a [50, ]
1 and b [50, ]
1 at a [50, ]
1 rings a [51, ]
1 the b [51, ]
2 amazing b [50, ]
2 an a [50, ]
2 at a [50, 51, ]
2 bell a [51, ]
3 an b [50, ]
3 at a [50, ]
3 rings a [51, ]
3 the a [51, ]
4 at b [50, ]
4 bell a [51, ]

View File

@ -0,0 +1,4 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
[51, ]

View File

@ -0,0 +1,14 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 a 5 [51, ]
1 a amazing [50, ]
1 a an [50, ]
1 a and [50, ]
1 a beautiful [50, ]
2 a am [51, ]
2 a amazing [50, ]
2 a and [50, ]
2 a beautiful [50, ]
2 a house [50, ]

View File

@ -0,0 +1,65 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
5 [51, ]
a0 [0, ]
a1 [1, ]
a10 [16, ]
a11 [17, ]
a12 [18, ]
a13 [19, ]
a14 [20, ]
a15 [21, ]
a16 [22, ]
a17 [23, ]
a18 [24, ]
a19 [25, ]
a1a [26, ]
a1b [27, ]
a1c [28, ]
a1d [29, ]
a1e [30, ]
a1f [31, ]
a2 [2, ]
a20 [32, ]
a21 [33, ]
a22 [34, ]
a23 [35, ]
a24 [36, ]
a25 [37, ]
a26 [38, ]
a27 [39, ]
a28 [40, ]
a29 [41, ]
a2a [42, ]
a2b [43, ]
a2c [44, ]
a2d [45, ]
a2e [46, ]
a2f [47, ]
a3 [3, ]
a30 [48, ]
a31 [49, ]
a4 [4, ]
a5 [5, ]
a6 [6, ]
a7 [7, ]
a8 [8, ]
a9 [9, ]
aa [10, ]
ab [11, ]
ac [12, ]
ad [13, ]
ae [14, ]
af [15, ]
am [51, ]
amazing [50, ]
an [50, ]
and [50, ]
at [50, 51, ]
beautiful [50, ]
bell [51, ]
house [50, ]
rings [51, ]
the [51, ]

View File

@ -0,0 +1,16 @@
---
source: milli/src/update/prefix_word_pairs/mod.rs
---
1 5 a [51, ]
1 amazing a [50, ]
1 an a [50, ]
1 at a [50, ]
1 rings a [51, ]
2 an a [50, ]
2 at a [50, 51, ]
2 bell a [51, ]
3 at a [50, ]
3 rings a [51, ]
3 the a [51, ]
4 bell a [51, ]