Improve performance of processing read syncs.

fork-5.53.8
Greyson Parrelli 2021-12-21 14:47:53 -05:00
rodzic 282639469d
commit 46dd7f8a06
5 zmienionych plików z 91 dodań i 52 usunięć

Wyświetl plik

@ -121,7 +121,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
public abstract void markIncomingNotificationReceived(long threadId);
public abstract Set<ThreadUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType);
public abstract List<Pair<Long, Long>> setTimestampRead(SyncMessageId messageId, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead);
abstract @NonNull MmsSmsDatabase.TimestampReadResult setTimestampRead(SyncMessageId messageId, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead);
public abstract List<MarkedMessageInfo> setEntireThreadRead(long threadId);
public abstract List<MarkedMessageInfo> setMessagesReadSince(long threadId, long timestamp);
public abstract List<MarkedMessageInfo> setAllMessagesRead();

Wyświetl plik

@ -1000,14 +1000,15 @@ public class MmsDatabase extends MessageDatabase {
}
@Override
public List<Pair<Long, Long>> setTimestampRead(SyncMessageId messageId, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead) {
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
List<Pair<Long, Long>> expiring = new LinkedList<>();
Cursor cursor = null;
try {
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, MESSAGE_BOX, EXPIRES_IN, EXPIRE_STARTED, RECIPIENT_ID}, DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())}, null, null, null, null);
@NonNull MmsSmsDatabase.TimestampReadResult setTimestampRead(SyncMessageId messageId, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead) {
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
List<Pair<Long, Long>> expiring = new LinkedList<>();
String[] projection = new String[] { ID, THREAD_ID, MESSAGE_BOX, EXPIRES_IN, EXPIRE_STARTED, RECIPIENT_ID };
String query = DATE_SENT + " = ?";
String[] args = SqlUtil.buildArgs(messageId.getTimetamp());
List<Long> threads = new LinkedList<>();
try (Cursor cursor = database.query(TABLE_NAME, projection, query, args, null, null, null)) {
while (cursor.moveToNext()) {
RecipientId theirRecipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID)));
RecipientId ourRecipientId = messageId.getRecipientId();
@ -1030,22 +1031,17 @@ public class MmsDatabase extends MessageDatabase {
expiring.add(new Pair<>(id, expiresIn));
}
database.update(TABLE_NAME, values, ID_WHERE, new String[]{String.valueOf(id)});
database.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(id));
SignalDatabase.threads().updateReadState(threadId);
SignalDatabase.threads().setLastSeen(threadId);
notifyConversationListeners(threadId);
threads.add(threadId);
Long latest = threadToLatestRead.get(threadId);
threadToLatestRead.put(threadId, (latest != null) ? Math.max(latest, messageId.getTimetamp()) : messageId.getTimetamp());
}
}
} finally {
if (cursor != null)
cursor.close();
}
return expiring;
return new MmsSmsDatabase.TimestampReadResult(expiring, threads);
}
@Override

Wyświetl plik

@ -31,19 +31,23 @@ import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId;
import org.thoughtcrime.securesms.database.MessageDatabase.ThreadUpdate;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.notifications.v2.MessageNotifierV2;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.CursorUtil;
import org.thoughtcrime.securesms.util.SqlUtil;
import org.whispersystems.libsignal.util.Pair;
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@ -489,6 +493,56 @@ public class MmsSmsDatabase extends Database {
return threadUpdates;
}
public void setTimestampRead(@NonNull Recipient senderRecipient, @NonNull List<ReadMessage> readMessages, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead) {
SQLiteDatabase db = getWritableDatabase();
List<Pair<Long, Long>> expiringText = new LinkedList<>();
List<Pair<Long, Long>> expiringMedia = new LinkedList<>();
Set<Long> updatedThreads = new HashSet<>();
db.beginTransaction();
try {
for (ReadMessage readMessage : readMessages) {
TimestampReadResult textResult = SignalDatabase.sms().setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()),
proposedExpireStarted,
threadToLatestRead);
TimestampReadResult mediaResult = SignalDatabase.mms().setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()),
proposedExpireStarted,
threadToLatestRead);
expiringText.addAll(textResult.expiring);
expiringMedia.addAll(mediaResult.expiring);
updatedThreads.addAll(textResult.threads);
updatedThreads.addAll(mediaResult.threads);
}
for (long threadId : updatedThreads) {
SignalDatabase.threads().updateReadState(threadId);
SignalDatabase.threads().setLastSeen(threadId);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
for (Pair<Long, Long> expiringMessage : expiringText) {
ApplicationDependencies.getExpiringMessageManager()
.scheduleDeletion(expiringMessage.first(), false, proposedExpireStarted, expiringMessage.second());
}
for (Pair<Long, Long> expiringMessage : expiringMedia) {
ApplicationDependencies.getExpiringMessageManager()
.scheduleDeletion(expiringMessage.first(), true, proposedExpireStarted, expiringMessage.second());
}
for (long threadId : updatedThreads) {
notifyConversationListeners(threadId);
}
}
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) {
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
@ -862,4 +916,14 @@ public class MmsSmsDatabase extends Database {
cursor.close();
}
}
static final class TimestampReadResult {
final List<Pair<Long, Long>> expiring;
final List<Long> threads;
TimestampReadResult(@NonNull List<Pair<Long, Long>> expiring, @NonNull List<Long> threads) {
this.expiring = expiring;
this.threads = threads;
}
}
}

