| 74 |
74 |
|
|
| 75 |
75 |
|
### TagIndex (Autocomplete)
|
| 76 |
76 |
|
|
| 77 |
|
- |
Sorted `Vec<String>` with binary-search lookup. Two-tier suggestion strategy:
|
|
77 |
+ |
Sorted `Vec<String>` with binary-search lookup. Three suggestion tiers, each running only if the one before it left room under `limit`:
|
| 78 |
78 |
|
|
| 79 |
79 |
|
1. **Path prefix** (tier 1): binary search for tags whose full path starts with input. O(log n + k).
|
| 80 |
80 |
|
2. **Segment prefix** (tier 2): linear scan for tags where any non-first segment starts with input. Only runs if tier 1 didn't fill the limit and input has no dots. A segment index gates entry: if no known segment starts with input, scan is skipped in O(log m).
|
|
81 |
+ |
3. **Fuzzy segment** (tier 3): linear scan for tags with any segment within Levenshtein distance 2 of input, sorted by distance then lexicographically. Skips tags already returned by tiers 1 and 2.
|
| 81 |
82 |
|
|
| 82 |
|
- |
Key methods: `new()`, `empty()`, `insert()`, `remove()`, `rebuild()`, `contains()`, `suggest(input, limit)`, `suggest_with_status(input, limit)`.
|
|
83 |
+ |
`suggest(input, limit)` runs tiers 1 and 2. `suggest_fuzzy(input, limit)` runs all three: it calls `suggest` first and appends tier-3 hits. Within each tier results are sorted, and earlier tiers come first.
|
|
84 |
+ |
|
|
85 |
+ |
Key methods: `new()`, `empty()`, `insert()`, `remove()`, `rebuild()`, `contains()`, `len()`, `is_empty()`, `iter()`, `suggest(input, limit)`, `suggest_with_status(input, limit)` (adds a flag for whether input is itself a tag), `suggest_fuzzy(input, limit)`.
|
|
86 |
+ |
|
|
87 |
+ |
`insert()` and `remove()` keep sorted order. `remove()` does not prune orphaned segments; call `rebuild()` when segment accuracy matters after many removals.
|
|
88 |
+ |
|
|
89 |
+ |
### Bulk Operations (free functions over `&mut TagIndex`)
|
|
90 |
+ |
|
|
91 |
+ |
Each rewrites the index in place and returns a count.
|
|
92 |
+ |
|
|
93 |
+ |
- `rename_prefix_bulk(old, new, index)`: apply `rename_prefix` to every tag, rebuilding the index. Returns tags modified.
|
|
94 |
+ |
- `remove_subtree(prefix, index)`: drop `prefix` and all its descendants. Returns tags removed.
|
|
95 |
+ |
- `merge_tags(source, target, index)`: rewrite the `source` prefix to `target` across the subtree, deduplicating collisions with tags already under `target`. Implemented as a call through to `rename_prefix_bulk`. Returns tags moved.
|
|
96 |
+ |
- `batch_rename(operations, index)`: apply `(old, new)` prefix renames in order. Returns the sum of per-operation counts, so a tag renamed twice counts twice.
|
| 83 |
97 |
|
|
| 84 |
98 |
|
## Integration Patterns
|
| 85 |
99 |
|
|