mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 12:38:33 +00:00
Add read through cache for thread id.
This commit is contained in:
@@ -17,7 +17,6 @@ import org.signal.core.util.exists
|
|||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.signal.core.util.or
|
import org.signal.core.util.or
|
||||||
import org.signal.core.util.readToList
|
import org.signal.core.util.readToList
|
||||||
import org.signal.core.util.readToSingleLong
|
|
||||||
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
|
||||||
@@ -60,6 +59,7 @@ import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
|||||||
import org.thoughtcrime.securesms.util.ConversationUtil
|
import org.thoughtcrime.securesms.util.ConversationUtil
|
||||||
import org.thoughtcrime.securesms.util.JsonUtils
|
import org.thoughtcrime.securesms.util.JsonUtils
|
||||||
import org.thoughtcrime.securesms.util.JsonUtils.SaneJSONObject
|
import org.thoughtcrime.securesms.util.JsonUtils.SaneJSONObject
|
||||||
|
import org.thoughtcrime.securesms.util.LRUCache
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.thoughtcrime.securesms.util.isScheduled
|
import org.thoughtcrime.securesms.util.isScheduled
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId
|
import org.whispersystems.signalservice.api.push.ServiceId
|
||||||
@@ -107,6 +107,8 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
const val PINNED = "pinned"
|
const val PINNED = "pinned"
|
||||||
const val UNREAD_SELF_MENTION_COUNT = "unread_self_mention_count"
|
const val UNREAD_SELF_MENTION_COUNT = "unread_self_mention_count"
|
||||||
|
|
||||||
|
const val MAX_CACHE_SIZE = 1000
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val CREATE_TABLE = """
|
val CREATE_TABLE = """
|
||||||
CREATE TABLE $TABLE_NAME (
|
CREATE TABLE $TABLE_NAME (
|
||||||
@@ -179,6 +181,8 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
const val NO_TRIM_MESSAGE_COUNT_SET = Int.MAX_VALUE
|
const val NO_TRIM_MESSAGE_COUNT_SET = Int.MAX_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val threadIdCache = LRUCache<RecipientId, Long>(MAX_CACHE_SIZE)
|
||||||
|
|
||||||
private fun createThreadForRecipient(recipientId: RecipientId, group: Boolean, distributionType: Int): Long {
|
private fun createThreadForRecipient(recipientId: RecipientId, group: Boolean, distributionType: Int): Long {
|
||||||
if (recipientId.isUnknown) {
|
if (recipientId.isUnknown) {
|
||||||
throw AssertionError("Cannot create a thread for an unknown recipient!")
|
throw AssertionError("Cannot create a thread for an unknown recipient!")
|
||||||
@@ -1057,6 +1061,9 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
db.delete(TABLE_NAME)
|
db.delete(TABLE_NAME)
|
||||||
.where("$ID = ?", threadId)
|
.where("$ID = ?", threadId)
|
||||||
.run()
|
.run()
|
||||||
|
synchronized(threadIdCache) {
|
||||||
|
threadIdCache.remove(recipientIdForThreadId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyConversationListListeners()
|
notifyConversationListListeners()
|
||||||
@@ -1080,6 +1087,11 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
mentions.deleteAbandonedMentions()
|
mentions.deleteAbandonedMentions()
|
||||||
drafts.clearDrafts(selectedConversations)
|
drafts.clearDrafts(selectedConversations)
|
||||||
attachments.deleteAbandonedAttachmentFiles()
|
attachments.deleteAbandonedAttachmentFiles()
|
||||||
|
synchronized(threadIdCache) {
|
||||||
|
for (recipientId in recipientIds) {
|
||||||
|
threadIdCache.remove(recipientId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyConversationListListeners()
|
notifyConversationListListeners()
|
||||||
@@ -1096,6 +1108,9 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
drafts.clearAllDrafts()
|
drafts.clearAllDrafts()
|
||||||
db.delete(TABLE_NAME, null, null)
|
db.delete(TABLE_NAME, null, null)
|
||||||
calls.deleteAllCalls()
|
calls.deleteAllCalls()
|
||||||
|
synchronized(threadIdCache) {
|
||||||
|
threadIdCache.clear()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyConversationListListeners()
|
notifyConversationListListeners()
|
||||||
@@ -1103,12 +1118,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getThreadIdIfExistsFor(recipientId: RecipientId): Long {
|
fun getThreadIdIfExistsFor(recipientId: RecipientId): Long {
|
||||||
return readableDatabase
|
return getThreadIdFor(recipientId) ?: -1
|
||||||
.select(ID)
|
|
||||||
.from(TABLE_NAME)
|
|
||||||
.where("$RECIPIENT_ID = ?", recipientId)
|
|
||||||
.run()
|
|
||||||
.readToSingleLong(-1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getOrCreateValidThreadId(recipient: Recipient, candidateId: Long): Long {
|
fun getOrCreateValidThreadId(recipient: Recipient, candidateId: Long): Long {
|
||||||
@@ -1150,18 +1160,29 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getThreadIdFor(recipientId: RecipientId): Long? {
|
fun getThreadIdFor(recipientId: RecipientId): Long? {
|
||||||
return readableDatabase
|
var threadId: Long? = synchronized(threadIdCache) {
|
||||||
.select(ID)
|
threadIdCache[recipientId]
|
||||||
.from(TABLE_NAME)
|
}
|
||||||
.where("$RECIPIENT_ID = ?", recipientId)
|
if (threadId == null) {
|
||||||
.run()
|
threadId = readableDatabase
|
||||||
.use { cursor ->
|
.select(ID)
|
||||||
if (cursor.moveToFirst()) {
|
.from(TABLE_NAME)
|
||||||
cursor.requireLong(ID)
|
.where("$RECIPIENT_ID = ?", recipientId)
|
||||||
} else {
|
.run()
|
||||||
null
|
.use { cursor ->
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
cursor.requireLong(ID)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (threadId != null) {
|
||||||
|
synchronized(threadIdCache) {
|
||||||
|
threadIdCache[recipientId] = threadId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return threadId
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRecipientIdForThreadId(threadId: Long): RecipientId? {
|
fun getRecipientIdForThreadId(threadId: Long): RecipientId? {
|
||||||
@@ -1500,6 +1521,9 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
.values(RECIPIENT_ID to primaryRecipientId.serialize())
|
.values(RECIPIENT_ID to primaryRecipientId.serialize())
|
||||||
.where("$ID = ?", secondary.threadId)
|
.where("$ID = ?", secondary.threadId)
|
||||||
.run()
|
.run()
|
||||||
|
synchronized(threadIdCache) {
|
||||||
|
threadIdCache.remove(secondaryRecipientId)
|
||||||
|
}
|
||||||
MergeResult(threadId = secondary.threadId, previousThreadId = -1, neededMerge = false)
|
MergeResult(threadId = secondary.threadId, previousThreadId = -1, neededMerge = false)
|
||||||
} else if (primary == null && secondary == null) {
|
} else if (primary == null && secondary == null) {
|
||||||
Log.w(TAG, "[merge] No thread for either.")
|
Log.w(TAG, "[merge] No thread for either.")
|
||||||
@@ -1518,6 +1542,10 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
|||||||
.where("$ID = ?", secondary.threadId)
|
.where("$ID = ?", secondary.threadId)
|
||||||
.run()
|
.run()
|
||||||
|
|
||||||
|
synchronized(threadIdCache) {
|
||||||
|
threadIdCache.remove(secondaryRecipientId)
|
||||||
|
}
|
||||||
|
|
||||||
if (primary.expiresIn != secondary.expiresIn) {
|
if (primary.expiresIn != secondary.expiresIn) {
|
||||||
val values = ContentValues()
|
val values = ContentValues()
|
||||||
if (primary.expiresIn == 0L) {
|
if (primary.expiresIn == 0L) {
|
||||||
|
|||||||
Reference in New Issue
Block a user