You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Mobile: SwiftDataCacheStore eviction scans full table + read() writes on every hit #45
PR #14 (SwiftData-backed offline cache, issue #4) shipped SwiftDataCacheStore. Two
independent performance-focused review-cli passes (GLM-5.2 and Claude Opus) flagged the
same two issues across two separate review iterations:
1. evictIfNeeded() fetches every row (including payload blobs) on every write — High
SwiftData has no attribute-level projection, so this fully hydrates every row's payload: Data blob, not just payloadSize/fetchedAt, just to sum an Int. Worst
case per write (default caps: 200 entries / 20 MB): up to ~20 MB copied out of SQLite
plus a sort. This runs on every successful list load (pull-to-refresh, every
foreground-return sync added by this same PR).
Suggested fix: maintain a running entryCount/totalBytes inside the actor (sole
writer; rehydrate once at init with one aggregate pass), and only run the sorted
full-fetch when a cap is actually exceeded.
2. read() performs a SQLite write (UPDATE + save) on every cache hit — Medium
Same file, read():
row.fetchedAt =Date()try? context.save()
This is a deliberate LRU-on-read design (documented in-code) but means every cache read
— the offline hot path this PR exists to serve — is a persisted write transaction
(WAL append/fsync). Drilling into a repo offline does 3+ fallback reads (tree, PRs,
issues), each now a write txn.
Suggested fix: throttle the bump (e.g. only persist fetchedAt if it's more than ~60s
stale) — LRU correctness doesn't need per-read precision.
Acceptance criteria
Eviction check no longer fetches the full row set (including payload blobs) on
every write when caps aren't exceeded.
Cache reads no longer unconditionally trigger a SQLite write; fetchedAt bump is
throttled or batched instead.
Existing SwiftDataCacheStoreTests (eviction, LRU-on-read) still pass.
User impact if not fixed
Not a correctness bug — data stays consistent either way — but on the exact hot paths
this feature targets (offline browsing, foreground-return sync), every list load/read
does more SQLite I/O than necessary, which shows up as extra disk writes and latency on
low-end devices or larger caches.
Activity