Wyświetl plik

@ -526,16 +526,15 @@ public class SmsDatabase extends MessageDatabase {
}
@Override
public List<Pair<Long, Long>> setTimestampRead(SyncMessageId messageId, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead) {
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
List<Pair<Long, Long>> expiring = new LinkedList<>();
Cursor cursor = null;
try {
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, RECIPIENT_ID, TYPE, EXPIRES_IN, EXPIRE_STARTED},
DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())},
null, null, null, null);
@NonNull MmsSmsDatabase.TimestampReadResult setTimestampRead(SyncMessageId messageId, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead) {
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
List<Pair<Long, Long>> expiring = new LinkedList<>();
String[] projection = new String[] {ID, THREAD_ID, RECIPIENT_ID, TYPE, EXPIRES_IN, EXPIRE_STARTED};
String query = DATE_SENT + " = ?";
String[] args = SqlUtil.buildArgs(messageId.getTimetamp());
List<Long> threads = new LinkedList<>();
try (Cursor cursor = database.query(TABLE_NAME, projection, query, args, null, null, null)) {
while (cursor.moveToNext()) {
RecipientId theirRecipientId = messageId.getRecipientId();
RecipientId outRecipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID)));
@ -558,21 +557,17 @@ public class SmsDatabase extends MessageDatabase {
expiring.add(new Pair<>(id, expiresIn));
}
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {cursor.getLong(cursor.getColumnIndexOrThrow(ID)) + ""});
database.update(TABLE_NAME, contentValues, ID_WHERE, SqlUtil.buildArgs(id));
SignalDatabase.threads().updateReadState(threadId);
SignalDatabase.threads().setLastSeen(threadId);
notifyConversationListeners(threadId);
threads.add(threadId);
Long latest = threadToLatestRead.get(threadId);
threadToLatestRead.put(threadId, (latest != null) ? Math.max(latest, messageId.getTimetamp()) : messageId.getTimetamp());
}
}
} finally {
if (cursor != null) cursor.close();
}
return expiring;
return new MmsSmsDatabase.TimestampReadResult(expiring, threads);
}
@Override

Wyświetl plik

@ -121,7 +121,6 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.protocol.DecryptionErrorMessage;
import org.whispersystems.libsignal.util.Pair;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
@ -1199,29 +1198,14 @@ public final class MessageContentProcessor {
private void handleSynchronizeReadMessage(@NonNull List<ReadMessage> readMessages, long envelopeTimestamp, @NonNull Recipient senderRecipient)
{
log(envelopeTimestamp, "Synchronize read message.");
log(envelopeTimestamp, "Synchronize read message. Count: " + readMessages.size());
Map<Long, Long> threadToLatestRead = new HashMap<>();
for (ReadMessage readMessage : readMessages) {
List<Pair<Long, Long>> expiringText = SignalDatabase.sms().setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()),
envelopeTimestamp,
threadToLatestRead);
List<Pair<Long, Long>> expiringMedia = SignalDatabase.mms().setTimestampRead(new SyncMessageId(senderRecipient.getId(), readMessage.getTimestamp()),
envelopeTimestamp,
threadToLatestRead);
for (Pair<Long, Long> expiringMessage : expiringText) {
ApplicationDependencies.getExpiringMessageManager()
.scheduleDeletion(expiringMessage.first(), false, envelopeTimestamp, expiringMessage.second());
}
for (Pair<Long, Long> expiringMessage : expiringMedia) {
ApplicationDependencies.getExpiringMessageManager()
.scheduleDeletion(expiringMessage.first(), true, envelopeTimestamp, expiringMessage.second());
}
}
SignalDatabase.mmsSms().setTimestampRead(senderRecipient, readMessages, envelopeTimestamp, threadToLatestRead);
List<MessageDatabase.MarkedMessageInfo> markedMessages = SignalDatabase.threads().setReadSince(threadToLatestRead, false);
if (Util.hasItems(markedMessages)) {
Log.i(TAG, "Updating past messages: " + markedMessages.size());
MarkReadReceiver.process(context, markedMessages);
@ -1234,7 +1218,7 @@ public final class MessageContentProcessor {
}
private void handleSynchronizeViewedMessage(@NonNull List<ViewedMessage> viewedMessages, long envelopeTimestamp) {
log(envelopeTimestamp, "Synchronize viewed message.");
log(envelopeTimestamp, "Synchronize viewed message. Count: " + viewedMessages.size());
List<Long> toMarkViewed = Stream.of(viewedMessages)
.map(message -> {