Fix backup perf issue by doing cleanup inline.

This commit is contained in:
Greyson Parrelli
2024-12-04 15:51:33 -05:00
parent e47861796e
commit 6d415ca85a
2 changed files with 52 additions and 33 deletions

View File

@@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.backup.v2.exporters.ChatItemArchiveExporter
import org.thoughtcrime.securesms.backup.v2.importer.ChatItemArchiveImporter import org.thoughtcrime.securesms.backup.v2.importer.ChatItemArchiveImporter
import org.thoughtcrime.securesms.database.GroupTable import org.thoughtcrime.securesms.database.GroupTable
import org.thoughtcrime.securesms.database.MessageTable import org.thoughtcrime.securesms.database.MessageTable
import org.thoughtcrime.securesms.database.MessageTypes
import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.recipients.RecipientId 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. // 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. // This cleans it up. Reminder, this is only a snapshot of the data.
val cleanupStartTime = System.currentTimeMillis()
db.rawWritableDatabase.execSQL( db.rawWritableDatabase.execSQL(
""" """
UPDATE ${MessageTable.TABLE_NAME} UPDATE ${MessageTable.TABLE_NAME}
@@ -78,16 +78,7 @@ fun MessageTable.getMessagesForBackup(db: SignalDatabase, backupTime: Long, medi
) )
""" """
) )
Log.d(TAG, "Cleanup took ${System.currentTimeMillis() - cleanupStartTime} ms")
// 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(",")})
"""
)
return ChatItemArchiveExporter( return ChatItemArchiveExporter(
db = db, db = db,

View File

@@ -390,17 +390,39 @@ private fun simpleUpdate(type: SimpleChatUpdate.Type): ChatUpdateMessage {
private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: RecipientId, isGroupThread: Boolean, groupReceipts: List<GroupReceiptTable.GroupReceiptInfo>?, exportState: ExportState, backupStartTime: Long): ChatItem.Builder? { private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: RecipientId, isGroupThread: Boolean, groupReceipts: List<GroupReceiptTable.GroupReceiptInfo>?, exportState: ExportState, backupStartTime: Long): ChatItem.Builder? {
val record = this 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 { val builder = ChatItem.Builder().apply {
chatId = record.threadId chatId = record.threadId
authorId = record.fromRecipientId authorId = fromRecipientId
dateSent = record.dateSent dateSent = record.dateSent
expireStartDate = record.expireStarted.takeIf { it > 0 } expireStartDate = record.expireStarted.takeIf { it > 0 }
expiresInMs = record.expiresIn.takeIf { it > 0 } expiresInMs = record.expiresIn.takeIf { it > 0 }
revisions = emptyList() revisions = emptyList()
sms = record.type.isSmsType() sms = record.type.isSmsType()
if (record.type.isDirectionlessType() || record.messageExtras?.gv2UpdateDescription != null) { when (direction) {
Direction.DIRECTIONLESS -> {
directionless = ChatItem.DirectionlessMessageDetails() directionless = ChatItem.DirectionlessMessageDetails()
} else if (MessageTypes.isOutgoingMessageType(record.type) || record.fromRecipientId == selfRecipientId.toLong()) { }
Direction.OUTGOING -> {
outgoing = ChatItem.OutgoingMessageDetails( outgoing = ChatItem.OutgoingMessageDetails(
sendStatus = record.toRemoteSendStatus(isGroupThread, groupReceipts, exportState) sendStatus = record.toRemoteSendStatus(isGroupThread, groupReceipts, exportState)
) )
@@ -409,7 +431,8 @@ private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: Recipien
Log.w(TAG, "Outgoing expiring message was sent but the timer wasn't started! Fixing.") Log.w(TAG, "Outgoing expiring message was sent but the timer wasn't started! Fixing.")
expireStartDate = record.dateReceived expireStartDate = record.dateReceived
} }
} else { }
Direction.INCOMING -> {
incoming = ChatItem.IncomingMessageDetails( incoming = ChatItem.IncomingMessageDetails(
dateServerSent = record.dateServer.takeIf { it > 0 }, dateServerSent = record.dateServer.takeIf { it > 0 },
dateReceived = record.dateReceived, dateReceived = record.dateReceived,
@@ -423,6 +446,7 @@ private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: Recipien
} }
} }
} }
}
if (!MessageTypes.isExpirationTimerUpdate(record.type) && builder.expiresInMs != null && builder.expireStartDate != null && builder.expireStartDate!! + builder.expiresInMs!! < backupStartTime + 1.days.inWholeMilliseconds) { if (!MessageTypes.isExpirationTimerUpdate(record.type) && builder.expiresInMs != null && builder.expireStartDate != null && builder.expireStartDate!! + builder.expiresInMs!! < backupStartTime + 1.days.inWholeMilliseconds) {
Log.w(TAG, "Message expires too soon! Must skip.") Log.w(TAG, "Message expires too soon! Must skip.")
@@ -1285,10 +1309,14 @@ private class BackupMessageRecord(
val viewOnce: Boolean val viewOnce: Boolean
) )
data class ExtraMessageData( private data class ExtraMessageData(
val mentionsById: Map<Long, List<Mention>>, val mentionsById: Map<Long, List<Mention>>,
val reactionsById: Map<Long, List<ReactionRecord>>, val reactionsById: Map<Long, List<ReactionRecord>>,
val attachmentsById: Map<Long, List<DatabaseAttachment>>, val attachmentsById: Map<Long, List<DatabaseAttachment>>,
val groupReceiptsById: Map<Long, List<GroupReceiptTable.GroupReceiptInfo>>, val groupReceiptsById: Map<Long, List<GroupReceiptTable.GroupReceiptInfo>>,
val isGroupThreadById: Map<Long, Boolean> val isGroupThreadById: Map<Long, Boolean>
) )
private enum class Direction {
OUTGOING, INCOMING, DIRECTIONLESS
}