Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 880ebcbc authored by Rafael Tonholo's avatar Rafael Tonholo
Browse files

feat(outbox): cache the outbox id for a better performance

parent 51225e71
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@ import com.fsck.k9.mailstore.folder.DefaultOutboxFolderManager
import com.fsck.k9.message.extractors.AttachmentCounter
import com.fsck.k9.message.extractors.MessageFulltextCreator
import com.fsck.k9.message.extractors.MessagePreviewCreator
import kotlin.time.ExperimentalTime
import net.thunderbird.core.common.cache.TimeLimitedCache
import net.thunderbird.feature.mail.folder.api.OutboxFolderManager
import org.koin.dsl.module

@@ -48,6 +50,7 @@ val mailStoreModule = module {
            logger = get(),
            accountManager = get(),
            localStoreProvider = get(),
            outboxFolderIdCache = @OptIn(ExperimentalTime::class)TimeLimitedCache(),
        )
    }
}
+53 −36
Original line number Diff line number Diff line
@@ -8,11 +8,13 @@ import com.fsck.k9.mailstore.LocalStoreProvider
import com.fsck.k9.mailstore.toDatabaseFolderType
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.time.ExperimentalTime
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import net.thunderbird.core.android.account.LegacyAccountManager
import net.thunderbird.core.common.cache.TimeLimitedCache
import net.thunderbird.core.common.exception.MessagingException
import net.thunderbird.core.logging.Logger
import net.thunderbird.core.outcome.Outcome
@@ -28,28 +30,41 @@ class DefaultOutboxFolderManager(
    private val logger: Logger,
    private val accountManager: LegacyAccountManager,
    private val localStoreProvider: LocalStoreProvider,
    private val outboxFolderIdCache: TimeLimitedCache<AccountId, Long>,
    private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
) : OutboxFolderManager {
    @OptIn(ExperimentalTime::class)
    override suspend fun getOutboxFolderId(
        uuid: AccountId,
        createIfMissing: Boolean,
    ): Long = withContext(ioDispatcher) {
    ): Long {
        logger.verbose(TAG) { "getOutboxFolderId() called with: uuid = $uuid" }
        outboxFolderIdCache[uuid]?.let { entry ->
            logger.debug(TAG) {
                "getOutboxFolderId: Found Outbox folder with id = ${entry.value} in cache. " +
                    "Cache expires on ${entry.expiresAt}"
            }
            return entry.value
        }

        return withContext(ioDispatcher) {
            val localStore = createLocalStore(uuid)

            var id = try {
                suspendCancellableCoroutine { continuation ->
                    localStore.database.execute(false) { db ->
                    var id = -1L
                        db.rawQuery(
                            "SELECT id FROM folders WHERE type = ?",
                            arrayOf(FolderType.OUTBOX.toDatabaseFolderType()),
                        ).use { cursor ->
                            var id = -1L
                            if (cursor.moveToFirst()) {
                                id = cursor.getLong(0)
                                logger.debug(TAG) { "getOutboxFolderId: Found Outbox folder with id = $id." }
                            }

                            if (id != -1L) {
                                outboxFolderIdCache.set(key = uuid, value = id)
                                continuation.resume(id)
                            } else {
                                continuation.resumeWithException(MessagingException("Outbox folder not found"))
@@ -67,6 +82,7 @@ class DefaultOutboxFolderManager(
                createOutboxFolder(uuid).handleAsync(
                    onSuccess = {
                        logger.debug(TAG) { "Created Outbox folder with id = $it." }
                        outboxFolderIdCache.set(key = uuid, value = it)
                        id = it
                    },
                    onFailure = { exception ->
@@ -78,6 +94,7 @@ class DefaultOutboxFolderManager(

            id
        }
    }

    override suspend fun createOutboxFolder(uuid: AccountId): Outcome<Long, Exception> = withContext(ioDispatcher) {
        logger.verbose(TAG) { "createOutboxFolder() called with: uuid = $uuid" }