mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 07:29:14 +01:00
store artwork seeds without read-time writes and prune periodically
This commit is contained in:
@@ -13,15 +13,9 @@ interface ArtworkSeedDao {
|
||||
@Upsert
|
||||
suspend fun upsert(seed: ArtworkSeed)
|
||||
|
||||
@Query("UPDATE artwork_seeds SET lastUsed = :lastUsed WHERE cacheKey = :cacheKey")
|
||||
suspend fun touch(
|
||||
cacheKey: String,
|
||||
lastUsed: Long,
|
||||
)
|
||||
|
||||
@Query(
|
||||
"DELETE FROM artwork_seeds WHERE cacheKey NOT IN " +
|
||||
"(SELECT cacheKey FROM artwork_seeds ORDER BY lastUsed DESC LIMIT :keep)",
|
||||
"(SELECT cacheKey FROM artwork_seeds ORDER BY storedAt DESC LIMIT :keep)",
|
||||
)
|
||||
suspend fun prune(keep: Int)
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ val MIGRATION_12_13 =
|
||||
connection.execSQL(
|
||||
"CREATE TABLE IF NOT EXISTS `artwork_seeds` (`cacheKey` TEXT NOT NULL, " +
|
||||
"`primary` INTEGER NOT NULL, `secondary` INTEGER, `nameBusy` INTEGER, " +
|
||||
"`sourceId` INTEGER NOT NULL, `lastUsed` INTEGER NOT NULL DEFAULT 0, " +
|
||||
"`sourceId` INTEGER NOT NULL, `storedAt` INTEGER NOT NULL DEFAULT 0, " +
|
||||
"PRIMARY KEY(`cacheKey`), " +
|
||||
"FOREIGN KEY(`sourceId`) REFERENCES `sources`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
)
|
||||
|
||||
@@ -255,7 +255,7 @@ data class ArtworkSeed(
|
||||
val secondary: Int?,
|
||||
val nameBusy: Boolean? = null,
|
||||
val sourceId: Long = 0,
|
||||
@ColumnInfo(defaultValue = "0") val lastUsed: Long = 0,
|
||||
@ColumnInfo(defaultValue = "0") val storedAt: Long = 0,
|
||||
)
|
||||
|
||||
class QueueKindConverter {
|
||||
|
||||
@@ -2,8 +2,10 @@ package com.subtracks.data.repo
|
||||
|
||||
import com.subtracks.data.db.SubtracksDatabase
|
||||
import com.subtracks.data.model.ArtworkSeed
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
private const val MAX_STORED_SEEDS = 1024
|
||||
private const val MAX_STORED_SEEDS = 10_240
|
||||
private const val PRUNE_EVERY_SAVES = 128
|
||||
|
||||
interface ArtworkSeedStore {
|
||||
suspend fun seed(cacheKey: String): ArtworkSeed?
|
||||
@@ -14,18 +16,19 @@ interface ArtworkSeedStore {
|
||||
class ArtworkSeedRepository(
|
||||
private val db: SubtracksDatabase,
|
||||
private val maxStoredSeeds: Int = MAX_STORED_SEEDS,
|
||||
private val pruneEverySaves: Int = PRUNE_EVERY_SAVES,
|
||||
) : ArtworkSeedStore {
|
||||
override suspend fun seed(cacheKey: String): ArtworkSeed? {
|
||||
val dao = db.artworkSeedDao()
|
||||
val row = dao.seed(cacheKey) ?: return null
|
||||
dao.touch(cacheKey, System.currentTimeMillis())
|
||||
return row
|
||||
}
|
||||
private val savesSincePrune = AtomicInteger(0)
|
||||
|
||||
override suspend fun seed(cacheKey: String): ArtworkSeed? = db.artworkSeedDao().seed(cacheKey)
|
||||
|
||||
override suspend fun save(seed: ArtworkSeed) {
|
||||
val sourceId = seed.cacheKey.substringBefore(':').toLongOrNull() ?: return
|
||||
val dao = db.artworkSeedDao()
|
||||
dao.upsert(seed.copy(sourceId = sourceId, lastUsed = System.currentTimeMillis()))
|
||||
dao.prune(maxStoredSeeds)
|
||||
dao.upsert(seed.copy(sourceId = sourceId, storedAt = System.currentTimeMillis()))
|
||||
if (savesSincePrune.incrementAndGet() >= pruneEverySaves) {
|
||||
savesSincePrune.set(0)
|
||||
dao.prune(maxStoredSeeds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user