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

Verified Commit 0d3a08fe authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

perf: maximize CleanAPK detail concurrency

Use batch availability as a prefilter and fetch full details in parallel, with per-package fallback to keep labels correct.
parent d548fd32
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@ import foundation.e.apps.data.cleanapk.data.download.Download
import foundation.e.apps.data.cleanapk.data.search.Search
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.system.SystemInfoProvider
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import retrofit2.Response
import javax.inject.Inject

@@ -107,7 +110,41 @@ class CleanApkAppsRepository @Inject constructor(
    }

    override suspend fun getAppDetailsForPackages(packageNames: List<String>): List<Application> {
        return packageNames.map { getAppDetails(it) }
        return coroutineScope {
            if (packageNames.isEmpty()) {
                return@coroutineScope emptyList()
            }

            val response = cleanApkRetrofit.checkAvailablePackages(
                packages = packageNames,
                architectures = SystemInfoProvider.getSupportedArchitectureList()
            )
            val search = response.body()
            if (!response.isSuccessful || search?.success != true) {
                return@coroutineScope packageNames.map {
                    async { getAppDetails(it) }
                }.awaitAll()
            }

            val appsByPackage = search.apps.associateBy { it.package_name }
            return@coroutineScope packageNames.map { packageName ->
                val app = appsByPackage[packageName]
                if (app == null || app._id.isBlank()) {
                    async { getAppDetails(packageName) }
                } else {
                    async {
                        val appResponse = cleanApkRetrofit.getAppOrPWADetailsByID(
                            id = app._id,
                            architectures = SystemInfoProvider.getSupportedArchitectureList(),
                            type = null
                        )
                        appResponse.body()?.app?.let {
                            it.copy(source = if (it.is_pwa) Source.PWA else Source.OPEN_SOURCE)
                        } ?: Application()
                    }
                }
            }.awaitAll()
        }
    }

    override suspend fun getSearchResults(pattern: String): List<Application> {
+41 −1
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ import foundation.e.apps.data.cleanapk.data.categories.Categories
import foundation.e.apps.data.cleanapk.data.search.Search
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.Type
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import retrofit2.Response
import javax.inject.Inject

@@ -101,7 +104,44 @@ class CleanApkPwaRepository @Inject constructor(
    }

    override suspend fun getAppDetailsForPackages(packageNames: List<String>): List<Application> {
        return packageNames.map { getAppDetails(it) }
        return coroutineScope {
            if (packageNames.isEmpty()) {
                return@coroutineScope emptyList()
            }

            val response = cleanApkRetrofit.checkAvailablePackages(
                packageNames,
                CleanApkRetrofit.APP_TYPE_PWA
            )
            val search = response.body()
            if (!response.isSuccessful || search?.success != true) {
                return@coroutineScope packageNames.map {
                    async { getAppDetails(it) }
                }.awaitAll()
            }

            val appsByPackage = search.apps.associateBy { it.package_name }
            return@coroutineScope packageNames.map { packageName ->
                val app = appsByPackage[packageName]
                if (app == null || app._id.isBlank()) {
                    async { getAppDetails(packageName) }
                } else {
                    async {
                        val appResponse = cleanApkRetrofit.getAppOrPWADetailsByID(app._id, null, null)
                        appResponse.body()?.app?.let {
                            if (it.is_pwa) {
                                it.copy(
                                    source = Source.PWA,
                                    type = Type.PWA
                                )
                            } else {
                                it
                            }
                        } ?: Application()
                    }
                }
            }.awaitAll()
        }
    }

    override suspend fun getSearchResults(pattern: String): List<Application> {