Skip to content

findSymbol should use symbol_index for O(1) lookup instead of scanning all outlines #309

@justrach

Description

@justrach

Summary

Explorer.findSymbol currently iterates every entry in self.outlines for every call (src/explore.zig around line 1256 on main). For a large project this is O(files × symbols-per-file) per query — the find command and any downstream HTTP/MCP endpoints that call it pay that cost even though an O(1) symbol_index map already exists on the explorer.

Two things need to change together for the index to be a safe replacement:

  1. Use the index in findSymbol. Look up the name in self.symbol_index; if it's present, build SymbolResult entries from the locations and return. Keep the current outline scan as a fallback so the change is defensive — if indexing ever misses a kind the old behavior still covers it.

  2. Stop excluding kinds from the index. rebuildSymbolIndexFor currently skips .import and .comment_block:

    if (sym.kind == .import or sym.kind == .comment_block) continue;

    That makes the index incomplete — imports are often exactly what a user searches for ("find Store" → the import line). Without this, the O(1) path misses those hits and callers silently diverge from the scan-based path. Removing the skip makes the index authoritative.

Why this matters

  • find is a hot path (it's hit from shell usage, MCP tools, and any restored HTTP server endpoint — see Restore codedb serve --port HTTP endpoint on Zig 0.16 #307)
  • O(1) vs O(files) on a large project is the difference between ~µs and tens of ms per call
  • Without change (2), lookups for imports fall through to the slow path; worse, if callers start trusting the index-only path, they'd get wrong answers

Scope

  • src/explore.zig:
    • findSymbol — add index lookup before the existing scan
    • rebuildSymbolIndexFor — drop the kind filter so every symbol is indexed

Verification

  • Existing find output should be unchanged (same kinds, same order per file)
  • A micro-benchmark on a project with many files should show findSymbol dropping from linear in file count to constant

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions