kopia lustrzana https://github.com/ryukoposting/Signal-Android
Improve performance of marking chats read.
SQLite isn't always smart enough to use the best index for a query. The main improvement here was to force it to use a better index than the one it was using (which, on my device, happened to by the story index, which was only minimally useful here).main
rodzic
a513e93d18
commit
59f05e0815
|
@ -994,16 +994,25 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||||
|
|
||||||
private void handleMarkAsRead(@NonNull Collection<Long> ids) {
|
private void handleMarkAsRead(@NonNull Collection<Long> ids) {
|
||||||
Context context = requireContext();
|
Context context = requireContext();
|
||||||
|
Stopwatch stopwatch = new Stopwatch("mark-read");
|
||||||
|
|
||||||
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
|
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
|
||||||
|
stopwatch.split("task-start");
|
||||||
|
|
||||||
List<MarkedMessageInfo> messageIds = SignalDatabase.threads().setRead(ids, false);
|
List<MarkedMessageInfo> messageIds = SignalDatabase.threads().setRead(ids, false);
|
||||||
|
stopwatch.split("db");
|
||||||
|
|
||||||
ApplicationDependencies.getMessageNotifier().updateNotification(context);
|
ApplicationDependencies.getMessageNotifier().updateNotification(context);
|
||||||
|
stopwatch.split("notification");
|
||||||
|
|
||||||
MarkReadReceiver.process(context, messageIds);
|
MarkReadReceiver.process(context, messageIds);
|
||||||
|
stopwatch.split("process");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, none -> {
|
}, none -> {
|
||||||
endActionModeIfActive();
|
endActionModeIfActive();
|
||||||
|
stopwatch.stop(TAG);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,12 +232,14 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
EXPORT_STATE + " BLOB DEFAULT NULL, " +
|
EXPORT_STATE + " BLOB DEFAULT NULL, " +
|
||||||
EXPORTED + " INTEGER DEFAULT 0);";
|
EXPORTED + " INTEGER DEFAULT 0);";
|
||||||
|
|
||||||
|
private static final String INDEX_THREAD_DATE = "mms_thread_date_index";
|
||||||
|
|
||||||
public static final String[] CREATE_INDEXS = {
|
public static final String[] CREATE_INDEXS = {
|
||||||
"CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");",
|
"CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS mms_type_index ON " + TABLE_NAME + " (" + TYPE + ");",
|
"CREATE INDEX IF NOT EXISTS mms_type_index ON " + TABLE_NAME + " (" + TYPE + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS mms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ", " + RECIPIENT_ID + ", " + THREAD_ID + ");",
|
"CREATE INDEX IF NOT EXISTS mms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ", " + RECIPIENT_ID + ", " + THREAD_ID + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS mms_date_server_index ON " + TABLE_NAME + " (" + DATE_SERVER + ");",
|
"CREATE INDEX IF NOT EXISTS mms_date_server_index ON " + TABLE_NAME + " (" + DATE_SERVER + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS mms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");",
|
"CREATE INDEX IF NOT EXISTS " + INDEX_THREAD_DATE + " ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS mms_reactions_unread_index ON " + TABLE_NAME + " (" + REACTIONS_UNREAD + ");",
|
"CREATE INDEX IF NOT EXISTS mms_reactions_unread_index ON " + TABLE_NAME + " (" + REACTIONS_UNREAD + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS mms_story_type_index ON " + TABLE_NAME + " (" + STORY_TYPE + ");",
|
"CREATE INDEX IF NOT EXISTS mms_story_type_index ON " + TABLE_NAME + " (" + STORY_TYPE + ");",
|
||||||
"CREATE INDEX IF NOT EXISTS mms_parent_story_id_index ON " + TABLE_NAME + " (" + PARENT_STORY_ID + ");",
|
"CREATE INDEX IF NOT EXISTS mms_parent_story_id_index ON " + TABLE_NAME + " (" + PARENT_STORY_ID + ");",
|
||||||
|
@ -2020,7 +2022,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
database.beginTransaction();
|
database.beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cursor = database.query(TABLE_NAME, new String[] { ID, RECIPIENT_ID, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID, STORY_TYPE }, where, arguments, null, null, null);
|
cursor = database.query(TABLE_NAME + " INDEXED BY " + INDEX_THREAD_DATE, new String[] { ID, RECIPIENT_ID, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID, STORY_TYPE }, where, arguments, null, null, null);
|
||||||
|
|
||||||
while(cursor != null && cursor.moveToNext()) {
|
while(cursor != null && cursor.moveToNext()) {
|
||||||
if (MessageTypes.isSecureType(CursorUtil.requireLong(cursor, TYPE))) {
|
if (MessageTypes.isSecureType(CursorUtil.requireLong(cursor, TYPE))) {
|
||||||
|
@ -2045,7 +2047,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
contentValues.put(REACTIONS_UNREAD, 0);
|
contentValues.put(REACTIONS_UNREAD, 0);
|
||||||
contentValues.put(REACTIONS_LAST_SEEN, System.currentTimeMillis());
|
contentValues.put(REACTIONS_LAST_SEEN, System.currentTimeMillis());
|
||||||
|
|
||||||
database.update(TABLE_NAME, contentValues, where, arguments);
|
database.update(TABLE_NAME + " INDEXED BY " + INDEX_THREAD_DATE, contentValues, where, arguments);
|
||||||
database.setTransactionSuccessful();
|
database.setTransactionSuccessful();
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) cursor.close();
|
if (cursor != null) cursor.close();
|
||||||
|
@ -3913,7 +3915,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
|
||||||
public int getUnreadCount(long threadId) {
|
public int getUnreadCount(long threadId) {
|
||||||
String selection = READ + " = 0 AND " + STORY_TYPE + " = 0 AND " + THREAD_ID + " = " + threadId + " AND " + PARENT_STORY_ID + " <= 0";
|
String selection = READ + " = 0 AND " + STORY_TYPE + " = 0 AND " + THREAD_ID + " = " + threadId + " AND " + PARENT_STORY_ID + " <= 0";
|
||||||
|
|
||||||
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, COUNT, selection, null, null, null, null)) {
|
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME + " INDEXED BY " + INDEX_THREAD_DATE, COUNT, selection, null, null, null, null)) {
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
return cursor.getInt(0);
|
return cursor.getInt(0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import androidx.annotation.NonNull;
|
||||||
import com.annimon.stream.Collectors;
|
import com.annimon.stream.Collectors;
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
|
import org.signal.core.util.Stopwatch;
|
||||||
import org.signal.core.util.concurrent.SignalExecutors;
|
import org.signal.core.util.concurrent.SignalExecutors;
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.database.MessageTable.ExpirationInfo;
|
import org.thoughtcrime.securesms.database.MessageTable.ExpirationInfo;
|
||||||
|
@ -75,18 +76,12 @@ public class MarkReadReceiver extends BroadcastReceiver {
|
||||||
List<SyncMessageId> syncMessageIds = Stream.of(markedReadMessages)
|
List<SyncMessageId> syncMessageIds = Stream.of(markedReadMessages)
|
||||||
.map(MarkedMessageInfo::getSyncMessageId)
|
.map(MarkedMessageInfo::getSyncMessageId)
|
||||||
.toList();
|
.toList();
|
||||||
List<ExpirationInfo> mmsExpirationInfo = Stream.of(markedReadMessages)
|
List<ExpirationInfo> expirationInfo = Stream.of(markedReadMessages)
|
||||||
.map(MarkedMessageInfo::getExpirationInfo)
|
.map(MarkedMessageInfo::getExpirationInfo)
|
||||||
.filter(ExpirationInfo::isMms)
|
|
||||||
.filter(info -> info.getExpiresIn() > 0 && info.getExpireStarted() <= 0)
|
|
||||||
.toList();
|
|
||||||
List<ExpirationInfo> smsExpirationInfo = Stream.of(markedReadMessages)
|
|
||||||
.map(MarkedMessageInfo::getExpirationInfo)
|
|
||||||
.filterNot(ExpirationInfo::isMms)
|
|
||||||
.filter(info -> info.getExpiresIn() > 0 && info.getExpireStarted() <= 0)
|
.filter(info -> info.getExpiresIn() > 0 && info.getExpireStarted() <= 0)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
scheduleDeletion(context, smsExpirationInfo, mmsExpirationInfo);
|
scheduleDeletion(expirationInfo);
|
||||||
|
|
||||||
MultiDeviceReadUpdateJob.enqueue(syncMessageIds);
|
MultiDeviceReadUpdateJob.enqueue(syncMessageIds);
|
||||||
|
|
||||||
|
@ -108,23 +103,13 @@ public class MarkReadReceiver extends BroadcastReceiver {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void scheduleDeletion(@NonNull Context context,
|
private static void scheduleDeletion(@NonNull List<ExpirationInfo> expirationInfo) {
|
||||||
@NonNull List<ExpirationInfo> smsExpirationInfo,
|
if (expirationInfo.size() > 0) {
|
||||||
@NonNull List<ExpirationInfo> mmsExpirationInfo)
|
SignalDatabase.messages().markExpireStarted(Stream.of(expirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis());
|
||||||
{
|
|
||||||
if (smsExpirationInfo.size() > 0) {
|
|
||||||
SignalDatabase.messages().markExpireStarted(Stream.of(smsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mmsExpirationInfo.size() > 0) {
|
|
||||||
SignalDatabase.messages().markExpireStarted(Stream.of(mmsExpirationInfo).map(ExpirationInfo::getId).toList(), System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smsExpirationInfo.size() + mmsExpirationInfo.size() > 0) {
|
|
||||||
ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager();
|
ExpiringMessageManager expirationManager = ApplicationDependencies.getExpiringMessageManager();
|
||||||
|
|
||||||
Stream.concat(Stream.of(smsExpirationInfo), Stream.of(mmsExpirationInfo))
|
expirationInfo.stream().forEach(info -> expirationManager.scheduleDeletion(info.getId(), info.isMms(), info.getExpiresIn()));
|
||||||
.forEach(info -> expirationManager.scheduleDeletion(info.getId(), info.isMms(), info.getExpiresIn()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue