improvements to caching and prop fetching

should be fast as fuck boiiiiiiiiiii

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/89/head
androidacy-user 2 years ago
parent 58ebbc0ba3
commit 72faa2c244

@ -32,6 +32,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.util.concurrent.Executors
@Suppress("NAME_SHADOWING", "unused") @Suppress("NAME_SHADOWING", "unused")
class RepoManager private constructor(mainApplication: MainApplication) : SyncManager() { class RepoManager private constructor(mainApplication: MainApplication) : SyncManager() {
@ -172,19 +173,23 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
val repoModules = repoUpdaters[i]!!.toUpdate() val repoModules = repoUpdaters[i]!!.toUpdate()
val repoData = repoDatas[i] val repoData = repoDatas[i]
if (BuildConfig.DEBUG) Timber.d("Registering %s", repoData.name) if (BuildConfig.DEBUG) Timber.d("Registering %s", repoData.name)
// max threads is equal to the number of cores
val executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
for (repoModule in repoModules!!) { for (repoModule in repoModules!!) {
try { try {
if (repoModule.propUrl != null && repoModule.propUrl!!.isNotEmpty()) { if (repoModule.propUrl != null && repoModule.propUrl!!.isNotEmpty()) {
repoData.storeMetadata( executor.execute {
repoModule, doHttpGet( repoData.storeMetadata(
repoModule.propUrl!!, false repoModule, doHttpGet(
repoModule.propUrl!!, false
)
) )
) write(
write( File(repoData.cacheRoot, repoModule.id + ".prop"), doHttpGet(
File(repoData.cacheRoot, repoModule.id + ".prop"), doHttpGet( repoModule.propUrl!!, false
repoModule.propUrl!!, false )
) )
) }
} }
if (repoData.tryLoadMetadata(repoModule) && (allowLowQualityModules || !isLowQualityModule( if (repoData.tryLoadMetadata(repoModule) && (allowLowQualityModules || !isLowQualityModule(
repoModule.moduleInfo repoModule.moduleInfo

@ -72,14 +72,17 @@ class RepoUpdater(repoData2: RepoData) {
repoData.preferenceId, repoData.preferenceId,
results.size results.size
) )
val jsonObject = JSONObject()
// apply the toApply list to the toUpdate list // apply the toApply list to the toUpdate list
try { try {
val jsonObject = JSONObject()
jsonObject.put("modules", JSONArray(results)) jsonObject.put("modules", JSONArray(results))
toUpdate = repoData.populate(jsonObject) toUpdate = repoData.populate(jsonObject)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) Timber.e(e)
} }
// log first 100 chars of indexRaw
indexRaw = jsonObject.toString().toByteArray()
Timber.d("Index raw: %s", String(indexRaw!!, StandardCharsets.UTF_8).subSequence(0, 100))
// Since we reuse instances this should work // Since we reuse instances this should work
toApply = HashSet(repoData.moduleHashMap.values) toApply = HashSet(repoData.moduleHashMap.values)
(toApply as HashSet<RepoModule>).removeAll(toUpdate!!.toSet()) (toApply as HashSet<RepoModule>).removeAll(toUpdate!!.toSet())
@ -125,15 +128,19 @@ class RepoUpdater(repoData2: RepoData) {
fun finish(): Boolean { fun finish(): Boolean {
val success = AtomicBoolean(false) val success = AtomicBoolean(false)
Timber.d("Finishing update for %s", repoData.preferenceId)
// If repo is not enabled we don't need to do anything, just return true // If repo is not enabled we don't need to do anything, just return true
if (!repoData.isEnabled) { if (!repoData.isEnabled) {
Timber.d("Repo %s is disabled, skipping", repoData.preferenceId)
return true return true
} }
if (indexRaw != null) { if (indexRaw != null) {
val tmpIndexRaw = indexRaw!!
Timber.d("Updating database for %s", repoData.preferenceId)
// new thread to update the database // new thread to update the database
val thread = Thread { val thread = Thread {
val startTime = System.currentTimeMillis() val startTime = System.currentTimeMillis()
Timber.d("Updating database for %s", repoData.preferenceId) Timber.d("Updating database thread for %s", repoData.preferenceId)
try { try {
// iterate over modules, using this.supportedProperties as a template to attempt to get each property from the module. everything that is not null is added to the module // iterate over modules, using this.supportedProperties as a template to attempt to get each property from the module. everything that is not null is added to the module
// use room to insert to // use room to insert to
@ -145,23 +152,30 @@ class RepoUpdater(repoData2: RepoData) {
).build() ).build()
// all except first six can be null // all except first six can be null
// this.indexRaw is the raw index file (json) // this.indexRaw is the raw index file (json)
val modules = JSONObject(String(indexRaw!!, StandardCharsets.UTF_8)) val modules = JSONObject(String(tmpIndexRaw, StandardCharsets.UTF_8))
// androidacy repo uses "data" key, others should use "modules" key. Both are JSONArrays // androidacy repo uses "data" key, others should use "modules" key. Both are JSONArrays
val modulesArray: JSONArray = if (repoData.preferenceId == "androidacy_repo") { val modulesArray = try {
// get modules from "data" key. This is a JSONArray so we need to convert it to a JSONObject
modules.getJSONArray("data") modules.getJSONArray("data")
} else { } catch (e: Exception) {
// get modules from "modules" key. This is a JSONArray so we need to convert it to a JSONObject
modules.getJSONArray("modules") modules.getJSONArray("modules")
} catch (e: Exception) {
Timber.e(e)
Timber.w("No modules were found in the index file for %s", repoData.preferenceId)
Timber.d("Finished updating database for %s in %dms", repoData.preferenceId, System.currentTimeMillis() - startTime)
success.set(false)
return@Thread
} }
Timber.d("Got modules for %s", repoData.preferenceId)
val moduleListCacheDao = db.moduleListCacheDao() val moduleListCacheDao = db.moduleListCacheDao()
moduleListCacheDao.deleteByRepoId(repoData.preferenceId!!) moduleListCacheDao.deleteByRepoId(repoData.preferenceId!!)
Timber.d("Deleted old modules for %s", repoData.preferenceId)
if (modulesArray.length() == 0) { if (modulesArray.length() == 0) {
Timber.w("No modules were found in the index file for %s", repoData.preferenceId) Timber.w("No modules were found in the index file for %s", repoData.preferenceId)
Timber.d("Finished updating database for %s in %dms", repoData.preferenceId, System.currentTimeMillis() - startTime) Timber.d("Finished updating database for %s in %dms", repoData.preferenceId, System.currentTimeMillis() - startTime)
success.set(false) success.set(false)
return@Thread return@Thread
} }
Timber.d("Iterating over modules for %s", repoData.preferenceId)
// iterate over modules // iterate over modules
for (n in 0 until modulesArray.length()) { for (n in 0 until modulesArray.length()) {
// get module // get module
@ -169,7 +183,7 @@ class RepoUpdater(repoData2: RepoData) {
try { try {
// get module id // get module id
// if codename is present, prefer that over id // if codename is present, prefer that over id
val id: String? = val id: String =
if (module.has("codename") && module.getString("codename") != "") { if (module.has("codename") && module.getString("codename") != "") {
module.getString("codename") module.getString("codename")
} else { } else {
@ -294,7 +308,7 @@ class RepoUpdater(repoData2: RepoData) {
safe = safe, safe = safe,
lastUpdate = lastUpdate.toLong(), lastUpdate = lastUpdate.toLong(),
stats = downloads, stats = downloads,
codename = id ?: "" codename = id
) )
moduleListCacheDao.insert(moduleListCache) moduleListCacheDao.insert(moduleListCache)
} catch (ignored: Exception) { } catch (ignored: Exception) {
@ -320,6 +334,7 @@ class RepoUpdater(repoData2: RepoData) {
db.close() db.close()
success.set(true) success.set(true)
} else { } else {
Timber.d("No index file found for %s", repoData.preferenceId)
success.set(true) // assume we're reading from cache. this may be unsafe but it's better than nothing success.set(true) // assume we're reading from cache. this may be unsafe but it's better than nothing
} }
return success.get() return success.get()

Loading…
Cancel
Save