mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-07-02 12:05:46 +01:00
Add index to make marking unread faster.
This commit is contained in:
committed by
Michelle Tang
parent
ed73dc2c24
commit
b2f450d849
@@ -310,6 +310,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
"""
|
||||
|
||||
private const val INDEX_THREAD_STORY_SCHEDULED_DATE_LATEST_REVISION_ID = "message_thread_story_parent_story_scheduled_date_latest_revision_id_index"
|
||||
private const val INDEX_THREAD_DATE_RECEIVED_UNREAD = "message_thread_date_received_unread_index"
|
||||
private const val INDEX_DATE_SENT_FROM_TO_THREAD = "message_date_sent_from_to_thread_index"
|
||||
private const val INDEX_THREAD_COUNT = "message_thread_count_index"
|
||||
private const val INDEX_THREAD_UNREAD_COUNT = "message_thread_unread_count_index"
|
||||
@@ -339,6 +340,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
"CREATE INDEX IF NOT EXISTS $INDEX_THREAD_COUNT ON $TABLE_NAME ($THREAD_ID) WHERE $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND $LATEST_REVISION_ID IS NULL AND $COLLAPSED_STATE != ${CollapsedState.COLLAPSED.id}",
|
||||
// This index is created specifically for getting the number of unread messages in a thread and therefore needs to be kept in sync with that query
|
||||
"CREATE INDEX IF NOT EXISTS $INDEX_THREAD_UNREAD_COUNT ON $TABLE_NAME ($THREAD_ID) WHERE $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND $ORIGINAL_MESSAGE_ID IS NULL AND $READ = 0",
|
||||
// Partial index for marking messages read in a thread (see setMessagesReadSince). Only contains unread/unseen rows.
|
||||
"CREATE INDEX IF NOT EXISTS $INDEX_THREAD_DATE_RECEIVED_UNREAD ON $TABLE_NAME ($THREAD_ID, $DATE_RECEIVED) WHERE $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND ($READ = 0 OR $REACTIONS_UNREAD = 1 OR $VOTES_UNREAD = 1)",
|
||||
"CREATE INDEX IF NOT EXISTS message_votes_unread_index ON $TABLE_NAME ($VOTES_UNREAD)",
|
||||
"CREATE INDEX IF NOT EXISTS message_pinned_until_index ON $TABLE_NAME ($PINNED_UNTIL)",
|
||||
"CREATE INDEX IF NOT EXISTS message_pinned_at_index ON $TABLE_NAME ($PINNED_AT)",
|
||||
@@ -2523,22 +2526,26 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
fun setMessagesReadSince(threadId: Long, sinceTimestamp: Long): List<MarkedMessageInfo> {
|
||||
// The standalone "($READ = 0 OR $REACTIONS_UNREAD = 1 OR $VOTES_UNREAD = 1)" term below is logically redundant -- it's implied by the
|
||||
// larger read/reactions/votes clause that follows. We need it to satisfy the query planner so we can use INDEX_THREAD_DATE_RECEIVED_UNREAD.
|
||||
// The index needs to appear exactly in the query.
|
||||
var query = """
|
||||
$THREAD_ID = ? AND
|
||||
$STORY_TYPE = 0 AND
|
||||
$PARENT_STORY_ID <= 0 AND
|
||||
$THREAD_ID = ? AND
|
||||
$STORY_TYPE = 0 AND
|
||||
$PARENT_STORY_ID <= 0 AND
|
||||
(
|
||||
$ORIGINAL_MESSAGE_ID IS NULL OR
|
||||
$LATEST_REVISION_ID IS NULL
|
||||
) AND
|
||||
) AND
|
||||
($READ = 0 OR $REACTIONS_UNREAD = 1 OR $VOTES_UNREAD = 1) AND
|
||||
(
|
||||
$READ = 0 OR
|
||||
$READ = 0 OR
|
||||
(
|
||||
$REACTIONS_UNREAD = 1 AND
|
||||
$REACTIONS_UNREAD = 1 AND
|
||||
($outgoingTypeClause)
|
||||
) OR
|
||||
(
|
||||
$VOTES_UNREAD = 1 AND
|
||||
$VOTES_UNREAD = 1 AND
|
||||
($outgoingTypeClause)
|
||||
)
|
||||
)
|
||||
@@ -2551,7 +2558,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
args += sinceTimestamp.toString()
|
||||
}
|
||||
|
||||
return setMessagesRead(query, args.toTypedArray())
|
||||
return setMessagesRead(query, args.toTypedArray(), index = INDEX_THREAD_DATE_RECEIVED_UNREAD)
|
||||
}
|
||||
|
||||
fun setGroupStoryMessagesReadSince(threadId: Long, groupStoryId: Long, sinceTimestamp: Long): List<MarkedMessageInfo> {
|
||||
@@ -2618,7 +2625,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
|
||||
private fun setMessagesRead(where: String, arguments: Array<String>?, index: String = INDEX_THREAD_STORY_SCHEDULED_DATE_LATEST_REVISION_ID): List<MarkedMessageInfo> {
|
||||
val releaseChannelId = SignalStore.releaseChannel.releaseChannelRecipientId
|
||||
return writableDatabase.rawQuery(
|
||||
val startTime = System.currentTimeMillis()
|
||||
val results = writableDatabase.rawQuery(
|
||||
"""
|
||||
UPDATE $TABLE_NAME INDEXED BY $index
|
||||
SET $READ = 1, $REACTIONS_UNREAD = 0, $REACTIONS_LAST_SEEN = ${System.currentTimeMillis()}, $VOTES_UNREAD = 0, $VOTES_LAST_SEEN = ${System.currentTimeMillis()}
|
||||
@@ -2645,6 +2653,10 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
}
|
||||
.filterNotNull()
|
||||
|
||||
Log.d(TAG, "[setMessagesRead] Updated ${results.size} messages in ${System.currentTimeMillis() - startTime} ms using index $index.")
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
fun getOldestUnreadMentionDetails(threadId: Long): Pair<RecipientId, Long>? {
|
||||
|
||||
+4
-2
@@ -169,6 +169,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V313_AddCollapsingU
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V314_FixMessageRequestAcceptedToRecipient
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V315_CleanupE164SenderKeyShared
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V316_AddVerifiedGroupNameHashMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V317_AddMessageThreadDateReceivedUnreadIndex
|
||||
import org.thoughtcrime.securesms.database.SQLiteDatabase as SignalSqliteDatabase
|
||||
|
||||
/**
|
||||
@@ -345,10 +346,11 @@ object SignalDatabaseMigrations {
|
||||
313 to V313_AddCollapsingUpdateColumns,
|
||||
314 to V314_FixMessageRequestAcceptedToRecipient,
|
||||
315 to V315_CleanupE164SenderKeyShared,
|
||||
316 to V316_AddVerifiedGroupNameHashMigration
|
||||
316 to V316_AddVerifiedGroupNameHashMigration,
|
||||
317 to V317_AddMessageThreadDateReceivedUnreadIndex
|
||||
)
|
||||
|
||||
const val DATABASE_VERSION = 316
|
||||
const val DATABASE_VERSION = 317
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SignalSqliteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import org.thoughtcrime.securesms.database.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* Adds a partial index on message (thread_id, date_received) containing only unread/unseen rows. This lets the mark-thread-read query in
|
||||
* MessageTable.setMessagesReadSince seek straight to the relevant rows instead of scanning the whole thread.
|
||||
*/
|
||||
@Suppress("ClassName")
|
||||
object V317_AddMessageThreadDateReceivedUnreadIndex : SignalDatabaseMigration {
|
||||
|
||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL("CREATE INDEX IF NOT EXISTS message_thread_date_received_unread_index ON message (thread_id, date_received) WHERE story_type = 0 AND parent_story_id <= 0 AND (read = 0 OR reactions_unread = 1 OR votes_unread = 1)")
|
||||
}
|
||||
}
|
||||
@@ -200,9 +200,10 @@ public class ApplicationMigrations {
|
||||
static final int COLLAPSED_EVENTS_2 = 156;
|
||||
static final int KEY_TRANSPARENCY = 157;
|
||||
static final int RELEASE_NOTES_CHAT_SYNC = 158;
|
||||
static final int READ_INDEX_DB_MIGRATION = 159;
|
||||
}
|
||||
|
||||
public static final int CURRENT_VERSION = 158;
|
||||
public static final int CURRENT_VERSION = 159;
|
||||
|
||||
/**
|
||||
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
|
||||
@@ -929,6 +930,10 @@ public class ApplicationMigrations {
|
||||
jobs.put(Version.RELEASE_NOTES_CHAT_SYNC, new AccountRecordMigrationJob());
|
||||
}
|
||||
|
||||
if (lastSeenVersion < Version.READ_INDEX_DB_MIGRATION) {
|
||||
jobs.put(Version.READ_INDEX_DB_MIGRATION, new DatabaseMigrationJob());
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user