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
52
53
54
55
56
57
//! Pre-filtering for approximate string matching.
//!
//! This module provides fast candidate filtering algorithms that can reject
//! 90%+ of candidates before expensive Levenshtein automata traversal.
//!
//! # Filtering Pipeline
//!
//! The hybrid filtering approach combines multiple stages:
//!
//! 1. **N-gram Index** (fastest, coarsest)
//! - Indexes terms by n-grams (bigrams/trigrams)
//! - Rejects candidates with insufficient n-gram overlap
//! - Time: O(|query| + |candidates|)
//!
//! 2. **Jaro-Winkler** (fast, finer)
//! - Computes string similarity with prefix bonus
//! - Rejects candidates below similarity threshold
//! - Time: O(|query| * |term|) per candidate
//!
//! 3. **Levenshtein Automaton** (expensive, exact)
//! - Full automaton traversal for remaining candidates
//! - Produces final matches with exact distances
//!
//! # Example
//!
//! ```rust,ignore
//! use liblevenshtein::filter::{HybridMatcher, NgramIndex};
//!
//! // Build index from dictionary
//! let mut index = NgramIndex::new(2); // Bigrams
//! for term in ["apple", "application", "banana", "apply"] {
//! index.insert(term);
//! }
//!
//! // Find candidates for "aple" with max distance 2
//! let candidates = index.find_candidates("aple", 2);
//! // candidates: ["apple", "apply"] (rejected "banana", "application")
//! ```
//!
//! # Performance
//!
//! For a 100K word dictionary with max_distance=2:
//! - N-gram filter: ~1-5ms, rejects 85-95% of candidates
//! - Jaro-Winkler refinement: ~0.5-2ms, rejects 50-80% of remaining
//! - Combined: ~2-7ms total filtering vs ~50-200ms full automaton
pub use ;
pub use ;
pub use NgramIndex;