Add media retention policy (#5749)
* Add media retention policy. Add `ByteSize` class to help with conversions between byte units. * Use bit shifting instead of multiplication Improve the tests too
This commit is contained in:
parent
5dc93d672f
commit
2b5c94cf9a
3 changed files with 94 additions and 0 deletions
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Element Creations Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.core.data
|
||||||
|
|
||||||
|
enum class ByteUnit(val bitShift: Int) {
|
||||||
|
BYTES(0),
|
||||||
|
KB(10),
|
||||||
|
MB(20),
|
||||||
|
GB(30)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ByteSize internal constructor(val value: Long, val unit: ByteUnit) {
|
||||||
|
fun to(dest: ByteUnit): Long {
|
||||||
|
if (unit == dest) return value
|
||||||
|
return value shl unit.bitShift shr dest.bitShift
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val Number.gigaBytes get() = ByteSize(toLong(), ByteUnit.GB)
|
||||||
|
val Number.megaBytes get() = ByteSize(toLong(), ByteUnit.MB)
|
||||||
|
val Number.kiloBytes get() = ByteSize(toLong(), ByteUnit.KB)
|
||||||
|
val Number.bytes get() = ByteSize(toLong(), ByteUnit.BYTES)
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Element Creations Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.core.data
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class ByteSizeTest {
|
||||||
|
@Test
|
||||||
|
fun testSizeConversions() {
|
||||||
|
// Check bytes to other units
|
||||||
|
val bytes = 10_000_000.bytes
|
||||||
|
assertThat(bytes.to(ByteUnit.BYTES)).isEqualTo(bytes.value)
|
||||||
|
assertThat(bytes.to(ByteUnit.KB)).isEqualTo(bytes.value / 1024L)
|
||||||
|
assertThat(bytes.to(ByteUnit.MB)).isEqualTo(bytes.value / 1024L / 1024L)
|
||||||
|
assertThat(bytes.to(ByteUnit.GB)).isEqualTo(bytes.value / 1024L / 1024L / 1024L)
|
||||||
|
|
||||||
|
// Now check for values too small to be converted
|
||||||
|
assertThat(100.bytes.to(ByteUnit.KB)).isEqualTo(0)
|
||||||
|
assertThat(100.bytes.to(ByteUnit.MB)).isEqualTo(0)
|
||||||
|
assertThat(100.bytes.to(ByteUnit.GB)).isEqualTo(0)
|
||||||
|
|
||||||
|
// Check for KBs
|
||||||
|
val kiloBytes = 10_000.kiloBytes
|
||||||
|
assertThat(kiloBytes.to(ByteUnit.BYTES)).isEqualTo(kiloBytes.value * 1024L)
|
||||||
|
assertThat(kiloBytes.to(ByteUnit.KB)).isEqualTo(kiloBytes.value)
|
||||||
|
assertThat(kiloBytes.to(ByteUnit.MB)).isEqualTo(kiloBytes.value / 1024L)
|
||||||
|
assertThat(kiloBytes.to(ByteUnit.GB)).isEqualTo(kiloBytes.value / 1024L / 1024L)
|
||||||
|
|
||||||
|
// Check for MBs
|
||||||
|
val megaBytes = 10_000.megaBytes
|
||||||
|
assertThat(megaBytes.to(ByteUnit.BYTES)).isEqualTo(megaBytes.value * 1024L * 1024L)
|
||||||
|
assertThat(megaBytes.to(ByteUnit.KB)).isEqualTo(megaBytes.value * 1024L)
|
||||||
|
assertThat(megaBytes.to(ByteUnit.MB)).isEqualTo(megaBytes.value)
|
||||||
|
assertThat(megaBytes.to(ByteUnit.GB)).isEqualTo(megaBytes.value / 1024L)
|
||||||
|
|
||||||
|
// Check for GBs
|
||||||
|
val gigaBytes = 10.gigaBytes
|
||||||
|
assertThat(gigaBytes.to(ByteUnit.BYTES)).isEqualTo(gigaBytes.value * 1024L * 1024L * 1024L)
|
||||||
|
assertThat(gigaBytes.to(ByteUnit.KB)).isEqualTo(gigaBytes.value * 1024L * 1024L)
|
||||||
|
assertThat(gigaBytes.to(ByteUnit.MB)).isEqualTo(gigaBytes.value * 1024L)
|
||||||
|
assertThat(gigaBytes.to(ByteUnit.GB)).isEqualTo(gigaBytes.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@ package io.element.android.libraries.matrix.impl
|
||||||
|
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
|
import io.element.android.libraries.core.data.ByteUnit
|
||||||
|
import io.element.android.libraries.core.data.megaBytes
|
||||||
import io.element.android.libraries.di.CacheDirectory
|
import io.element.android.libraries.di.CacheDirectory
|
||||||
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||||
|
|
@ -37,10 +39,13 @@ import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder
|
||||||
import org.matrix.rustcomponents.sdk.SqliteStoreBuilder
|
import org.matrix.rustcomponents.sdk.SqliteStoreBuilder
|
||||||
import org.matrix.rustcomponents.sdk.use
|
import org.matrix.rustcomponents.sdk.use
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import uniffi.matrix_sdk_base.MediaRetentionPolicy
|
||||||
import uniffi.matrix_sdk_crypto.CollectStrategy
|
import uniffi.matrix_sdk_crypto.CollectStrategy
|
||||||
import uniffi.matrix_sdk_crypto.DecryptionSettings
|
import uniffi.matrix_sdk_crypto.DecryptionSettings
|
||||||
import uniffi.matrix_sdk_crypto.TrustRequirement
|
import uniffi.matrix_sdk_crypto.TrustRequirement
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.time.Duration.Companion.days
|
||||||
|
import kotlin.time.toJavaDuration
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
class RustMatrixClientFactory(
|
class RustMatrixClientFactory(
|
||||||
|
|
@ -70,6 +75,19 @@ class RustMatrixClientFactory(
|
||||||
.username(sessionData.userId)
|
.username(sessionData.userId)
|
||||||
.use { it.build() }
|
.use { it.build() }
|
||||||
|
|
||||||
|
client.setMediaRetentionPolicy(
|
||||||
|
MediaRetentionPolicy(
|
||||||
|
// Make this 500MB instead of 400MB
|
||||||
|
maxCacheSize = 500.megaBytes.to(ByteUnit.BYTES).toULong(),
|
||||||
|
// This is the default value, but let's make it explicit
|
||||||
|
maxFileSize = 20.megaBytes.to(ByteUnit.BYTES).toULong(),
|
||||||
|
// Use 30 days instead of 60
|
||||||
|
lastAccessExpiry = 30.days.toJavaDuration(),
|
||||||
|
// This is the default value, but let's make it explicit
|
||||||
|
cleanupFrequency = 1.days.toJavaDuration(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
client.restoreSession(sessionData.toSession())
|
client.restoreSession(sessionData.toSession())
|
||||||
|
|
||||||
create(client)
|
create(client)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue