Skip to content

refactor(datagrid): merge sortCache into coordinator.querySortCache#937

Merged
datlechin merged 2 commits intomainfrom
refactor/datagrid-merge-sort-caches
Apr 29, 2026
Merged

refactor(datagrid): merge sortCache into coordinator.querySortCache#937
datlechin merged 2 commits intomainfrom
refactor/datagrid-merge-sort-caches

Conversation

@datlechin
Copy link
Copy Markdown
Member

Summary

Drops the duplicate sort cache. MainEditorContentView had a @State var sortCache: [UUID: SortedRowsCache] for the sync inline-sort path (≤1000 rows). MainContentCoordinator had @ObservationIgnored var querySortCache: [UUID: QuerySortCacheEntry] for the async background-sort path. The two structs were byte-identical (sortedIDs: [RowID], columnIndex: Int, direction: SortDirection, schemaVersion: Int).

Both writes now go to coordinator.querySortCache. The view-side cache is gone.

Stale-sort bug fixed as a side effect

Row-mutation invalidations in MainContentCoordinator+RowOperations (six call sites: addNewRow, deleteSelectedRows, duplicateSelectedRow, undoInsertRow, handleUndoResult, pasteRows) called querySortCache.removeValue(forKey: tabId) but never touched the view-side sortCache. A small (≤1000-row) sorted table that received an add / delete / undo / paste would return stale sortedIDs until the user clicked the column header again. After the merge, both paths share one cache and one invalidation set.

Drops

  • private struct SortedRowsCache (was duplicate of QuerySortCacheEntry)
  • @State private var sortCache in MainEditorContentView
  • The conditional view-side cleanup in onChange(of: tabStructureVersion)
  • sortCache.removeAll() from the onTeardown handler
  • The sync-cache lookup branch in sortedIDsForTab

coordinator.cleanupSortCache(openTabIds:) and querySortCache.removeAll() (called on coordinator teardown at MainContentCoordinator.swift:585) cover both paths uniformly.

Net −33 / +2 LOC.

Test plan

  • Build clean
  • Manual: small table (≤1000 rows) sort by header — sorts ✓
  • Manual: large table (>1000 rows) sort by header — async sort ✓
  • Manual: sort + edit a cell — sorted view stays correct
  • Manual: sort + add row — new row appears at end of sorted view
  • Manual: switch tabs and back — sort persists

The view-side @State sortCache (in MainEditorContentView) and the coordinator's @ObservationIgnored querySortCache stored byte-identical SortedRowsCache / QuerySortCacheEntry structs keyed by tab ID. Two write paths fed them: sync inline sort (small tables, ≤1000 rows) wrote to the view-side cache; async background sort (large tables) wrote to the coordinator-side cache. The read in sortedIDsForTab checked both.

The split was historical, not architectural. Both caches share the same lifecycle (window/coordinator) and the row-mutation invalidations in MainContentCoordinator+RowOperations only cleared querySortCache — meaning a sync-sorted small table would silently return a stale sortedIDs after add/delete/undo. Bug fixed as a side effect of the merge.

Drops:
- private struct SortedRowsCache
- @State var sortCache from MainEditorContentView
- The two-step cache cleanup in onChange(of: tabStructureVersion) and onTeardown
- The sortCache lookup branch in sortedIDsForTab

The sync sort path now writes directly to coordinator.querySortCache. cleanupSortCache and the row-mutation invalidations cover both paths uniformly. -23 LOC.
Four tests cover the four mutation pathways through the now-merged querySortCache:
- addNewRow invalidates the cache (was view-side sortCache before merge — silently stale)
- duplicateSelectedRow invalidates
- deleteSelectedRows invalidates when physically removing inserted rows
- deleteSelectedRows preserves the cache on soft-delete of existing rows (sortedIDs reference rows by ID, soft-delete only changes appearance, not order)

Documents the soft-delete-preserves invariant that emerged during test writing — guards a future contributor from "helpfully" invalidating on every delete and breaking sort persistence.
@datlechin datlechin merged commit a027cdd into main Apr 29, 2026
2 checks passed
@datlechin datlechin deleted the refactor/datagrid-merge-sort-caches branch April 29, 2026 05:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant