Liking cljdoc? Tell your friends :D

liblevenshtein Algorithm Documentation

Comprehensive guide to the algorithms, data structures, and optimizations in liblevenshtein-rust.

This documentation provides in-depth coverage of all algorithmic layers, complete with theory, diagrams, usage examples, performance analysis, and references to academic literature.


Table of Contents

  1. Overview
  2. Quick Start
  3. Algorithmic Layers
  4. Performance Summary
  5. Use Case Guide
  6. References

Overview

liblevenshtein-rust is a high-performance fuzzy string matching library based on Levenshtein automata. It combines multiple algorithmic layers to provide fast approximate string matching against large dictionaries.

Architecture

The library is organized into 9 distinct algorithmic layers:

┌─────────────────────────────────────────────────────────┐
│  Application Layer (Your Code)                          │
├─────────────────────────────────────────────────────────┤
│  8. Caching Layer (LRU, LFU, TTL, etc.)                │
├─────────────────────────────────────────────────────────┤
│  7. Contextual Completion (Scope-aware, Hierarchical)   │
├─────────────────────────────────────────────────────────┤
│  6. Zipper Navigation (Functional Traversal)            │
├─────────────────────────────────────────────────────────┤
│  3. Intersection/Traversal (Query Iterators)            │
├─────────────────────────────────────────────────────────┤
│  2. Levenshtein Automata (Finite State Machines)        │
├─────────────────────────────────────────────────────────┤
│  1. Dictionary Layer (Tries, DAWGs, Suffix Automata)    │
├─────────────────────────────────────────────────────────┤
│  9. Value Storage (Term → Value Mappings)               │
├─────────────────────────────────────────────────────────┤
│  5. SIMD Optimization (Vectorized Hot Paths)            │
├─────────────────────────────────────────────────────────┤
│  4. Distance Calculation (Direct DP Algorithms)         │
└─────────────────────────────────────────────────────────┘

Key Features

  • 9 Dictionary Backends - Tries, DAWGs, Suffix Automata (byte & char variants)
  • 5 String-Distance Selectors - Standard, OSA transposition, unrestricted Damerau, merge-and-split, and parameterized affine gap
  • SIMD Acceleration - 20-64% speedup with AVX2/SSE4.1
  • Value Storage - Associate arbitrary data with terms (fuzzy maps)
  • Unicode Support - Correct character-level edit distances
  • Contextual Completion - Scope-aware code completion
  • Flexible Caching - 9 eviction strategies

Quick Start

Basic Fuzzy Search

use liblevenshtein::prelude::*;

// Create dictionary
let dict = DoubleArrayTrie::from_terms(vec![
    "apple", "application", "apply", "apricot"
]);

// Fuzzy search with max distance 2
let results: Vec<String> = dict
    .fuzzy_search("aple", 2)
    .collect();

// Results: ["apple", "apply"]

With Values (Fuzzy Maps)

// Dictionary with associated values
let dict = DoubleArrayTrie::from_terms_with_values(vec![
    ("apple", 1),
    ("banana", 2),
    ("cherry", 3),
]);

// Search with value filtering (10-100x faster!)
let results: Vec<(String, i32)> = dict
    .fuzzy_search_filtered("aple", 2, |v| *v < 3)
    .collect();

// Results: [("apple", 1)]

Unicode Support

// Character-level for proper Unicode
let dict = DoubleArrayTrieChar::from_terms(vec![
    "café", "naïve", "中文", "🎉"
]);

// Correct character-level distance
let results: Vec<String> = dict
    .fuzzy_search("cafe", 1)  // Missing accent = 1 character edit
    .collect();

// Results: ["café"]

Algorithmic Layers

Layer 1: Dictionary Layer

Purpose: Efficient storage and traversal of term collections

Implementations:

  • DoubleArrayTrieRecommended
    • 6-8 bytes/char, 3x faster queries than DAWG
    • Use case: General purpose, static/append-only dictionaries
  • DoubleArrayTrieCharUnicode
    • Character-level for proper Unicode semantics
    • Use case: International text, CJK, emoji
  • DynamicDawg
    • Thread-safe insert/remove operations
    • Use case: Frequently changing dictionaries
  • SuffixAutomaton
    • Substring/infix matching
    • Use case: Full-text search

Key Topics:

  • Data Structures
  • Value Storage
  • Performance Comparison

Layer 2: Levenshtein Automata

Purpose: Finite state machines for approximate string matching

