Date: 2025-11-06 Purpose: Compare implementation approaches and provide recommendation for WallBreaker integration.
Recommended Approach: Option B - Hybrid (SuffixAutomaton-based)
Rationale: Best balance of effort (6-9 weeks), performance (60-70% of full SCDAWG), and risk (medium). Leverages existing SuffixAutomaton capabilities (suffix links, substring search) to achieve significant performance gains without the complexity of full SCDAWG implementation.
Performance Gain
Implementation Effort
Risk Level
Reusability
Completeness
Description: Implement complete Symmetric Compact Directed Acyclic Word Graph backend with full bidirectional traversal, exactly as described in WallBreaker paper.
Core Idea: Build a new dictionary backend that natively supports arbitrary-position traversal in both directions.
Description: Extend existing SuffixAutomaton with bidirectional capabilities, using suffix links for substring search and adding parent links for reverse traversal.
Core Idea: Leverage SuffixAutomaton's existing bidirectional properties (suffix links) rather than building from scratch.
Description: Add HashMap-based substring index to existing backends without modifying core dictionary structures.
Core Idea: Separate substring index from dictionary structure, enabling WallBreaker pattern without deep architectural changes.
| Criterion | Option A (Full SCDAWG) | Option B (Hybrid) | Option C (Index-Based) |
|---|---|---|---|
| Performance | ⭐⭐⭐⭐⭐ (100%) | ⭐⭐⭐⭐ (60-70%) | ⭐⭐⭐ (40-50%) |
| Effort | ❌ 21-31 weeks | ✅ 6-9 weeks | ✅ 3-4 weeks |
| Risk | ❌ High | ✅ Medium | ✅ Low |
| Reusability | ⭐⭐ (30%) | ⭐⭐⭐⭐ (70%) | ⭐⭐⭐ (50%) |
| Completeness | ⭐⭐⭐⭐⭐ (100%) | ⭐⭐⭐⭐ (80%) | ⭐⭐⭐ (60%) |
| Memory | ⭐⭐⭐ (good) | ⭐⭐⭐⭐ (better) | ⭐⭐ (more overhead) |
| Maintainability | ⭐⭐⭐ (complex) | ⭐⭐⭐⭐ (moderate) | ⭐⭐⭐⭐⭐ (simple) |
| API Impact | ⭐⭐ (new backend) | ⭐⭐⭐⭐ (extends existing) | ⭐⭐⭐⭐⭐ (minimal) |
Legend: ⭐ = Poor, ⭐⭐⭐ = Average, ⭐⭐⭐⭐⭐ = Excellent
Benchmark Scenario: 100-character pattern, max_distance = 16, 750K dictionary
| Metric | Traditional | Option A | Option B | Option C |
|---|---|---|---|---|
| Query Time | ~500ms | ~0.088ms (paper) | ~0.15-0.20ms | ~0.20-0.30ms |
| Speedup | 1x | 5600x | 2500-3300x | 1600-2500x |
| Dictionary Build | N/A | Slower (2-3x) | Same | Slower (1.5x) |
| Memory Usage | Baseline | +50% | +30% | +80% |
Performance Notes:
When Performance Matters:
| Task Category | Option A | Option B | Option C |
|---|---|---|---|
| New Traits | 2 weeks | 1 week | 3 days |
| Backend Implementation | 8-12 weeks | N/A | N/A |
| Substring Search | 2 weeks | 1 week | 2 weeks |
| Bidirectional Extension | 4 weeks | 2 weeks | N/A |
| Query Iterator | 2 weeks | 1.5 weeks | 1 week |
| Testing | 2-3 weeks | 1.5-2 weeks | 1 week |
| Documentation | 1-2 weeks | 1 week | 3 days |
| Total | 21-31 weeks | 6-9 weeks | 3-4 weeks |
Developer Experience Assumed: Intermediate Rust, familiar with codebase
| Risk Factor | Option A | Option B | Option C |
|---|---|---|---|
| Implementation Complexity | HIGH (New data structure) | MEDIUM (Extend existing) | LOW (HashMap layer) |
| Correctness Risk | HIGH (Many edge cases) | MEDIUM (Fewer edge cases) | LOW (Simple logic) |
| Performance Risk | LOW (Paper validated) | MEDIUM (May not hit targets) | HIGH (May be too slow) |
| API Compatibility | MEDIUM (New backend) | LOW (Backward compatible) | LOW (Minimal changes) |
| Maintenance Burden | HIGH (Complex codebase) | MEDIUM (Moderate complexity) | LOW (Simple design) |
| Testing Complexity | HIGH (Many scenarios) | MEDIUM (Moderate coverage) | LOW (Easy to test) |
What Can Be Reused:
Option A (Full SCDAWG):
Option B (Hybrid):
Option C (Index-Based):
Option A: Full SCDAWG (21-31 weeks)
Phase 1: Foundation (4-6 weeks)
├─ Trait extensions (2 weeks)
├─ Substring search API (1 week)
└─ Bidirectional state (1-3 weeks)
Phase 2: SCDAWG Backend (8-12 weeks) ← Most effort here
├─ SCDAWG data structure (4-6 weeks)
├─ Construction algorithm (2-3 weeks)
├─ Bidirectional traversal (2-3 weeks)
Phase 3: WallBreaker Algorithm (5-7 weeks)
├─ Pattern splitting (1 week)
├─ Extension filters (2-3 weeks)
├─ Query iterator (2-3 weeks)
Phase 4: Integration & Testing (4-6 weeks)
├─ API integration (1-2 weeks)
├─ Comprehensive testing (2-3 weeks)
└─ Documentation (1 week)
Option B: Hybrid (6-9 weeks) ⭐ RECOMMENDED
Phase 1: Foundation (2-3 weeks)
├─ SubstringDictionary trait (1 week)
├─ SuffixAutomaton parent links (1 week)
└─ Bidirectional state (1 week)
Phase 2: WallBreaker Core (2-4 weeks)
├─ Pattern splitting (1 week)
├─ Hybrid extension (1-2 weeks)
└─ Query iterator (1-2 weeks)
Phase 3: Testing & Integration (2-3 weeks)
├─ Unit tests (1 week)
├─ Integration tests (1 week)
└─ Documentation (1 week)
Option C: Index-Based (3-4 weeks)
Phase 1: Substring Index (1-2 weeks)
├─ HashMap index structure (3 days)
├─ Index building (3 days)
└─ Substring query (1-2 days)
Phase 2: WallBreaker Query (1-1.5 weeks)
├─ Pattern splitting (2 days)
├─ Two-phase query (3 days)
└─ Result merging (2 days)
Phase 3: Testing & Integration (1 week)
├─ Tests (3 days)
├─ Benchmarks (2 days)
└─ Documentation (2 days)
| Component | Option A | Option B | Option C |
|---|---|---|---|
| New Traits | 200 | 150 | 50 |
| Backend/Index | 2000 | 300 | 400 |
| Substring Search | 500 | 200 | 300 |
| Bidirectional Logic | 800 | 400 | 0 |
| Query Iterator | 600 | 500 | 300 |
| Tests | 1500 | 800 | 400 |
| Documentation | 500 | 300 | 150 |
| Total New LoC | ~6100 | ~2650 | ~1600 |
| Skill Area | Option A | Option B | Option C |
|---|---|---|---|
| Rust Proficiency | Advanced | Intermediate | Intermediate |
| Data Structures | Expert | Intermediate | Beginner |
| Graph Algorithms | Expert | Intermediate | Beginner |
| Automata Theory | Expert | Intermediate | Basic |
| Performance Tuning | Advanced | Intermediate | Intermediate |
Scenario 1: Small Error Bound (max_distance = 2)
| Approach | Traditional | Option A | Option B | Option C |
|---|---|---|---|---|
| Query Time | 5ms | 4ms | 4.5ms | 6ms |
| Speedup | 1x | 1.25x | 1.1x | 0.8x |
| Winner | 🏆 Traditional | - | - | - |
Verdict: WallBreaker doesn't help for small distances (wall is small).
Scenario 2: Medium Error Bound (max_distance = 4)
| Approach | Traditional | Option A | Option B | Option C |
|---|---|---|---|---|
| Query Time | 50ms | 2ms | 5ms | 10ms |
| Speedup | 1x | 25x | 10x | 5x |
| Winner | - | 🏆 Option A | 🥈 Option B | 🥉 Option C |
Verdict: All WallBreaker options significantly faster. Option B provides excellent speedup (10x) with moderate effort.
Scenario 3: Large Error Bound (max_distance = 16)
| Approach | Traditional | Option A | Option B | Option C |
|---|---|---|---|---|
| Query Time | 500ms | 0.088ms | 0.15ms | 0.25ms |
| Speedup | 1x | 5600x | 3300x | 2000x |
| Winner | - | 🏆 Option A | 🥈 Option B | 🥉 Option C |
Verdict: Massive gains for all WallBreaker options. Even Option C (2000x) is excellent.
Option A Advantages:
Option B Advantages:
Option C Advantages:
Choose Option A if:
Choose Option B if: ⭐ RECOMMENDED
Choose Option C if:
Option A: Full SCDAWG
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| SCDAWG construction bugs | HIGH | HIGH | Extensive unit tests, reference implementation |
| Performance doesn't match paper | MEDIUM | HIGH | Early benchmarking, incremental optimization |
| Integration complexity | MEDIUM | MEDIUM | Phased rollout, existing backends as fallback |
| Timeline overrun | HIGH | HIGH | Build simplest version first, iterate |
Overall Risk: HIGH
Option B: Hybrid (SuffixAutomaton)
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| Suffix links insufficient for full WallBreaker | MEDIUM | MEDIUM | Add parent links, validate early |
| Performance target not met | MEDIUM | LOW | 60-70% still excellent, fallback to traditional |
| SuffixAutomaton edge cases | LOW | MEDIUM | Comprehensive testing, already battle-tested |
| Parent link tracking overhead | LOW | LOW | Benchmark early, optimize if needed |
Overall Risk: MEDIUM (manageable)
Option C: Index-Based
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| Index memory overhead too high | MEDIUM | MEDIUM | Lazy index building, memory profiling |
| Index invalidation on dictionary updates | LOW | LOW | Document immutability requirement |
| Performance insufficient | LOW | LOW | Still 2000x faster than traditional |
| HashMap lookup overhead | LOW | LOW | Use high-performance hasher |
Overall Risk: LOW
| Risk Factor | Option A | Option B | Option C |
|---|---|---|---|
| Underestimated Complexity | HIGH (+50% timeline) | LOW (+20% timeline) | VERY LOW (+10% timeline) |
| Blocked by Dependencies | MEDIUM (New data structure) | LOW (Existing backend) | VERY LOW (Independent) |
| Testing Reveals Issues | HIGH (Many edge cases) | MEDIUM (Moderate scope) | LOW (Simple logic) |
Expected Timeline with Risk Buffer:
Assumptions:
| Option | Total Hours | Cost | Performance Gain | ROI Score |
|---|---|---|---|---|
| Option A | 840-1240h | $126K-$186K | 5600x speedup | 0.03-0.04 |
| Option B | 240-360h | $36K-$54K | 3300x speedup | 0.06-0.09 |
| Option C | 120-160h | $18K-$24K | 2000x speedup | 0.08-0.11 |
ROI Score = (Speedup / Cost) × 1000
Analysis:
Option A Value:
Option B Value: ⭐ BEST VALUE
Option C Value:
Long-Term Vision:
Path 1: Option C → Option B → Option A
Path 2: Option B (Stop Here)
Path 3: Option A (All-In)
Recommended Path: Path 2 (Option B, stop here unless extreme performance needed)
🏆 Option B: Hybrid (SuffixAutomaton-based)
Reasons:
Best Effort/Benefit Ratio
Leverages Existing Code
Manageable Risk
Sufficient for Most Use Cases
Backward Compatible
Choose Option C (Index-Based) if:
Upgrade Path: Can migrate from Option C → Option B later
Choose Option A (Full SCDAWG) if:
Note: Can implement Option B first, then Option A later if needed
START: Need WallBreaker?
│
├─ NO ──► Keep traditional approach
│
└─ YES
│
├─ Timeline < 5 weeks? ──► Option C (Index-Based)
│ │
│ └─ Need better performance later?
│ └─ YES ──► Upgrade to Option B
│
├─ Timeline 6-10 weeks? ──► Option B (Hybrid) ⭐ RECOMMENDED
│ │
│ └─ Need extreme performance later?
│ └─ YES ──► Upgrade to Option A
│
└─ Timeline > 20 weeks AND extreme performance? ──► Option A (Full SCDAWG)
Performance Requirements:
Resource Constraints:
20 weeks → Option A
Dictionary Characteristics:
5M terms → Option A
Error Bound Usage:
Risk Tolerance:
Scoring System (1-5, higher is better):
| Criterion | Weight | Option A | Option B | Option C |
|---|---|---|---|---|
| Performance | 20% | 5 | 4 | 3 |
| Timeline | 25% | 1 | 4 | 5 |
| Risk | 20% | 2 | 4 | 5 |
| Reusability | 10% | 2 | 5 | 3 |
| Maintainability | 10% | 3 | 4 | 5 |
| Scalability | 10% | 5 | 4 | 2 |
| ROI | 5% | 2 | 5 | 5 |
| Weighted Score | - | 2.45 | 4.10 ⭐ | 4.15 |
Analysis:
Contextual Adjustment:
Phase 1: Start with Option B (Hybrid)
Timeline: 6-9 weeks Investment: $36K-$54K (240-360 hours) Expected Outcome: 3300x speedup, 60-70% of full performance
Milestones:
Success Criteria:
Decision Point: After Week 7
If Option B Performance Insufficient:
Optimize Hybrid implementation (1-2 weeks)
Implement Option A (Full SCDAWG)
If Timeline Too Long:
Year 1: Implement Option B (Hybrid)
Year 2: Evaluate Option A (Full SCDAWG)
Probability of Needing Option A: Low (< 20%)
Final Recommendation: Option B - Hybrid (SuffixAutomaton-based)
Summary:
Next Steps:
Document Status: ✅ Complete Decision: Option B (Hybrid) Recommended Last Updated: 2025-11-06 Next Document: progress-tracker.md - Task breakdown and status tracking
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |