Improve performance of finding message positions in chats.

This commit is contained in:
Greyson Parrelli 2023-04-18 09:35:37 -04:00 committed by Cody Henthorne
parent d628921e48
commit 6db71f4a39
2 changed files with 43 additions and 36 deletions

View file

@ -51,6 +51,7 @@ import org.signal.core.util.requireBlob
import org.signal.core.util.requireBoolean import org.signal.core.util.requireBoolean
import org.signal.core.util.requireInt import org.signal.core.util.requireInt
import org.signal.core.util.requireLong import org.signal.core.util.requireLong
import org.signal.core.util.requireLongOrNull
import org.signal.core.util.requireNonNullString import org.signal.core.util.requireNonNullString
import org.signal.core.util.requireString import org.signal.core.util.requireString
import org.signal.core.util.select import org.signal.core.util.select
@ -4009,52 +4010,53 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
} }
fun getQuotedMessagePosition(threadId: Long, quoteId: Long, authorId: RecipientId): Int { fun getQuotedMessagePosition(threadId: Long, quoteId: Long, authorId: RecipientId): Int {
var position = 0 val targetMessageDateReceived: Long = readableDatabase
readableDatabase .select(DATE_RECEIVED, LATEST_REVISION_ID)
.select(DATE_SENT, FROM_RECIPIENT_ID, REMOTE_DELETED, LATEST_REVISION_ID)
.from(TABLE_NAME) .from(TABLE_NAME)
.where("$THREAD_ID = $threadId AND $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1") .where("$DATE_SENT = $quoteId AND $FROM_RECIPIENT_ID = ? AND $REMOTE_DELETED = 0 AND $SCHEDULED_DATE = -1", authorId)
.orderBy("$DATE_RECEIVED DESC")
.run() .run()
.forEach { cursor -> .readToSingleObject { cursor ->
val quoteIdMatches = cursor.requireLong(DATE_SENT) == quoteId val latestRevisionId = cursor.requireLongOrNull(LATEST_REVISION_ID)
val recipientIdMatches = authorId == RecipientId.from(cursor.requireLong(FROM_RECIPIENT_ID)) if (latestRevisionId != null) {
readableDatabase
if (quoteIdMatches && recipientIdMatches) { .select(DATE_RECEIVED)
return if (cursor.requireBoolean(REMOTE_DELETED)) { .from(TABLE_NAME)
-1 .where("$ID = ?", latestRevisionId)
} else { .run()
position .readToSingleLong(-1L)
} } else {
} else if (cursor.requireLong(LATEST_REVISION_ID) == 0L) { cursor.requireLong(DATE_RECEIVED)
position++
} }
} } ?: -1L
return -1 if (targetMessageDateReceived == -1L) {
return -1
}
return readableDatabase
.select("COUNT(*)")
.from(TABLE_NAME)
.where("$THREAD_ID = $threadId AND $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND $LATEST_REVISION_ID IS NULL AND $DATE_RECEIVED > $targetMessageDateReceived")
.run()
.readToSingleInt()
} }
fun getMessagePositionInConversation(threadId: Long, receivedTimestamp: Long, authorId: RecipientId): Int { fun getMessagePositionInConversation(threadId: Long, receivedTimestamp: Long, authorId: RecipientId): Int {
readableDatabase val validMessageExists: Boolean = readableDatabase
.select(DATE_RECEIVED, FROM_RECIPIENT_ID, REMOTE_DELETED) .exists(TABLE_NAME)
.from(TABLE_NAME) .where("$DATE_RECEIVED = $receivedTimestamp AND $FROM_RECIPIENT_ID = ? AND $REMOTE_DELETED = 0 AND $SCHEDULED_DATE = -1 AND $LATEST_REVISION_ID IS NULL", authorId)
.where("$THREAD_ID = $threadId AND $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND $LATEST_REVISION_ID IS NULL")
.orderBy("$DATE_RECEIVED DESC")
.run() .run()
.forEach { cursor ->
val timestampMatches = cursor.requireLong(DATE_RECEIVED) == receivedTimestamp
val authorIdMatches = authorId == RecipientId.from(cursor.requireLong(FROM_RECIPIENT_ID))
if (timestampMatches && authorIdMatches) { if (!validMessageExists) {
return if (cursor.requireBoolean(REMOTE_DELETED)) { return -1
-1 }
} else {
cursor.position
}
}
}
return -1 return readableDatabase
.select("COUNT(*)")
.from(TABLE_NAME)
.where("$THREAD_ID = $threadId AND $STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND $SCHEDULED_DATE = -1 AND $LATEST_REVISION_ID IS NULL AND $DATE_RECEIVED > $receivedTimestamp")
.run()
.readToSingleInt(-1)
} }
fun getMessagePositionInConversation(threadId: Long, receivedTimestamp: Long): Int { fun getMessagePositionInConversation(threadId: Long, receivedTimestamp: Long): Int {

View file

@ -1,6 +1,7 @@
package org.signal.core.util package org.signal.core.util
import android.database.Cursor import android.database.Cursor
import androidx.core.database.getLongOrNull
import java.util.Optional import java.util.Optional
fun Cursor.requireString(column: String): String? { fun Cursor.requireString(column: String): String? {
@ -31,6 +32,10 @@ fun Cursor.requireLong(column: String): Long {
return CursorUtil.requireLong(this, column) return CursorUtil.requireLong(this, column)
} }
fun Cursor.requireLongOrNull(column: String): Long? {
return this.getLongOrNull(this.getColumnIndexOrThrow(column))
}
fun Cursor.optionalLong(column: String): Optional<Long> { fun Cursor.optionalLong(column: String): Optional<Long> {
return CursorUtil.getLong(this, column) return CursorUtil.getLong(this, column)
} }