Properly calculate backup size when optimize media is enabled.

This commit is contained in:
Cody Henthorne
2025-12-12 14:17:17 -05:00
committed by GitHub
parent b1eba86445
commit c67267b589
3 changed files with 34 additions and 27 deletions

View File

@@ -715,12 +715,6 @@ class AttachmentTable(
.readToSingleLong() .readToSingleLong()
} }
private fun getMessageDoesNotExpireWithinTimeoutClause(tablePrefix: String = MessageTable.TABLE_NAME): String {
val messageHasExpiration = "$tablePrefix.${MessageTable.EXPIRES_IN} > 0"
val messageExpiresInOneDayAfterViewing = "$messageHasExpiration AND $tablePrefix.${MessageTable.EXPIRES_IN} < ${1.days.inWholeMilliseconds}"
return "NOT ($messageExpiresInOneDayAfterViewing)"
}
/** /**
* Finds all of the attachmentIds of attachments that need to be uploaded to the archive cdn. * Finds all of the attachmentIds of attachments that need to be uploaded to the archive cdn.
*/ */
@@ -867,7 +861,7 @@ class AttachmentTable(
.exists("$TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}") .exists("$TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}")
.where( .where(
""" """
${buildAttachmentsThatNeedUploadQuery("$ARCHIVE_THUMBNAIL_TRANSFER_STATE IN (${ArchiveTransferState.NONE.value}, ${ArchiveTransferState.TEMPORARY_FAILURE.value})")} AND ${buildAttachmentsThatCanArchiveQuery("$ARCHIVE_THUMBNAIL_TRANSFER_STATE IN (${ArchiveTransferState.NONE.value}, ${ArchiveTransferState.TEMPORARY_FAILURE.value})")} AND
$QUOTE = 0 AND $QUOTE = 0 AND
$STICKER_ID = -1 AND $STICKER_ID = -1 AND
($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND ($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND
@@ -887,7 +881,7 @@ class AttachmentTable(
.from("$TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}") .from("$TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}")
.where( .where(
""" """
${buildAttachmentsThatNeedUploadQuery("$ARCHIVE_THUMBNAIL_TRANSFER_STATE IN (${ArchiveTransferState.NONE.value}, ${ArchiveTransferState.TEMPORARY_FAILURE.value})")} AND ${buildAttachmentsThatCanArchiveQuery("$ARCHIVE_THUMBNAIL_TRANSFER_STATE IN (${ArchiveTransferState.NONE.value}, ${ArchiveTransferState.TEMPORARY_FAILURE.value})")} AND
$QUOTE = 0 AND $QUOTE = 0 AND
$STICKER_ID = -1 AND $STICKER_ID = -1 AND
($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND ($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND
@@ -1181,7 +1175,7 @@ class AttachmentTable(
FROM ( FROM (
SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY, $DATA_SIZE SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY, $DATA_SIZE
FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID} FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE ${buildAttachmentsThatNeedUploadQuery(archiveTransferStateFilter)} WHERE ${buildAttachmentsThatCanArchiveQuery(archiveTransferStateFilter)}
) )
""".trimIndent() """.trimIndent()
) )
@@ -3110,7 +3104,7 @@ class AttachmentTable(
SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY
FROM $TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID} FROM $TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE WHERE
${buildAttachmentsThatNeedUploadQuery("$ARCHIVE_THUMBNAIL_TRANSFER_STATE != ${ArchiveTransferState.PERMANENT_FAILURE.value}")} AND ${buildAttachmentsThatCanArchiveQuery(archiveTransferStateFilter = "$ARCHIVE_THUMBNAIL_TRANSFER_STATE != ${ArchiveTransferState.PERMANENT_FAILURE.value}", includeOptimized = true)} AND
($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND ($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND
$CONTENT_TYPE != 'image/svg+xml' AND $CONTENT_TYPE != 'image/svg+xml' AND
$MESSAGE_ID != $WALLPAPER_MESSAGE_ID $MESSAGE_ID != $WALLPAPER_MESSAGE_ID
@@ -3129,15 +3123,10 @@ class AttachmentTable(
SELECT $DATA_SIZE SELECT $DATA_SIZE
FROM ( FROM (
SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY, $DATA_SIZE SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY, $DATA_SIZE
FROM $TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} AS m ON $TABLE_NAME.$MESSAGE_ID = m.${MessageTable.ID} FROM $TABLE_NAME INNER JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE WHERE
$DATA_FILE NOT NULL AND ${buildAttachmentsThatCanArchiveQuery(archiveTransferStateFilter = "$ARCHIVE_TRANSFER_STATE != ${ArchiveTransferState.PERMANENT_FAILURE.value}", includeOptimized = true)}
$DATA_HASH_END NOT NULL AND ${if (afterTimestamp > 0) "AND ${MessageTable.TABLE_NAME}.${MessageTable.DATE_RECEIVED} >= $afterTimestamp" else ""}
$REMOTE_KEY NOT NULL AND
$TRANSFER_STATE = $TRANSFER_PROGRESS_DONE AND
$ARCHIVE_TRANSFER_STATE != ${ArchiveTransferState.PERMANENT_FAILURE.value} AND
${if (afterTimestamp > 0) "m.${MessageTable.DATE_RECEIVED} >= $afterTimestamp AND" else ""}
${getMessageDoesNotExpireWithinTimeoutClause(tablePrefix = "m")}
) )
""" """
) )
@@ -3167,17 +3156,36 @@ class AttachmentTable(
} }
} }
private fun buildAttachmentsThatNeedUploadQuery(transferStateFilter: String = "$ARCHIVE_TRANSFER_STATE IN (${ArchiveTransferState.NONE.value}, ${ArchiveTransferState.TEMPORARY_FAILURE.value})"): String { private fun buildAttachmentsThatNeedUploadQuery(): String {
return buildAttachmentsThatCanArchiveQuery(
archiveTransferStateFilter = "$ARCHIVE_TRANSFER_STATE IN (${ArchiveTransferState.NONE.value}, ${ArchiveTransferState.TEMPORARY_FAILURE.value})",
includeOptimized = false
)
}
private fun buildAttachmentsThatCanArchiveQuery(archiveTransferStateFilter: String, includeOptimized: Boolean = false): String {
val notReleaseChannelClause = SignalStore.releaseChannel.releaseChannelRecipientId?.let { val notReleaseChannelClause = SignalStore.releaseChannel.releaseChannelRecipientId?.let {
"(${MessageTable.TABLE_NAME}.${MessageTable.FROM_RECIPIENT_ID} != ${it.toLong()}) AND" "(${MessageTable.TABLE_NAME}.${MessageTable.FROM_RECIPIENT_ID} != ${it.toLong()}) AND"
} ?: "" } ?: ""
val dataFileClause = if (includeOptimized) {
"($DATA_FILE NOT NULL OR $TRANSFER_STATE = $TRANSFER_RESTORE_OFFLOADED)"
} else {
"$DATA_FILE NOT NULL"
}
val transferStateClause = if (includeOptimized) {
"($TRANSFER_STATE = $TRANSFER_PROGRESS_DONE OR $TRANSFER_STATE = $TRANSFER_RESTORE_OFFLOADED)"
} else {
"$TRANSFER_STATE = $TRANSFER_PROGRESS_DONE"
}
return """ return """
$transferStateFilter AND $archiveTransferStateFilter AND
$DATA_FILE NOT NULL AND $dataFileClause AND
$REMOTE_KEY NOT NULL AND $REMOTE_KEY NOT NULL AND
$DATA_HASH_END NOT NULL AND $DATA_HASH_END NOT NULL AND
$TRANSFER_STATE = $TRANSFER_PROGRESS_DONE AND $transferStateClause AND
(${MessageTable.STORY_TYPE} = 0 OR ${MessageTable.STORY_TYPE} IS NULL) AND (${MessageTable.STORY_TYPE} = 0 OR ${MessageTable.STORY_TYPE} IS NULL) AND
(${MessageTable.TABLE_NAME}.${MessageTable.EXPIRES_IN} <= 0 OR ${MessageTable.TABLE_NAME}.${MessageTable.EXPIRES_IN} > ${ChatItemArchiveExporter.EXPIRATION_CUTOFF.inWholeMilliseconds}) AND (${MessageTable.TABLE_NAME}.${MessageTable.EXPIRES_IN} <= 0 OR ${MessageTable.TABLE_NAME}.${MessageTable.EXPIRES_IN} > ${ChatItemArchiveExporter.EXPIRATION_CUTOFF.inWholeMilliseconds}) AND
$notReleaseChannelClause $notReleaseChannelClause
@@ -3358,7 +3366,7 @@ class AttachmentTable(
SELECT COUNT(*) FROM ( SELECT COUNT(*) FROM (
SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY
FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID} FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE ${buildAttachmentsThatNeedUploadQuery(transferStateFilter = "$ARCHIVE_TRANSFER_STATE != ${ArchiveTransferState.PERMANENT_FAILURE.value}")} WHERE ${buildAttachmentsThatCanArchiveQuery(archiveTransferStateFilter = "$ARCHIVE_TRANSFER_STATE != ${ArchiveTransferState.PERMANENT_FAILURE.value}")}
) )
""" """
) )
@@ -3370,7 +3378,7 @@ class AttachmentTable(
SELECT COUNT(*) FROM ( SELECT COUNT(*) FROM (
SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY
FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID} FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE ${buildAttachmentsThatNeedUploadQuery(transferStateFilter = "$ARCHIVE_TRANSFER_STATE = ${state.value}")} WHERE ${buildAttachmentsThatCanArchiveQuery(archiveTransferStateFilter = "$ARCHIVE_TRANSFER_STATE = ${state.value}")}
) )
""" """
) )
@@ -3385,7 +3393,7 @@ class AttachmentTable(
SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY SELECT DISTINCT $DATA_HASH_END, $REMOTE_KEY
FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID} FROM $TABLE_NAME LEFT JOIN ${MessageTable.TABLE_NAME} ON $TABLE_NAME.$MESSAGE_ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE WHERE
${buildAttachmentsThatNeedUploadQuery("$ARCHIVE_THUMBNAIL_TRANSFER_STATE = ${state.value}")} AND ${buildAttachmentsThatCanArchiveQuery("$ARCHIVE_THUMBNAIL_TRANSFER_STATE = ${state.value}")} AND
$QUOTE = 0 AND $QUOTE = 0 AND
($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND ($CONTENT_TYPE LIKE 'image/%' OR $CONTENT_TYPE LIKE 'video/%') AND
$CONTENT_TYPE != 'image/svg+xml' AND $CONTENT_TYPE != 'image/svg+xml' AND

View File

@@ -64,7 +64,7 @@ class OptimizeMediaJob private constructor(parameters: Parameters) : Job(paramet
val minimumAge = if (remaining > 5f) 30.days else 15.days val minimumAge = if (remaining > 5f) 30.days else 15.days
Log.i(TAG, "${"%.1f".format(remaining)}% storage available, not optimizing the last $minimumAge of attachments") Log.i(TAG, "${"%.1f".format(remaining)}% storage available, optimizing attachments older than $minimumAge")
SignalDatabase.attachments.markEligibleAttachmentsAsOptimized(minimumAge) SignalDatabase.attachments.markEligibleAttachmentsAsOptimized(minimumAge)

View File

@@ -6,7 +6,6 @@
package org.signal.core.models package org.signal.core.models
import org.signal.core.models.backup.MessageBackupKey import org.signal.core.models.backup.MessageBackupKey
import org.signal.core.util.logging.Log
private typealias LibSignalAccountEntropyPool = org.signal.libsignal.messagebackup.AccountEntropyPool private typealias LibSignalAccountEntropyPool = org.signal.libsignal.messagebackup.AccountEntropyPool