Skip to content

perf(lexical/search): no query result / filter cache layer (LRU + Roaring) #578

@mosuka

Description

@mosuka

Round-3 perf push sub-issue (tracked under umbrella #534).

[XL] No query result / filter cache layer (LRU + Roaring)

  • Where: cross-cutting; entry InvertedIndexSearcher::search (searcher.rs:632). No QueryCache / FilterCache type exists.
  • Current behavior: every query re-decodes every posting list. Even repeated SearchRequest::filter_query (engine/search.rs:190) is re-evaluated from scratch. No doc-set memoisation, no Query → bitset rewrite, no small-vs-large clause hit-set strategy.
  • Why it might be a bottleneck / risk: filter clauses dominate application workloads (tenancy, category, status flag). Multi-tenant servers cannot amortise. The single biggest scaling gap vs Lucene/Tantivy.
  • Reference precedent: Lucene LRUQueryCache materialises a BitDocIdSet (FixedBitSet or Roaring) per (segment, query); Tantivy ships QueryCache in tantivy-common. Both key on Query::hashCode/Eq.
  • Data structure (current → proposed): nothing → segment-keyed LruCache<Arc<dyn QueryKey>, Arc<RoaringBitmap>>. Roaring is the right choice: dense ranges become RunContainers, sparse facet filters stay ArrayContainers, and word-level AND/OR is 64-bit-aligned.
  • Suggested direction: add QueryCacheKey (hash + eq) on Query; gate with Query::cacheable() -> bool (skip score-dependent); add Arc<QueryCache> on InvertedIndexReader. Miss → materialise RoaringBitmap from the existing matcher; hit → single Roaring::contains/intersection.
  • Risk / scope: needs Eq + Hash on every concrete Query impl (15+ types under laurus/src/lexical/query/); large but mechanical.

ID: LS-01 — see ~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.md for the full Round-3 issue list.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions