From 0b53ba89505b4f369bdfb73232244bf11aa653d9 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Sep 2021 11:35:13 -0400 Subject: [PATCH] Improve MMS database insertion performance. --- .../database/GroupReceiptDatabase.java | 27 +++++++-------- .../securesms/database/MmsDatabase.java | 33 ++++++++++++------- .../securesms/database/ThreadDatabase.java | 9 +++++ 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java index dee701df1..84179954c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java @@ -12,9 +12,11 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.SqlUtil; import org.whispersystems.libsignal.util.Pair; +import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -49,20 +51,19 @@ public class GroupReceiptDatabase extends Database { public void insert(Collection recipientIds, long mmsId, int status, long timestamp) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - db.beginTransaction(); - try { - for (RecipientId recipientId : recipientIds) { - ContentValues values = new ContentValues(4); - values.put(MMS_ID, mmsId); - values.put(RECIPIENT_ID, recipientId.serialize()); - values.put(STATUS, status); - values.put(TIMESTAMP, timestamp); + List contentValues = new ArrayList<>(recipientIds.size()); + for (RecipientId recipientId : recipientIds) { + ContentValues values = new ContentValues(4); + values.put(MMS_ID, mmsId); + values.put(RECIPIENT_ID, recipientId.serialize()); + values.put(STATUS, status); + values.put(TIMESTAMP, timestamp); + contentValues.add(values); + } - db.insert(TABLE_NAME, null, values); - } - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); + List statements = SqlUtil.buildBulkInsert(TABLE_NAME, new String[] { MMS_ID, RECIPIENT_ID, STATUS, TIMESTAMP }, contentValues); + for (SqlUtil.Query statement : statements) { + db.execSQL(statement.getWhere(), statement.getWhereArgs()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index 0f3e9e296..f085d2d70 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -750,12 +750,19 @@ public class MmsDatabase extends MessageDatabase { private void updateMailboxBitmask(long id, long maskOff, long maskOn, Optional threadId) { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - db.execSQL("UPDATE " + TABLE_NAME + - " SET " + MESSAGE_BOX + " = (" + MESSAGE_BOX + " & " + (Types.TOTAL_MASK - maskOff) + " | " + maskOn + " )" + - " WHERE " + ID + " = ?", new String[] {id + ""}); - if (threadId.isPresent()) { - DatabaseFactory.getThreadDatabase(context).updateSnippetTypeSilently(threadId.get()); + db.beginTransaction(); + try { + db.execSQL("UPDATE " + TABLE_NAME + + " SET " + MESSAGE_BOX + " = (" + MESSAGE_BOX + " & " + (Types.TOTAL_MASK - maskOff) + " | " + maskOn + " )" + + " WHERE " + ID + " = ?", new String[] { id + "" }); + + if (threadId.isPresent()) { + DatabaseFactory.getThreadDatabase(context).updateSnippetTypeSilently(threadId.get()); + } + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); } } @@ -1344,7 +1351,7 @@ public class MmsDatabase extends MessageDatabase { return Optional.absent(); } - long messageId = insertMediaMessage(threadId, retrieved.getBody(), retrieved.getAttachments(), quoteAttachments, retrieved.getSharedContacts(), retrieved.getLinkPreviews(), retrieved.getMentions(), contentValues, null); + long messageId = insertMediaMessage(threadId, retrieved.getBody(), retrieved.getAttachments(), quoteAttachments, retrieved.getSharedContacts(), retrieved.getLinkPreviews(), retrieved.getMentions(), contentValues, null, true); if (!Types.isExpirationTimerUpdate(mailbox)) { DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1); @@ -1530,7 +1537,7 @@ public class MmsDatabase extends MessageDatabase { MentionUtil.UpdatedBodyAndMentions updatedBodyAndMentions = MentionUtil.updateBodyAndMentionsWithPlaceholders(message.getBody(), message.getMentions()); - long messageId = insertMediaMessage(threadId, updatedBodyAndMentions.getBodyAsString(), message.getAttachments(), quoteAttachments, message.getSharedContacts(), message.getLinkPreviews(), updatedBodyAndMentions.getMentions(), contentValues, insertListener); + long messageId = insertMediaMessage(threadId, updatedBodyAndMentions.getBodyAsString(), message.getAttachments(), quoteAttachments, message.getSharedContacts(), message.getLinkPreviews(), updatedBodyAndMentions.getMentions(), contentValues, insertListener, false); if (message.getRecipient().isGroup()) { OutgoingGroupUpdateMessage outgoingGroupUpdateMessage = (message instanceof OutgoingGroupUpdateMessage) ? (OutgoingGroupUpdateMessage) message : null; @@ -1556,8 +1563,7 @@ public class MmsDatabase extends MessageDatabase { } } - DatabaseFactory.getThreadDatabase(context).setLastSeenSilently(threadId); - DatabaseFactory.getThreadDatabase(context).setHasSentSilently(threadId, true); + DatabaseFactory.getThreadDatabase(context).updateLastSeenAndMarkSentAndLastScrolledSilenty(threadId); ApplicationDependencies.getDatabaseObserver().notifyMessageInsertObservers(threadId, new MessageId(messageId, true)); notifyConversationListListeners(); @@ -1585,7 +1591,8 @@ public class MmsDatabase extends MessageDatabase { @NonNull List linkPreviews, @NonNull List mentions, @NonNull ContentValues contentValues, - @Nullable SmsDatabase.InsertListener insertListener) + @Nullable SmsDatabase.InsertListener insertListener, + boolean updateThread) throws MmsException { SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); @@ -1651,8 +1658,10 @@ public class MmsDatabase extends MessageDatabase { long contentValuesThreadId = contentValues.getAsLong(THREAD_ID); - DatabaseFactory.getThreadDatabase(context).setLastScrolled(contentValuesThreadId, 0); - ThreadUpdateJob.enqueue(contentValuesThreadId); + if (updateThread) { + DatabaseFactory.getThreadDatabase(context).setLastScrolled(contentValuesThreadId, 0); + ThreadUpdateJob.enqueue(contentValuesThreadId); + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index f2ae5bcac..d4edd296b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -1110,6 +1110,15 @@ public class ThreadDatabase extends Database { return getThreadIdIfExistsFor(recipientId) > -1; } + public void updateLastSeenAndMarkSentAndLastScrolledSilenty(long threadId) { + ContentValues contentValues = new ContentValues(3); + contentValues.put(LAST_SEEN, System.currentTimeMillis()); + contentValues.put(HAS_SENT, 1); + contentValues.put(LAST_SCROLLED, 0); + + databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contentValues, ID_WHERE, SqlUtil.buildArgs(threadId)); + } + public void setHasSentSilently(long threadId, boolean hasSent) { ContentValues contentValues = new ContentValues(1); contentValues.put(HAS_SENT, hasSent ? 1 : 0);