Algorithms:

  • Standard (Insert, Delete, Substitute)
    • Use case: General fuzzy matching
  • Transposition (+Adjacent Swap)
    • Use case: Typo tolerance, keyboard errors
  • Merge-and-Split (+Merge/Split ops)
    • Use case: OCR errors, scanning artifacts

Core Concepts:

  • Position Representation: (term_index, accumulated_cost, kind, auxiliary_payload)

Affine-gap dictionary automata

Purpose: Exact trie search when a contiguous query or dictionary gap pays one opening cost plus a per-symbol extension cost.

Coverage: Gotoh recurrence, exact fixed-point costs, three position layers, B-4 subsumption, layer-aware completion, operation-derived windows, Rust API, security guidance, independent formal models, generated properties, and benchmark protocol.

Unrestricted Damerau–Levenshtein

Purpose: Exact trie search under history-composing adjacent transpositions.

Coverage: Lowrance–Wagner recurrence, bounded streaming macro, kind-aware subsumption, literate pseudocode, resource policy, Rust usage, formal invariants, generated properties, and corpus evidence.

  • Subsumption: 3.3x faster with online pruning
  • State Composition: SmallVec optimization

Performance:

  • Online subsumption: $\mathcal{O}(kn)$ vs $\mathcal{O}(n^{2})$ batch
  • SIMD acceleration: 3-4x on characteristic vector

Exact Generalized-Operation Grid

Purpose: Operation-driven acceptance for runtime weighted and multi-scalar operation sets

Core properties:

  • exact decimal-to-integer accumulation
  • sparse topological alignment traversal
  • correct absent insertion/deletion behavior
  • Hamming, indel, bounded-skip, and standard differential invariants

Class-A Preset References

Purpose: Independent reference algorithms and conformance harnesses for alignment-expressible presets

Core properties:

  • Hamming partial-domain and fixed-length metric laws
  • indel/LCS identity, banded threshold equivalence, and metric laws
  • directional bounded-skip/subsequence identity
  • operation-set progress, cost, overflow, and aggregate resource guards

Layer 3: Intersection & Traversal

Purpose: Execute queries by traversing Dictionary × Automaton

Query Types:

  • QueryIterator
    • Unordered results, streaming
    • Use case: Large result sets
  • OrderedQueryIterator
    • Distance-first ordering
    • Use case: Autocomplete, top-k results
  • ValueFilteredQueryIterator
    • Filter during traversal (10-100x faster!)
    • Use case: Scope-aware code completion
  • ZipperQueryIterator
    • Hierarchical navigation
    • Use case: Context-preserving search

Key Topics:

  • Product Construction
  • Path Tracking: 15-25% speedup
  • Lazy Evaluation

Language Products

Purpose: Exact bounded Levenshtein distance from a dictionary term to a regular language

Key Topics:

  • Unit-generic LanguageAutomaton<U>
  • Fixed $k+1$ cost frontier
  • Frontier merge and minimum-cost canonicalization laws
  • Iterative, frontier-pruned dictionary traversal
  • Regex resource ceilings and formal verification

Layer 4: Distance Calculation

Purpose: Direct string distance computation (non-automaton approach)

Algorithms:

Use Cases:

  • Direct comparison without dictionary
  • Validation of automaton results
  • Benchmarking

Layer 5: SIMD Optimization

Purpose: Vectorize hot paths for 20-64% performance gains

Optimized Operations:

  • Characteristic Vector
    • AVX2 (8-wide), SSE4.1 (4-wide)
    • 3-4x speedup in automaton transitions
  • Distance Matrix
    • Vectorized DP row updates
    • 20-30% speedup for strings $\ge 16$ chars
  • Edge Lookup
    • Optimal for exactly 4 edges

Key Topics:

  • Runtime Detection: CPU feature flags
  • Threshold Analysis: When SIMD helps
  • Benchmarks: 950+ lines of analysis

Layer 6: Zipper Navigation

Purpose: Functional, context-preserving traversal of data structures

Pattern: Huet's Zipper (1997) - functional navigation with context

Implementations:

  • DictZipper: Navigate dictionaries
  • ValuedDictZipper: Access values during navigation
  • AutomatonZipper: Track automaton state
  • IntersectionZipper: Compose dictionary + automaton

Use Cases:

  • Hierarchical Completion
  • Scope-aware Search
  • Backtracking

Layer 7: Contextual Completion

Purpose: Scope-aware, hierarchical code completion

Components:

Use Cases:


Layer 8: Caching

Purpose: Query result caching with configurable eviction

Eviction Policies:

Features:

  • Lock-free concurrency (DashMap)
  • Compact metadata storage
  • Fuzzy multimap support

