Fetch isQuoted status in bulk during conversation load.

Improves overall time to load a page of messages by ~50%.
This commit is contained in:
Greyson Parrelli
2022-12-18 11:43:39 -05:00
parent c6f29fc950
commit a84a9c5381
3 changed files with 93 additions and 16 deletions

View File

@@ -93,10 +93,11 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
@Override
public @NonNull List<ConversationMessage> load(int start, int length, @NonNull CancellationSignal cancellationSignal) {
Stopwatch stopwatch = new Stopwatch("load(" + start + ", " + length + "), thread " + threadId);
MmsSmsTable db = SignalDatabase.mmsSms();
List<MessageRecord> records = new ArrayList<>(length);
Stopwatch stopwatch = new Stopwatch("load(" + start + ", " + length + "), thread " + threadId);
MmsSmsTable db = SignalDatabase.mmsSms();
List<MessageRecord> records = new ArrayList<>(length);
MentionHelper mentionHelper = new MentionHelper();
QuotedHelper quotedHelper = new QuotedHelper();
AttachmentHelper attachmentHelper = new AttachmentHelper();
ReactionHelper reactionHelper = new ReactionHelper();
PaymentHelper paymentHelper = new PaymentHelper();
@@ -107,6 +108,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
while ((record = reader.getNext()) != null && !cancellationSignal.isCanceled()) {
records.add(record);
mentionHelper.add(record);
quotedHelper.add(record);
reactionHelper.add(record);
attachmentHelper.add(record);
paymentHelper.add(record);
@@ -131,6 +133,9 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
mentionHelper.fetchMentions(context);
stopwatch.split("mentions");
quotedHelper.fetchQuotedState();
stopwatch.split("is-quoted");
reactionHelper.fetchReactions();
stopwatch.split("reactions");
@@ -155,7 +160,7 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
stopwatch.split("recipient-resolves");
List<ConversationMessage> messages = Stream.of(records)
.map(m -> ConversationMessageFactory.createWithUnresolvedData(context, m, mentionHelper.getMentions(m.getId())))
.map(m -> ConversationMessageFactory.createWithUnresolvedData(context, m, mentionHelper.getMentions(m.getId()), quotedHelper.isQuoted(m.getId())))
.toList();
stopwatch.split("conversion");
@@ -180,28 +185,27 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
try {
if (record != null) {
List<Mention> mentions = SignalDatabase.mentions().getMentionsForMessage(messageId.getId());
stopwatch.split("mentions");
boolean isQuoted = SignalDatabase.mmsSms().isQuoted(record);
stopwatch.split("is-quoted");
List<ReactionRecord> reactions = SignalDatabase.reactions().getReactions(messageId);
record = ReactionHelper.recordWithReactions(record, reactions);
stopwatch.split("reactions");
List<DatabaseAttachment> attachments = SignalDatabase.attachments().getAttachmentsForMessage(messageId.getId());
if (attachments.size() > 0) {
record = ((MediaMmsMessageRecord) record).withAttachments(context, attachments);
}
stopwatch.split("attachments");
if (record.isPaymentNotification()) {
record = SignalDatabase.payments().updateMessageWithPayment(record);
}
stopwatch.split("payments");
return ConversationMessage.ConversationMessageFactory.createWithUnresolvedData(ApplicationDependencies.getApplication(), record, mentions);
return ConversationMessage.ConversationMessageFactory.createWithUnresolvedData(ApplicationDependencies.getApplication(), record, mentions, isQuoted);
} else {
return null;
}
@@ -235,6 +239,24 @@ public class ConversationDataSource implements PagedDataSource<MessageId, Conver
}
}
private static class QuotedHelper {
private Collection<MessageRecord> records = new LinkedList<>();
private Set<Long> hasBeenQuotedIds = new HashSet<>();
void add(MessageRecord record) {
records.add(record);
}
void fetchQuotedState() {
hasBeenQuotedIds = SignalDatabase.mmsSms().isQuoted(records);
}
boolean isQuoted(long id) {
return hasBeenQuotedIds.contains(id);
}
}
private static class AttachmentHelper {
private Collection<Long> messageIds = new LinkedList<>();

View File

@@ -35,10 +35,6 @@ public class ConversationMessage {
@NonNull private final MessageStyler.Result styleResult;
private final boolean hasBeenQuoted;
private ConversationMessage(@NonNull MessageRecord messageRecord) {
this(messageRecord, null, null, false);
}
private ConversationMessage(@NonNull MessageRecord messageRecord, boolean hasBeenQuoted) {
this(messageRecord, null, null, hasBeenQuoted);
}
@@ -165,9 +161,7 @@ public class ConversationMessage {
* @param mentions List of placeholder mentions to be used to update the body in the provided MessageRecord.
*/
@WorkerThread
public static @NonNull ConversationMessage createWithUnresolvedData(@NonNull Context context, @NonNull MessageRecord messageRecord, @Nullable List<Mention> mentions) {
boolean hasBeenQuoted = SignalDatabase.mmsSms().isQuoted(messageRecord);
public static @NonNull ConversationMessage createWithUnresolvedData(@NonNull Context context, @NonNull MessageRecord messageRecord, @Nullable List<Mention> mentions, boolean hasBeenQuoted) {
if (messageRecord.isMms() && mentions != null && !mentions.isEmpty()) {
MentionUtil.UpdatedBodyAndMentions updated = MentionUtil.updateBodyAndMentionsWithDisplayNames(context, messageRecord, mentions);
return new ConversationMessage(messageRecord, updated.getBody(), updated.getMentions(), hasBeenQuoted);