You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2.2 KiB

+++ title = "SQLite cache for list performance" priority = 3 status = "todo" ticket_type = "feature" dependencies = [] +++ Add an optional SQLite cache in .nbd/cache.db to accelerate nbd list and nbd ready for large ticket stores.

Motivation

list_tickets currently does O(n) file reads on every call. For stores with hundreds of tickets this is measurably slow. A SQLite cache avoids re-reading unchanged files by comparing file modification times (mtimes).

Approach

Crate dependency

Add sqlx with the sqlite and runtime-async-std features to Cargo.toml.

store.rs additions

New async function open_cache(root: &Path) -> Result<sqlx::SqlitePool>:

  • Opens (or creates) .nbd/cache.db.
  • Runs a migration: CREATE TABLE IF NOT EXISTS tickets (id TEXT PRIMARY KEY, json TEXT NOT NULL, mtime INTEGER NOT NULL).

New function list_tickets_cached(root: &Path) -> Result<Vec<Ticket>>:

  1. Open cache.
  2. Read directory listing to get file names and mtimes.
  3. For each file: if the DB has a row with matching mtime, use cached JSON; otherwise read file, parse, insert/update row.
  4. Delete DB rows for IDs no longer on disk.
  5. Return deserialized tickets sorted by priority desc.

Keep existing list_tickets as the non-cached fallback. Consider making cmd_list and cmd_ready use list_tickets_cached when available.

Migration strategy

  • The cache is always optional. If cache.db can't be opened, fall back to list_tickets (log a warning to stderr).
  • The cache is never the source of truth — the JSON files are. The cache is always reconstructable by deleting .nbd/cache.db.

Decision point

Decide whether to enable the cache unconditionally or gate it behind a flag (--cache / NBD_CACHE=1). Recommendation: enable by default once the feature is stable.

Tests

  • Unit test: cache hit returns same data as direct file read.
  • Unit test: cache miss (mtime changed) re-reads the file.
  • Unit test: deleted ticket is evicted from cache.
  • Performance test (optional): benchmark 1000-ticket list with and without cache.

Files touched

  • Cargo.toml — add sqlx
  • src/store.rsopen_cache, list_tickets_cached
  • src/tests.rs — cache unit tests
  • docs/ARCHITECTURE.md — document the cache layer