Repository navigation
Conversation
Three chat_messages scans run at every login before the chat list paints: failInterruptedSends (from recoverInterruptedSends, which blocks first paint), hasDuplicateClientIds and chatsWithKeyPending. Each reads the whole table for rows that are almost never there. v53 adds one partial index per scan, each holding only the rows it looks for: status = 'SENDING', encryption_state = 'KEY_PENDING', and (chat_id_hex, pending_client_id_hex) where the client id is set. Each WHERE repeats its scan's condition, since SQLite only uses a partial index for a query whose WHERE implies the index's. @Index can't express WHERE. The entity declares the same names and columns so Room's schema check, which compares names, columns and uniqueness and not the WHERE, accepts them, and 53.json shows full indexes. ChatPartialIndexes.ensure replaces any of the three that isn't partial: Migration52To53 calls it after the auto-migration creates them, and a Callback calls it on every open, which covers a fresh install and any later migration that rebuilds chat_messages from the entity. ChatPartialIndexMigrationTest builds a v52 database from 52.json, upgrades it through Room, and checks the rows survive, all three indexes are partial and the scans return what they did. It also checks a fresh database, that each scan's condition plans through its index, and that an index rebuilt without its WHERE is fixed on the next open.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three
chat_messagesscans run at every login:failInterruptedSends(fromrecoverInterruptedSends, which blocks first paint atRealChatCoordinator.kt:169-170),hasDuplicateClientIdsandchatsWithKeyPending. Each reads the whole table looking for rows that are almost never there.Change
status = 'SENDING',encryption_state = 'KEY_PENDING', and(chat_id_hex, pending_client_id_hex)wherepending_client_id_hex IS NOT NULL. Each WHERE repeats its scan's condition, because SQLite uses a partial index only for a query whose WHERE implies the index's.@Indexcan't declare a WHERE.ChatMessageEntitydeclares the three indexes by the same names and columns, so Room's schema check passes (it compares name, columns and uniqueness, not the WHERE). As a result53.jsonshows them as full indexes.ChatPartialIndexes.ensurereplaces any of the three that isn't partial.Migration52To53(the spec on the 52→53 auto-migration) calls it after Room creates the indexes, and aRoomDatabase.Callbackcalls it on every open. The open hook covers fresh installs, and any later migration that rebuildschat_messagesfrom the entity and recreates them as full indexes.Tests
ChatPartialIndexMigrationTestbuilds a v52 database from52.jsonand upgrades it through Room. It checks that the rows survive, that all three indexes are partial, and that each scan returns what it did before. It also covers a fresh database, checks that each scan plans through its index, and checks that an index rebuilt without its WHERE is fixed on the next open.Numbers
Chat-load harness,
ChatArrivalBenchmarkTest.launchIndexExperiment, 1000 chats x 10,000 messages, median of the timed runs:code/cashhasDuplicateClientIdsfailInterruptedSendschatsWithKeyPendingThe
code/cashcolumn is the harness baseline from 2026-11-06. The branch column is the harness's BEFORE phase run on this branch, with its seed database opened throughChatPartialIndexes.Callback. The harness's AFTER phase adds its own experiment indexes on top of these, so it isn't the comparison. The machine's load average was between 24 and 90 during the branch run.