IronDrop features a comprehensive search system that combines server-side indexing with client-side real-time filtering to provide fast, responsive file and directory search capabilities. The implementation includes both local directory search and recursive subdirectory search through a RESTful API.
The search system consists of four main components:
- Standard Search Engine (
src/search.rs) - Handles indexing, caching, and search operations for medium-sized directories - Ultra-Compact Search Engine (
src/ultra_compact_search.rs) - Memory-optimized search for large directories (10M+ files) - Frontend Search Interface (
templates/directory/) - Provides the user interface and real-time search experience - HTTP Search Endpoints (
src/http.rs) - RESTful API for search operations
1. Standard Search Engine (search.rs)
- Target: Directories with up to 100K files
- Memory Usage: ~10MB for 10K files
- Core Components:
- SearchCache: LRU cache with 5-minute TTL, max 1000 queries
- DirectoryIndex: In-memory index with recursive traversal (max 20 levels)
- SearchEngine: Thread-safe operations with
Arc<Mutex<>>, background updates
2. Ultra-Compact Search Engine (ultra_compact_search.rs)
- Target: Very large directories (around 10M files)
- Memory Usage: Approximately ~110MB for ~10M entries (about 11 bytes per entry)
- Core Components:
- UltraCompactEntry: Bit-packed 11-byte entries with parent references
- String Pool: Unified storage with binary search for deduplication
- Hierarchical Storage: Parent-child relationships instead of full paths
- Cache-Aligned Structures: CPU optimization for large datasets
3. Performance Testing Module (ultra_memory_test.rs)
- Purpose: Benchmarking and memory analysis for search engines
- Features: Load testing, memory profiling, performance comparisons
| Directory Size | Search Time | Memory Usage | Algorithm |
|---|---|---|---|
| 10-100 files | < 2ms | < 50KB | Linear substring |
| 100-500 files | 2-5ms | 50-200KB | Fuzzy + token |
| 500-1000 files | 5-10ms | 200-500KB | Indexed token |
| 1000-100K files | 10-50ms | 1-10MB | Full-text index |
| Directory Size | Search Time | Memory Usage | Entry Size | Notes |
|---|---|---|---|---|
| 100K files | 5-15ms | ~1.1MB | 11 bytes | Bit-packed data |
| 1M files | 20-80ms | ~11MB | 11 bytes | Hierarchical paths |
| 10M files | 100-500ms | ~110MB | 11 bytes | String pool + radix |
Standard Entry: 24 bytes Ultra-Compact Entry: 11 bytes
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ Full Path String (~40 bytes)│ │ Name Offset (3 bytes) │
│ Name String (~12 bytes) │ │ Parent ID (3 bytes) │
│ Size (8 bytes) │ │ Size Log2 (1 byte) │
│ Modified Time (8 bytes) │ │ Packed Data (4 bytes) │
│ Flags (4 bytes) │ └─────────────────────────────┘
└─────────────────────────────┘
Memory per entry: ~72 bytes Memory per entry: 11 bytes
Total for 10M files: ~720MB Total for 10M files: ~110MB
// Lightweight search index
const searchIndex = [{
idx: 0, // Row index
row: DOMElement, // Direct DOM reference
name: "filename", // Lowercase filename
nameEl: Element, // Name element for highlighting
originalName: "", // Original case filename
tokens: ["file", "name"] // Tokenized for fast search
}]- ✅ Real-time search with 150ms debouncing
- ✅ Substring matching - Find files by any part of filename
- ✅ Fuzzy search - Match files even with typos
- ✅ Token search - Match parts separated by
-,_,., spaces - ✅ Result highlighting - Matched text highlighted in results
- ✅ Result ranking - Exact matches first, then prefix, then length
- ✅ Recursive subdirectory search - Searches through all subdirectories via API
- ✅ Dropdown autocomplete - Shows matching files from subdirectories
- ✅ Keyboard navigation - Arrow keys and Enter to navigate dropdown
- ✅ Keyboard shortcuts:
Ctrl+F/Cmd+Fto focus searchEscapeto clear search or hide dropdown↑/↓arrows to navigate dropdownEnterto select dropdown item
- ✅ Live status: Shows "X of Y items" during search
- ✅ Smooth animations: Results animate in with highlight effect
- ✅ Mobile responsive: Optimized for mobile devices
- ✅ Performance monitoring: Logs slow searches (>10ms) for optimization
- ✅ Dual search modes: Local files + subdirectory API search
- ✅ Visual feedback: Icons, paths, and file sizes in dropdown
- ✅ Minimal footprint: Direct DOM references, no data duplication
- ✅ Lazy indexing: Token index built only for large directories
- ✅ Result limiting: Max 100 results displayed for performance
- ✅ Debouncing: Prevents excessive search operations
templates/directory/index.html- Added search containertemplates/directory/styles.css- Search UI styling with dark theme and dropdowntemplates/directory/script.js- Core search functionality with API integrationsrc/http.rs- Added search API endpoint for recursive subdirectory search
The search implementation uses a multi-stage approach:
-
Query Processing:
- Normalize query to lowercase for case-insensitive matching
- Trim whitespace and handle empty queries
-
Index Matching:
- Simple substring matching against filename/directory names
- Fast O(n) traversal of the indexed entries
-
Relevance Scoring:
- Exact matches score higher than partial matches
- Prefix matches score higher than substring matches
- Shorter filenames with matches score higher (more relevant)
-
Result Ranking:
- Sort results by relevance score (descending)
- Limit results to prevent overwhelming the UI (configurable)
Multi-level caching approach:
-
Search Result Cache: Stores computed search results
- Key: Query string
- Value: Vector of
SearchResultobjects - Eviction: LRU with TTL expiration
-
Directory Index Cache: In-memory index of file system
- Rebuilt only when necessary (directory modifications detected)
- Reduces file system traversal overhead
The search system automatically selects the optimal search engine based on directory size:
- <100K files: Standard search engine with full-text indexing and fuzzy search
- 100K-1M files: Transitions to ultra-compact mode with reduced features
- >1M files: Full ultra-compact mode with maximum memory efficiency
This selection is transparent to the API and frontend - search behavior remains consistent while optimizing performance.
Purpose: Perform search query against the directory index using the optimal search engine
Parameters:
q(required): Search query stringlimit(optional): Maximum number of results (default: 50, max: 100)offset(optional): Result offset for pagination (default: 0)case_sensitive(optional): Case-sensitive search (default: false)path(optional): Search within specific subdirectory
Response Format:
{
"status": "success",
"query": "filename",
"results": [
{
"name": "filename.txt",
"path": "/path/to/filename.txt",
"size": "1.2 KB",
"file_type": "text",
"score": 0.95,
"last_modified": 1704067200
}
],
"pagination": {
"total": 42,
"limit": 50,
"offset": 0,
"has_more": false
},
"search_stats": {
"search_time_ms": 12,
"indexed_files": 1247,
"cache_hit": false,
"engine_mode": "standard"
}
}Response Fields:
status: Request status ("success" or "error")results: Array of matching files/directories with relevance scorespagination: Pagination information for large result setssearch_stats: Performance metrics and search engine informationengine_mode: Which search engine was used ("standard" or "ultra_compact")
Error Responses:
400 Bad Request: Missing or invalid query parameter503 Service Unavailable: Search engine currently indexing500 Internal Server Error: Search engine failure
- Works seamlessly with existing keyboard navigation
- Preserves file type indicators and styling
- Compatible with intersection observer for large directories
- Hybrid approach: Client-side for current directory + server-side for subdirectories
- Modern browsers with ES6+ support
- Uses
requestAnimationFramefor smooth updates - Progressive enhancement - gracefully degrades if features unavailable
- Basic Search: Type filename or partial filename
- Multi-word: Space-separated terms (all must match)
- Fuzzy Search: Works even with minor typos
- Clear Search: Press Escape or delete all text
Tested on directories of various sizes:
Directory size: 50 files
Query "test": 0.8ms
Query "doc": 1.2ms
Query "index.html": 0.9ms
Directory size: 500 files
Query "test": 3.2ms
Query "doc": 4.1ms
Query "index.html": 2.8ms
Directory size: 1000 files
Query "test": 6.8ms
Query "doc": 7.9ms
Query "index.html": 5.2ms
Location: templates/directory/index.html
Components:
- Search input field with placeholder text
- Real-time search as user types (debounced)
- Loading states and result highlighting
- Keyboard navigation support
- Screen reader accessibility
JavaScript Implementation: templates/directory/script.js
Features:
- Debounced Search: 300ms delay to avoid excessive API calls
- Progressive Enhancement: Works without JavaScript (falls back to page refresh)
- Error Handling: Graceful degradation on API failures
- Loading States: Visual feedback during search operations
- Result Highlighting: Search terms highlighted in results
- Keyboard Support: Arrow keys for navigation, Enter to select
Location: templates/directory/styles.css
Search-specific styles:
.search-container: Main search interface container.search-input: Styled search input field.search-status: Screen reader status updates.search-results: Results display container.search-highlight: Highlighted search terms
-
Index Management:
- Indexes built asynchronously to prevent blocking
- Incremental updates when possible
- Memory limits to prevent excessive resource usage
-
Caching:
- LRU cache prevents memory growth
- TTL ensures data freshness
- Cache warming for common queries
-
Query Processing:
- Early termination for empty queries
- Limit result sets to prevent UI overload
- Case-insensitive preprocessing done once during indexing
-
Network Optimization:
- Debounced requests reduce server load
- Compressed JSON responses
- Efficient serialization of search results
- Maximum indexed files: 100,000 entries
- Maximum directory depth: 20 levels
- Cache size: 1,000 queries
- Search result limit: 1,000 results per query
- Memory usage: Approximately 1KB per indexed file
- All file paths are validated and sanitized
- Directory traversal attempts blocked (
../patterns) - Searches restricted to configured base directory
- Query strings sanitized to prevent injection attacks
- Maximum query length enforced
- Special characters handled safely
- Search respects existing authentication mechanisms
- No privilege escalation through search
- File permissions honored in results
# Search feature configuration
IRONDROP_SEARCH_ENABLED=true # Enable/disable search
IRONDROP_SEARCH_CACHE_SIZE=1000 # Max cached queries
IRONDROP_SEARCH_CACHE_TTL=300 # Cache TTL in seconds
IRONDROP_SEARCH_INDEX_UPDATE_INTERVAL=60 # Index update interval in seconds
IRONDROP_SEARCH_MAX_RESULTS=50 # Default max results per querySearch behavior can be configured through the SearchEngine::new() constructor:
let engine = SearchEngine::new(
base_directory,
cache_size, // Maximum cached queries
cache_ttl, // Cache TTL in seconds
);- Network failures: Graceful degradation to browsing
- Invalid queries: User-friendly error messages
- Rate limiting: Automatic retry with backoff
- Index corruption: Automatic rebuild
- Memory exhaustion: Graceful degradation
- File system errors: Logged with fallback behavior
The search functionality includes comprehensive tests as part of IronDrop's 189-test suite across 16 test files:
-
Ultra-Compact Search Tests (
tests/ultra_compact_test.rs- 4 tests):- RadixIndex memory efficiency with 10M entries
- Search performance optimization
- Path reconstruction accuracy
- CompactCache memory efficiency validation
-
Template Integration Tests (
tests/template_embedding_test.rs- 3 tests):- Embedded template rendering without filesystem access
- Static asset retrieval (CSS, JavaScript)
- Directory listing template rendering with search interface
-
Performance and Memory Tests:
- Memory optimization validation for large directories
- Search engine performance benchmarking
- Ultra-compact mode memory efficiency testing
- Microsecond-level performance measurement
-
Integration Testing:
- End-to-end search workflows
- API endpoint testing
- Template rendering with search elements
- Cross-browser compatibility validation
- Index build time: ~100ms for 1,000 files
- Search latency: <5ms for typical queries (cached)
- Memory usage: ~1MB for 10,000 indexed files
- Cache hit rate: >90% for typical usage patterns
-
Search not working:
- Verify search functionality is enabled
- Check server logs for indexing errors
- Ensure base directory is readable
-
Slow search performance:
- Monitor index size and memory usage
- Check for very deep directory structures
- Consider reducing search result limits
-
Missing results:
- Verify file permissions
- Check if index needs rebuilding
- Look for path traversal restrictions
-
Cache issues:
- Monitor cache hit rates
- Adjust cache TTL settings
- Clear cache through restart if needed
Enable debug logging to troubleshoot search issues:
RUST_LOG=debug ./irondropDebug logs include:
- Index building progress
- Cache hit/miss statistics
- Search query processing
- Performance timing information
- All search components are thread-safe
- Uses
Arc<Mutex<>>for shared state - Lock contention minimized through careful design
- Automatic cleanup of expired cache entries
- Bounded data structures prevent memory leaks
- Lazy loading of directory indexes
- Graceful handling of file system changes
- Automatic index rebuilding on corruption
- Fallback to directory browsing on search failure
-
Advanced Search:
- File type filtering (
.pdf,.jpg, etc.) - Size-based filtering (
>1MB,<10KB) - Date range searches
- Regular expression support
- File type filtering (
-
Search Analytics:
- Query performance metrics
- Popular search terms tracking
- Usage patterns analysis
-
Enhanced Relevance:
- Content-based searching (file contents)
- Fuzzy matching for typos
- Machine learning relevance scoring
-
UI Improvements:
- Search suggestions/autocomplete
- Recent searches history
- Saved search queries
- Advanced search filters UI
The implementation has been tested with:
- ✅ Directories with 1-5000 files
- ✅ Various filename patterns and special characters
- ✅ Mobile and desktop browsers
- ✅ Keyboard navigation integration
- ✅ Performance under load
This search implementation provides:
- Fast performance: Sub-10ms search guaranteed
- Low memory usage: <500KB overhead maximum
- Great UX: Smooth, responsive interface
- Scalable: Works from 1 to 1000+ files
- Maintainable: Clean, well-documented code
- Zero dependencies: Pure JavaScript implementation
The search bar enhances the IronDrop file browsing experience significantly while maintaining the project's principles of simplicity, performance, and minimal resource usage.