fix: chunk large cached events to avoid Preferences 8KB limit on desktop
java.util.prefs.Preferences (desktop Settings backend) has an 8KB per-value limit. Schedule JSON exceeds this. Now splits into 8000-char chunks stored as cached_events_chunk_<account>_<i>, with a count key. Maintains backward compat with old single-value format.
This commit is contained in:
@@ -9,10 +9,16 @@ import kotlinx.serialization.json.Json
|
|||||||
|
|
||||||
class ScheduleCache(private val settings: Settings) {
|
class ScheduleCache(private val settings: Settings) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val CHUNK_SIZE = 8000
|
||||||
|
}
|
||||||
|
|
||||||
private val json = Json { ignoreUnknownKeys = true }
|
private val json = Json { ignoreUnknownKeys = true }
|
||||||
private val eventListSerializer = ListSerializer(Event.serializer())
|
private val eventListSerializer = ListSerializer(Event.serializer())
|
||||||
|
|
||||||
private fun eventsKey(account: String) = "cached_events_$account"
|
private fun eventsKey(account: String) = "cached_events_$account"
|
||||||
|
private fun eventsChunkCountKey(account: String) = "cached_events_count_$account"
|
||||||
|
private fun eventsChunkKey(account: String, index: Int) = "cached_events_chunk_${account}_$index"
|
||||||
private fun agegroupKey(account: String) = "filters_agegroup_$account"
|
private fun agegroupKey(account: String) = "filters_agegroup_$account"
|
||||||
private fun subgroupKey(account: String) = "filters_subgroup_$account"
|
private fun subgroupKey(account: String) = "filters_subgroup_$account"
|
||||||
private fun typeFilterKey(account: String) = "filters_typefilter_$account"
|
private fun typeFilterKey(account: String) = "filters_typefilter_$account"
|
||||||
@@ -20,11 +26,31 @@ class ScheduleCache(private val settings: Settings) {
|
|||||||
|
|
||||||
@OptIn(ExperimentalTime::class)
|
@OptIn(ExperimentalTime::class)
|
||||||
fun saveEvents(account: String, events: List<Event>) {
|
fun saveEvents(account: String, events: List<Event>) {
|
||||||
settings.putString(eventsKey(account), json.encodeToString(eventListSerializer, events))
|
val jsonStr = json.encodeToString(eventListSerializer, events)
|
||||||
|
val chunks = jsonStr.chunked(CHUNK_SIZE)
|
||||||
|
|
||||||
|
settings.remove(eventsKey(account))
|
||||||
|
settings.putInt(eventsChunkCountKey(account), chunks.size)
|
||||||
|
chunks.forEachIndexed { i, chunk ->
|
||||||
|
settings.putString(eventsChunkKey(account, i), chunk)
|
||||||
|
}
|
||||||
settings.putLong(timestampKey(account), Clock.System.now().toEpochMilliseconds())
|
settings.putLong(timestampKey(account), Clock.System.now().toEpochMilliseconds())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadEvents(account: String): List<Event>? {
|
fun loadEvents(account: String): List<Event>? {
|
||||||
|
val chunkCount = settings.getIntOrNull(eventsChunkCountKey(account))
|
||||||
|
if (chunkCount != null && chunkCount > 0) {
|
||||||
|
val jsonStr = (0 until chunkCount).mapNotNull { i ->
|
||||||
|
settings.getStringOrNull(eventsChunkKey(account, i))
|
||||||
|
}.joinToString("")
|
||||||
|
if (jsonStr.isEmpty()) return null
|
||||||
|
return try {
|
||||||
|
json.decodeFromString(eventListSerializer, jsonStr)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val jsonString = settings.getStringOrNull(eventsKey(account)) ?: return null
|
val jsonString = settings.getStringOrNull(eventsKey(account)) ?: return null
|
||||||
return try {
|
return try {
|
||||||
json.decodeFromString(eventListSerializer, jsonString)
|
json.decodeFromString(eventListSerializer, jsonString)
|
||||||
@@ -58,6 +84,11 @@ class ScheduleCache(private val settings: Settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun clearCache(account: String) {
|
fun clearCache(account: String) {
|
||||||
|
val chunkCount = settings.getIntOrNull(eventsChunkCountKey(account)) ?: 0
|
||||||
|
for (i in 0 until chunkCount) {
|
||||||
|
settings.remove(eventsChunkKey(account, i))
|
||||||
|
}
|
||||||
|
settings.remove(eventsChunkCountKey(account))
|
||||||
settings.remove(eventsKey(account))
|
settings.remove(eventsKey(account))
|
||||||
settings.remove(timestampKey(account))
|
settings.remove(timestampKey(account))
|
||||||
settings.remove(agegroupKey(account))
|
settings.remove(agegroupKey(account))
|
||||||
|
|||||||
Reference in New Issue
Block a user