mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-26 20:55:10 +00:00
Reduce transactions during getAndPossiblyMerge.
This commit is contained in:
@@ -446,6 +446,14 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
fun getAndPossiblyMerge(aci: ACI?, pni: PNI?, e164: String?, pniVerified: Boolean = false, changeSelf: Boolean = false): RecipientId {
|
||||
require(aci != null || pni != null || e164 != null) { "Must provide an ACI, PNI, or E164!" }
|
||||
|
||||
// To avoid opening a transaction and doing extra reads, we start with a single read that checks if all of the fields already match a single recipient
|
||||
val singleMatch: RecipientId? = getRecipientIdIfAllFieldsMatch(aci, pni, e164)
|
||||
if (singleMatch != null) {
|
||||
return singleMatch
|
||||
}
|
||||
|
||||
Log.d(TAG, "[getAndPossiblyMerge] Requires a transaction.")
|
||||
|
||||
val db = writableDatabase
|
||||
var transactionSuccessful = false
|
||||
lateinit var result: ProcessPnpTupleResult
|
||||
@@ -2618,6 +2626,40 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* If all of the non-null fields match a single recipient, return it. Otherwise null.
|
||||
*/
|
||||
private fun getRecipientIdIfAllFieldsMatch(aci: ACI?, pni: PNI?, e164: String?): RecipientId? {
|
||||
if (aci == null && pni == null && e164 == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val columns = listOf(
|
||||
ACI_COLUMN to aci?.toString(),
|
||||
PNI_COLUMN to pni?.toString(),
|
||||
E164 to e164
|
||||
).filter { it.second != null }
|
||||
|
||||
val query = columns
|
||||
.map { "${it.first} = ?" }
|
||||
.joinToString(separator = " AND ")
|
||||
|
||||
val args: Array<String> = columns.map { it.second!! }.toTypedArray()
|
||||
|
||||
val ids: List<Long> = readableDatabase
|
||||
.select(ID)
|
||||
.from(TABLE_NAME)
|
||||
.where(query, args)
|
||||
.run()
|
||||
.readToList { it.requireLong(ID) }
|
||||
|
||||
return if (ids.size == 1) {
|
||||
RecipientId.from(ids[0])
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A session switchover event indicates a situation where we start communicating with a different session that we were before.
|
||||
* If a switchover is "verified" (i.e. proven safe cryptographically by the sender), then this doesn't require a user-visible event.
|
||||
|
||||
Reference in New Issue
Block a user