Layer 9: Value Storage

Purpose: Associate arbitrary data with dictionary terms (fuzzy maps)

Architecture:

Terms → States (via transitions) → Values (via state index)

Example:
"apple" → state 5 → value: Some(1)
"app"   → state 3 → value: None (not final)

Implementation:

  • values: Arc<Vec<Option<V>>> indexed by state number
  • Only final states can have Some(value)
  • Cloned on access for Rust ownership

Use Cases:

  • Scope IDs for code completion
  • Categorization and metadata
  • Fuzzy Maps - approximate key-value lookup
  • Filtered Queries - 10-100x speedup

Key Topics:

  • Term-Value Mapping
  • Memory Layout
  • Performance Impact

Performance Summary

Dictionary Comparison (10,000 words)

BackendConstructionExact MatchDistance 1Distance 2Memory
DoubleArrayTrie3.2ms6.6µs12.9µs16.3µs8 bytes/char
DynamicDawg4.1ms19.8µs319µs2,150µs~12 bytes/char
PathMap3.5ms71.1µs888µs5,919µsVariable

SIMD Performance Gains

ComponentScalarAVX2Speedup
Characteristic Vector100%3-4x300-400%
Distance Matrix ($\ge 16$ chars)100%1.2-1.3x20-30%
Overall Workload100%1.2-1.64x20-64%

Value Filtering Speedup

SelectivityPost-FilterDuring-TraversalSpeedup
10%100ms10ms10x
1%100ms1ms100x

Use Case Guide

Decision Tree: Which Dictionary?

Need to remove terms?
├─ YES → DynamicDawg (thread-safe insert/remove)
└─ NO
    ├─ Unicode text?
    │  ├─ YES → DoubleArrayTrieChar (character-level)
    │  └─ NO  → DoubleArrayTrie ⭐ (recommended)
    │
    └─ Substring search?
       └─ YES → SuffixAutomaton (infix matching)

Common Scenarios

Autocomplete / Spell Checking

  • Dictionary: DoubleArrayTrie
  • Algorithm: Standard (distance 1-2)
  • Iterator: OrderedQueryIterator (top-10 results)

Typo Tolerance

  • Dictionary: DoubleArrayTrie
  • Algorithm: Transposition (keyboard errors)
  • Iterator: QueryIterator (all matches)

International Text

  • Dictionary: DoubleArrayTrieChar
  • Algorithm: Standard or Transposition
  • Iterator: Depends on use case

Code Completion (Scope-aware)

  • Dictionary: DoubleArrayTrie with scope IDs
  • Algorithm: Standard
  • Iterator: ValueFilteredQueryIterator (10-100x faster)

Full-Text Search

  • Dictionary: SuffixAutomaton
  • Algorithm: Standard
  • Iterator: QueryIterator

Live Dictionary Updates

  • Dictionary: DynamicDawg (thread-safe)
  • Algorithm: Any
  • Iterator: Any

Example Index

Getting Started

  • Hello Fuzzy Search
  • Basic Query Patterns
  • Distance Calculation

Dictionaries

  • DoubleArrayTrie Demo
  • Dynamic DAWG Demo
  • Unicode Handling
  • Dictionary Comparison

Algorithms

  • Standard Levenshtein
  • Transposition Demo
  • Merge-and-Split Demo

Value Storage

  • Term-Value Storage
  • Scope-Aware Completion
  • Fuzzy Map
  • Value Filtering

Real-World Applications

  • Spell Checker
  • Autocomplete Server
  • Fuzzy Finder
  • LSP Completion

References

Academic Papers (Open Access)

  1. Schulz & Mihov (2002) - "Fast string correction with Levenshtein automata"

  2. Blumer et al. (1985) - "The smallest automaton recognizing the subwords of a text"

  3. Aoe (1989) - "An Efficient Digital Search Algorithm by Using a Double-Array Structure"

  4. Damerau (1964) - "A technique for computer detection and correction of spelling errors"

  5. Wagner & Fischer (1974) - "The String-to-String Correction Problem"

  6. Huet (1997) - "The Zipper"

  7. Gotoh (1982) - "An improved algorithm for matching biological sequences"

See the complete reference list for more papers and resources.


Navigation

By Layer:

By Topic:

Quick Links:


Contributing

Found an issue or have suggestions? See CONTRIBUTING.md for guidelines on improving this documentation.

License

Documentation is licensed under CC BY 4.0. Code examples are licensed under the same license as the library (MIT or Apache 2.0).

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close