Skip to content

Commit

Permalink
feat: rapidfuzz integration
Browse files Browse the repository at this point in the history
  • Loading branch information
leontoeides committed Jan 12, 2025
1 parent e7b6a60 commit c18558b
Show file tree
Hide file tree
Showing 56 changed files with 2,258 additions and 151 deletions.
37 changes: 24 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,42 +1,53 @@
[package]
name = "indicium"
version = "0.6.3"
version = "0.6.4"
authors = ["Dylan Bowker <dylan.bowker@arkiteq.io>"]
edition = "2021"
categories = [ "database-implementations" ]
categories = ["database-implementations"]
description = "Simple in-memory search for collections and key-value stores."
documentation = "https://docs.rs/indicium"
keywords = [ "search", "autocomplete", "struct", "vec", "hashmap" ]
keywords = ["search", "autocomplete", "struct", "vec", "hashmap"]
license = "MIT OR Apache-2.0"
publish = true
readme = "README.md"
repository = "https://github.com/leontoeides/indicium"
rust-version = "1.73.0"

[features]
default = [ "simple" ]
default = ["simple", "rustc-hash"]

simple = [ "strsim", "ahash" ]
select2 = [ "simple", "dep:serde" ]
simple = ["rapidfuzz"]
select2 = ["simple", "dep:serde"]

fuzzy = [ "dep:strsim" ]
strsim = [ "dep:strsim" ]
eddie = [ "dep:eddie" ]
fuzzy = ["dep:strsim"]
strsim = ["dep:strsim"]
eddie = ["dep:eddie"] # Quite fast but unstable. Not recommended
rapidfuzz = ["dep:rapidfuzz"]

ahash = [ "dep:ahash" ]
gxhash = [ "dep:gxhash" ]
ahash = ["dep:ahash"]
gxhash = ["dep:gxhash"]
rustc-hash = ["dep:rustc-hash"]

