mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-03-02 07:23:38 +00:00
Add an index specifically for improving thread count perf.
This commit is contained in:
committed by
Nicholas Tinsley
parent
bc1c8032c1
commit
494b2c6786
@@ -268,6 +268,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_DATE_SENT_FROM_TO_THREAD = "message_date_sent_from_to_thread_index"
|
||||
private const val INDEX_THREAD_COUNT = "message_thread_count_index"
|
||||
|
||||
@JvmField
|
||||
val CREATE_INDEXS = arrayOf(
|
||||
@@ -286,7 +287,9 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
"CREATE INDEX IF NOT EXISTS message_latest_revision_id_index ON $TABLE_NAME ($LATEST_REVISION_ID)",
|
||||
"CREATE INDEX IF NOT EXISTS message_from_recipient_id_index ON $TABLE_NAME ($FROM_RECIPIENT_ID)",
|
||||
"CREATE INDEX IF NOT EXISTS message_to_recipient_id_index ON $TABLE_NAME ($TO_RECIPIENT_ID)",
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS message_unique_sent_from_thread ON $TABLE_NAME ($DATE_SENT, $FROM_RECIPIENT_ID, $THREAD_ID)"
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS message_unique_sent_from_thread ON $TABLE_NAME ($DATE_SENT, $FROM_RECIPIENT_ID, $THREAD_ID)",
|
||||
// This index is created specifically for getting the number of messages in a thread and therefore needs to be kept in sync with that query
|
||||
"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"
|
||||
)
|
||||
|
||||
private val MMS_PROJECTION_BASE = arrayOf(
|
||||
@@ -1810,17 +1813,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
fun getMessageCountForThread(threadId: Long): Int {
|
||||
return readableDatabase
|
||||
.select("COUNT(*)")
|
||||
.from("$TABLE_NAME INDEXED BY $INDEX_THREAD_STORY_SCHEDULED_DATE_LATEST_REVISION_ID")
|
||||
.where("$THREAD_ID = ? AND $STORY_TYPE = ? AND $PARENT_STORY_ID <= ? AND $SCHEDULED_DATE = ? AND $LATEST_REVISION_ID IS NULL", threadId, 0, 0, -1)
|
||||
.run()
|
||||
.readToSingleInt()
|
||||
}
|
||||
|
||||
fun getMessageCountForThread(threadId: Long, beforeTime: Long): Int {
|
||||
return readableDatabase
|
||||
.select("COUNT(*)")
|
||||
.from("$TABLE_NAME INDEXED BY $INDEX_THREAD_STORY_SCHEDULED_DATE_LATEST_REVISION_ID")
|
||||
.where("$THREAD_ID = ? AND $DATE_RECEIVED < ? AND $STORY_TYPE = ? AND $PARENT_STORY_ID <= ? AND $SCHEDULED_DATE = ? AND $LATEST_REVISION_ID IS NULL", threadId, beforeTime, 0, 0, -1)
|
||||
.from("$TABLE_NAME INDEXED BY $INDEX_THREAD_COUNT")
|
||||
.where("$THREAD_ID = $threadId AND $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND $LATEST_REVISION_ID IS NULL")
|
||||
.run()
|
||||
.readToSingleInt()
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V202_DropMessageTab
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V203_PreKeyStaleTimestamp
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V204_GroupForeignKeyMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V205_DropPushTable
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V206_AddConversationCountIndex
|
||||
|
||||
/**
|
||||
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
|
||||
@@ -69,7 +70,7 @@ object SignalDatabaseMigrations {
|
||||
|
||||
val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
|
||||
|
||||
const val DATABASE_VERSION = 205
|
||||
const val DATABASE_VERSION = 206
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
@@ -300,6 +301,10 @@ object SignalDatabaseMigrations {
|
||||
if (oldVersion < 205) {
|
||||
V205_DropPushTable.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
|
||||
if (oldVersion < 206) {
|
||||
V206_AddConversationCountIndex.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* Add an index to speed up thread counts.
|
||||
*/
|
||||
@Suppress("ClassName")
|
||||
object V206_AddConversationCountIndex : SignalDatabaseMigration {
|
||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL("CREATE INDEX IF NOT EXISTS message_thread_count_index ON message (thread_id) WHERE story_type = 0 AND parent_story_id <= 0 AND scheduled_date = -1 AND latest_revision_id IS NULL")
|
||||
}
|
||||
}
|
||||
@@ -373,10 +373,8 @@ public final class MessageRequestRepository {
|
||||
|
||||
@WorkerThread
|
||||
private boolean isLegacyThread(@NonNull Recipient recipient) {
|
||||
Context context = ApplicationDependencies.getApplication();
|
||||
Long threadId = SignalDatabase.threads().getThreadIdFor(recipient.getId());
|
||||
Long threadId = SignalDatabase.threads().getThreadIdFor(recipient.getId());
|
||||
|
||||
return threadId != null &&
|
||||
(RecipientUtil.hasSentMessageInThread(threadId) || RecipientUtil.isPreMessageRequestThread(threadId));
|
||||
return threadId != null && RecipientUtil.hasSentMessageInThread(threadId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,9 +138,10 @@ public class ApplicationMigrations {
|
||||
static final int IDENTITY_FIX = 94;
|
||||
static final int COPY_USERNAME_TO_SIGNAL_STORE = 95;
|
||||
static final int RECHECK_PAYMENTS = 96;
|
||||
static final int THREAD_COUNT_DB_MIGRATION = 97;
|
||||
}
|
||||
|
||||
public static final int CURRENT_VERSION = 96;
|
||||
public static final int CURRENT_VERSION = 97;
|
||||
|
||||
/**
|
||||
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
|
||||
@@ -627,6 +628,10 @@ public class ApplicationMigrations {
|
||||
jobs.put(Version.RECHECK_PAYMENTS, new RecheckPaymentsMigrationJob());
|
||||
}
|
||||
|
||||
if (lastSeenVersion < Version.THREAD_COUNT_DB_MIGRATION) {
|
||||
jobs.put(Version.THREAD_COUNT_DB_MIGRATION, new DatabaseMigrationJob());
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
|
||||
@@ -280,27 +280,13 @@ public class RecipientUtil {
|
||||
return isCallRequestAccepted(threadId, threadRecipient);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if a conversation existed before we enabled message requests, otherwise false.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static boolean isPreMessageRequestThread(@Nullable Long threadId) {
|
||||
long beforeTime = SignalStore.misc().getMessageRequestEnableTime();
|
||||
return threadId != null && SignalDatabase.messages().getMessageCountForThread(threadId, beforeTime) > 0;
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static void shareProfileIfFirstSecureMessage(@NonNull Recipient recipient) {
|
||||
if (recipient.isProfileSharing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
long threadId = SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId());
|
||||
|
||||
if (isPreMessageRequestThread(threadId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
long threadId = SignalDatabase.threads().getThreadIdIfExistsFor(recipient.getId());
|
||||
boolean firstMessage = SignalDatabase.messages().getOutgoingSecureMessageCount(threadId) == 0;
|
||||
|
||||
if (firstMessage || recipient.isHidden()) {
|
||||
@@ -364,8 +350,7 @@ public class RecipientUtil {
|
||||
!threadRecipient.isRegistered() ||
|
||||
(!threadRecipient.isHidden() && (
|
||||
hasSentMessageInThread(threadId) ||
|
||||
noSecureMessagesAndNoCallsInThread(threadId) ||
|
||||
isPreMessageRequestThread(threadId))
|
||||
noSecureMessagesAndNoCallsInThread(threadId))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -373,8 +358,7 @@ public class RecipientUtil {
|
||||
private static boolean isCallRequestAccepted(@Nullable Long threadId, @NonNull Recipient threadRecipient) {
|
||||
return threadRecipient.isProfileSharing() ||
|
||||
threadRecipient.isSystemContact() ||
|
||||
hasSentMessageInThread(threadId) ||
|
||||
isPreMessageRequestThread(threadId);
|
||||
hasSentMessageInThread(threadId);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
||||
Reference in New Issue
Block a user