From 6d415ca85a24266a7c62c6853f027398fe77ca8d Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 4 Dec 2024 15:51:33 -0500 Subject: [PATCH] Fix backup perf issue by doing cleanup inline. --- .../database/MessageTableArchiveExtensions.kt | 13 +--- .../v2/exporters/ChatItemArchiveExporter.kt | 72 +++++++++++++------ 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/database/MessageTableArchiveExtensions.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/database/MessageTableArchiveExtensions.kt index 9893ca7dfe..dd05438996 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/database/MessageTableArchiveExtensions.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/database/MessageTableArchiveExtensions.kt @@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.backup.v2.exporters.ChatItemArchiveExporter import org.thoughtcrime.securesms.backup.v2.importer.ChatItemArchiveImporter import org.thoughtcrime.securesms.database.GroupTable import org.thoughtcrime.securesms.database.MessageTable -import org.thoughtcrime.securesms.database.MessageTypes import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.recipients.RecipientId @@ -68,6 +67,7 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, medi // Unfortunately we have some bad legacy data where the from_recipient_id is a group. // This cleans it up. Reminder, this is only a snapshot of the data. + val cleanupStartTime = System.currentTimeMillis() db.rawWritableDatabase.execSQL( """ UPDATE ${MessageTable.TABLE_NAME} @@ -78,16 +78,7 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, medi ) """ ) - - // If someone re-registers with a new phone number, previous outgoing messages will no longer be associated with self. - // This cleans it up by changing the from to be the current self id for all outgoing messages. - db.rawWritableDatabase.execSQL( - """ - UPDATE ${MessageTable.TABLE_NAME} - SET ${MessageTable.FROM_RECIPIENT_ID} = ${selfRecipientId.toLong()} - WHERE (${MessageTable.TYPE} & ${MessageTypes.BASE_TYPE_MASK}) IN (${MessageTypes.OUTGOING_MESSAGE_TYPES.joinToString(",")}) - """ - ) + Log.d(TAG, "Cleanup took ${System.currentTimeMillis() - cleanupStartTime} ms") return ChatItemArchiveExporter( db = db, diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt index 500d55a381..28147f4141 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt @@ -390,36 +390,60 @@ private fun simpleUpdate(type: SimpleChatUpdate.Type): ChatUpdateMessage { private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: RecipientId, isGroupThread: Boolean, groupReceipts: List?, exportState: ExportState, backupStartTime: Long): ChatItem.Builder? { val record = this + val direction = when { + record.type.isDirectionlessType() || record.messageExtras?.gv2UpdateDescription != null -> { + Direction.DIRECTIONLESS + } + MessageTypes.isOutgoingMessageType(record.type) || record.fromRecipientId == selfRecipientId.toLong() -> { + Direction.OUTGOING + } + else -> { + Direction.INCOMING + } + } + + // If a user restores a backup with a different number, then they'll have outgoing messages from a non-self contact. + // We want to ensure all outgoing messages are from ourselves. + val fromRecipientId = if (direction == Direction.OUTGOING) { + selfRecipientId.toLong() + } else { + record.fromRecipientId + } + val builder = ChatItem.Builder().apply { chatId = record.threadId - authorId = record.fromRecipientId + authorId = fromRecipientId dateSent = record.dateSent expireStartDate = record.expireStarted.takeIf { it > 0 } expiresInMs = record.expiresIn.takeIf { it > 0 } revisions = emptyList() sms = record.type.isSmsType() - if (record.type.isDirectionlessType() || record.messageExtras?.gv2UpdateDescription != null) { - directionless = ChatItem.DirectionlessMessageDetails() - } else if (MessageTypes.isOutgoingMessageType(record.type) || record.fromRecipientId == selfRecipientId.toLong()) { - outgoing = ChatItem.OutgoingMessageDetails( - sendStatus = record.toRemoteSendStatus(isGroupThread, groupReceipts, exportState) - ) - - if (expiresInMs != null && outgoing?.sendStatus?.all { it.pending == null && it.failed == null } == true) { - Log.w(TAG, "Outgoing expiring message was sent but the timer wasn't started! Fixing.") - expireStartDate = record.dateReceived + when (direction) { + Direction.DIRECTIONLESS -> { + directionless = ChatItem.DirectionlessMessageDetails() } - } else { - incoming = ChatItem.IncomingMessageDetails( - dateServerSent = record.dateServer.takeIf { it > 0 }, - dateReceived = record.dateReceived, - read = record.read, - sealedSender = record.sealedSender - ) + Direction.OUTGOING -> { + outgoing = ChatItem.OutgoingMessageDetails( + sendStatus = record.toRemoteSendStatus(isGroupThread, groupReceipts, exportState) + ) - if (expiresInMs != null && incoming?.read == true && expireStartDate == null) { - Log.w(TAG, "Incoming expiring message was read but the timer wasn't started! Fixing.") - expireStartDate = record.dateReceived + if (expiresInMs != null && outgoing?.sendStatus?.all { it.pending == null && it.failed == null } == true) { + Log.w(TAG, "Outgoing expiring message was sent but the timer wasn't started! Fixing.") + expireStartDate = record.dateReceived + } + } + Direction.INCOMING -> { + incoming = ChatItem.IncomingMessageDetails( + dateServerSent = record.dateServer.takeIf { it > 0 }, + dateReceived = record.dateReceived, + read = record.read, + sealedSender = record.sealedSender + ) + + if (expiresInMs != null && incoming?.read == true && expireStartDate == null) { + Log.w(TAG, "Incoming expiring message was read but the timer wasn't started! Fixing.") + expireStartDate = record.dateReceived + } } } } @@ -1285,10 +1309,14 @@ private class BackupMessageRecord( val viewOnce: Boolean ) -data class ExtraMessageData( +private data class ExtraMessageData( val mentionsById: Map>, val reactionsById: Map>, val attachmentsById: Map>, val groupReceiptsById: Map>, val isGroupThreadById: Map ) + +private enum class Direction { + OUTGOING, INCOMING, DIRECTIONLESS +}