[dependencies]
ahash = { version = "0.8", optional = true }
eddie = { version = "0.4", optional = true }
gxhash = { version = "3.4", optional = true }
kstring = "2.0"
serde = { version = "1.0", features = [ "derive" ], optional = true }
rapidfuzz = { version = "0.5", optional = true }
rustc-hash = { version = "2.1", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
strsim = { version = "0.11", optional = true }
tracing = "0.1"

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
gabble = "0.1"
pretty_assertions = "1"
rand = "0.8.*"

[badges]
maintenance = { status = "passively-maintained" }
maintenance = { status = "passively-maintained" }

[[bench]]
name = "all_bench"
harness = false
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ assert_eq!(resulting_keys, vec![&0]);

Search only supports exact keyword matches. For `Live` searches, fuzzy matching
is only applied to the last keyword. Consider providing the `autocomplete`
feature to your users as an ergonomic alternative to fuzzy matching.
feature to your users to help them build their search as they type.

## 4. Autocompletion

Expand Down
308 changes: 308 additions & 0 deletions benches/all_bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
use rand::rngs::ThreadRng;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use indicium::simple::{SearchIndex, SearchType};
use rand::Rng;

fn random_all_word(rng: &mut ThreadRng) -> String {
"all".to_owned() + &rng.gen::<gabble::Gab>().to_string()
}

fn criterion_benchmark(c: &mut Criterion) {
// The "all" test. Looks at 277 words that start with the prefix "all":
let all_vec: Vec<&str> = vec![
"allanite", // 1
"allanites", // 2
"allantoic", // 3
"allantoid", // 4
"allantoides", // 5
"allantoids", // 6
"allantoin", // 7
"allantoins", // 8
"allantois", // 9
"allargando", // 10
"allay", // 11
"allayed", // 12
"allayer", // 13
"allayers", // 14
"allaying", // 15
"allays", // 16
"allee", // 17
"allees", // 18
"allegation", // 19
"allegations", // 20
"allege", // 21
"alleged", // 22
"allegedly", // 23
"alleger", // 24
"allegers", // 25
"alleges", // 26
"allegiance", // 27
"allegiances", // 28
"allegiant", // 29
"allegiants", // 30
"alleging", // 31
"allegoric", // 32
"allegorical", // 33
"allegorically", // 34
"allegoricalness", // 35
"allegories", // 36
"allegorise", // 37
"allegorised", // 38
"allegorises", // 39
"allegorising", // 40
"allegorist", // 41
"allegorists", // 42
"allegorization", // 43
"allegorizations", // 44
"allegorize", // 45
"allegorized", // 46
"allegorizer", // 47
"allegorizers", // 48
"allegorizes", // 49
"allegorizing", // 50
"allegory", // 51
"allegretto", // 52
"allegrettos", // 53
"allegro", // 54
"allegros", // 55
"allele", // 56
"alleles", // 57
"allelic", // 58
"allelism", // 59
"allelisms", // 60
"allelomorph", // 61
"allelomorphic", // 62
"allelomorphism", // 63
"allelomorphisms", // 64
"allelomorphs", // 65
"allelopathic", // 66
"allelopathies", // 67
"allelopathy", // 68
"alleluia", // 69
"alleluias", // 70
"allemande", // 71
"allemandes", // 72
"allergen", // 73
"allergenic", // 74
"allergenicities", // 75
"allergenicity", // 76
"allergens", // 77
"allergic", // 78
"allergies", // 79
"allergin", // 80
"allergins", // 81
"allergist", // 82
"allergists", // 83
"allergy", // 84
"allethrin", // 85
"allethrins", // 86
"alleviant", // 87
"alleviants", // 88
"alleviate", // 89
"alleviated", // 90
"alleviates", // 91
"alleviating", // 92
"alleviation", // 93
"alleviations", // 94
"alleviator", // 95
"alleviators", // 96
"alley", // 97
"alleys", // 98
"alleyway", // 99
"alleyways", // 100
"allheal", // 101
"allheals", // 102
"alliable", // 103
"alliaceous", // 104
"alliance", // 105
"alliances", // 106
"allicin", // 107
"allicins", // 108
"allied", // 109
"allies", // 110
"alligator", // 111
"alligators", // 112
"alliterate", // 113
"alliterated", // 114
"alliterates", // 115
"alliterating", // 116
"alliteration", // 117
"alliterations", // 118
"alliterative", // 119
"alliteratively", // 120
"allium", // 121
"alliums", // 122
"alloantibodies", // 123
"alloantibody", // 124
"alloantigen", // 125
"alloantigens", // 126
"allobar", // 127
"allobars", // 128
"allocable", // 129
"allocatable", // 130
"allocate", // 131
"allocated", // 132
"allocates", // 133
"allocating", // 134
"allocation", // 135
"allocations", // 136
"allocator", // 137
"allocators", // 138
"allocution", // 139
"allocutions", // 140
"allod", // 141
"allodia", // 142
"allodial", // 143
"allodium", // 144
"allods", // 145
"allogamies", // 146
"allogamous", // 147
"allogamy", // 148
"allogeneic", // 149
"allogenic", // 150
"allograft", // 151
"allografted", // 152
"allografting", // 153
"allografts", // 154
"allograph", // 155
"allographic", // 156
"allographs", // 157
"allometric", // 158
"allometries", // 159
"allometry", // 160
"allomorph", // 161
"allomorphic", // 162
"allomorphism", // 163
"allomorphisms", // 164
"allomorphs", // 165
"allonge", // 166
"allonges", // 167
"allonym", // 168
"allonyms", // 169
"allopath", // 170
"allopathies", // 171
"allopaths", // 172
"allopathy", // 173
"allopatric", // 174
"allopatrically", // 175
"allopatries", // 176
"allopatry", // 177
"allophane", // 178
"allophanes", // 179
"allophone", // 180
"allophones", // 181
"allophonic", // 182
"alloplasm", // 183
"alloplasms", // 184
"allopolyploid", // 185
"allopolyploids", // 186
"allopolyploidy", // 187
"allopurinol", // 188
"allopurinols", // 189
"allosaur", // 190
"allosaurs", // 191
"allosaurus", // 192
"allosauruses", // 193
"allosteric", // 194
"allosterically", // 195
"allosteries", // 196
"allostery", // 197
"allot", // 198
"allotetraploid", // 199
"allotetraploids", // 200
"allotetraploidy", // 201
"allotment", // 202
"allotments", // 203
"allotrope", // 204
"allotropes", // 205
"allotropic", // 206
"allotropies", // 207
"allotropy", // 208
"allots", // 209
"allotted", // 210
"allottee", // 211
"allottees", // 212
"allotter", // 213
"allotters", // 214
"allotting", // 215
"allotype", // 216
"allotypes", // 217
"allotypic", // 218
"allotypically", // 219
"allotypies", // 220
"allotypy", // 221
"allover", // 222
"allovers", // 223
"allow", // 224
"allowable", // 225
"allowables", // 226
"allowably", // 227
"allowance", // 228
"allowanced", // 229
"allowances", // 230
"allowancing", // 231
"allowed", // 232
"allowedly", // 233
"allowing", // 234
"allows", // 235
"alloxan", // 236
"alloxans", // 237
"alloy", // 238
"alloyed", // 239
"alloying", // 240
"alloys", // 241
"alls", // 242
"allseed", // 243
"allseeds", // 244
"allspice", // 245
"allspices", // 246
"allude", // 247
"alluded", // 248
"alludes", // 249
"alluding", // 250
"allure", // 251
"allured", // 252
"allurement", // 253
"allurements", // 254
"allurer", // 255
"allurers", // 256
"allures", // 257
"alluring", // 258
"alluringly", // 259
"allusion", // 260
"allusions", // 261
"allusive", // 262
"allusively", // 263
"allusiveness", // 264
"allusivenesses", // 265
"alluvia", // 266
"alluvial", // 267
"alluvials", // 268
"alluvion", // 269
"alluvions", // 270
"alluvium", // 271
"alluviums", // 272
"ally", // 273
"allying", // 274
"allyl", // 275
"allylic", // 276
"allyls", // 277
]; // vec!

let mut search_index: SearchIndex<usize> = SearchIndex::default();

all_vec
.iter()
.enumerate()
.for_each(|(index, element)| search_index.insert(&index, element));

let mut rng: ThreadRng = rand::thread_rng();

c.bench_function("all277", |b| b.iter(|| {
let all_word = random_all_word(&mut rng);
search_index.search_type(&SearchType::Live, black_box(&all_word));
} ));
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@
//!
//! Search only supports exact keyword matches. For `Live` searches, fuzzy
//! matching is only applied to the last keyword. Consider providing the
//! `autocomplete` feature to your users as an ergonomic alternative to fuzzy
//! matching.
//! `autocomplete` feature to your users to help them build their search as they
//! type.
//!
//! ## 4. Autocompletion
//!
Expand Down
Loading

0 comments on commit c18558b

Please sign in to comment.