mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-12-01 22:40:09 +00:00
add repos.cache
This commit is contained in:
parent
8e62dd460c
commit
08c371c142
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## 0.4.31
|
## 0.4.31
|
||||||
|
|
||||||
|
* Add subproject `repos.cache`
|
||||||
|
|
||||||
## 0.4.30
|
## 0.4.30
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
17
repos/cache/build.gradle
vendored
Normal file
17
repos/cache/build.gradle
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
id "com.android.library"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$mppProjectWithSerializationPresetPath"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api internalProject("micro_utils.repos.common")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValueCacheRepo.kt
vendored
Normal file
42
repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValueCacheRepo.kt
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.cache
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.*
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
|
||||||
|
open class KeyValueCacheRepo<Key,Value>(
|
||||||
|
protected val parentRepo: KeyValueRepo<Key, Value>,
|
||||||
|
protected val cachedValuesCount: Int,
|
||||||
|
scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||||
|
) : KeyValueRepo<Key,Value> by parentRepo {
|
||||||
|
protected open val cache = mutableMapOf<Key,Value>()
|
||||||
|
protected open val cacheStack = ArrayList<Key>(cachedValuesCount)
|
||||||
|
protected val syncMutex = Mutex()
|
||||||
|
protected val onNewJob = parentRepo.onNewValue.onEach { putCacheValue(it.first, it.second) }.launchIn(scope)
|
||||||
|
protected val onRemoveJob = parentRepo.onValueRemoved.onEach { removeCacheValue(it) }.launchIn(scope)
|
||||||
|
|
||||||
|
protected suspend fun putCacheValue(k: Key, v: Value) = syncMutex.withLock {
|
||||||
|
if (cache.size >= cachedValuesCount) {
|
||||||
|
val key = cacheStack.removeAt(0)
|
||||||
|
cache.remove(key)
|
||||||
|
}
|
||||||
|
cacheStack.add(k)
|
||||||
|
cache[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
protected suspend fun removeCacheValue(k: Key) = syncMutex.withLock {
|
||||||
|
val i = cacheStack.indexOf(k)
|
||||||
|
if (i >= 0) {
|
||||||
|
val key = cacheStack.removeAt(i)
|
||||||
|
cache.remove(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun get(k: Key): Value? = syncMutex.withLock {
|
||||||
|
cache[k] ?: parentRepo.get(k) ?.also { cache[k] = it }
|
||||||
|
}
|
||||||
|
override suspend fun contains(key: Key): Boolean = cache.containsKey(key) || parentRepo.contains(key)
|
||||||
|
}
|
74
repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValuesCacheRepo.kt
vendored
Normal file
74
repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValuesCacheRepo.kt
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.cache
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.pagination.Pagination
|
||||||
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.paginate
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.reverse
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.*
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
|
||||||
|
open class KeyValuesCacheRepo<Key,Value>(
|
||||||
|
protected val parentRepo: KeyValuesRepo<Key, Value>,
|
||||||
|
protected val cachedValuesCount: Int,
|
||||||
|
scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||||
|
) : KeyValuesRepo<Key,Value> by parentRepo {
|
||||||
|
protected open val cache = mutableMapOf<Key, List<Value>>()
|
||||||
|
protected open val cacheStack = ArrayList<Key>(cachedValuesCount)
|
||||||
|
protected val syncMutex = Mutex()
|
||||||
|
protected val onNewJob = parentRepo.onNewValue.onEach { putCacheValue(it.first, it.second) }.launchIn(scope)
|
||||||
|
protected val onRemoveJob = parentRepo.onValueRemoved.onEach { removeCacheValue(it.first, it.second) }.launchIn(scope)
|
||||||
|
protected val onDataClearedJob = parentRepo.onDataCleared.onEach { clearCacheValues(it) }.launchIn(scope)
|
||||||
|
|
||||||
|
protected suspend fun putCacheValues(k: Key, v: List<Value>) = syncMutex.withLock {
|
||||||
|
if (cache.size >= cachedValuesCount) {
|
||||||
|
val key = cacheStack.removeAt(0)
|
||||||
|
cache.remove(key)
|
||||||
|
}
|
||||||
|
cacheStack.add(k)
|
||||||
|
cache[k] = v
|
||||||
|
}
|
||||||
|
protected suspend fun putCacheValue(k: Key, v: Value) = syncMutex.withLock {
|
||||||
|
cache[k] ?.let {
|
||||||
|
cache[k] = it + v
|
||||||
|
}
|
||||||
|
} ?: putCacheValues(k, listOf(v))
|
||||||
|
|
||||||
|
protected suspend fun removeCacheValue(k: Key, v: Value) = syncMutex.withLock {
|
||||||
|
cache[k] ?.let {
|
||||||
|
val newList = it - v
|
||||||
|
if (newList.isEmpty()) {
|
||||||
|
cache.remove(k)
|
||||||
|
cacheStack.remove(k)
|
||||||
|
} else {
|
||||||
|
cache[k] = newList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected suspend fun clearCacheValues(k: Key) = syncMutex.withLock {
|
||||||
|
val i = cacheStack.indexOf(k)
|
||||||
|
if (i >= 0) {
|
||||||
|
val key = cacheStack.removeAt(i)
|
||||||
|
cache.remove(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> {
|
||||||
|
return cache[k] ?.paginate(
|
||||||
|
pagination.let { if (reversed) it.reverse(count(k)) else it }
|
||||||
|
) ?.let {
|
||||||
|
if (reversed) it.copy(results = it.results.reversed()) else it
|
||||||
|
} ?: parentRepo.get(k, pagination, reversed)
|
||||||
|
}
|
||||||
|
override suspend fun getAll(k: Key, reversed: Boolean): List<Value> {
|
||||||
|
return cache[k] ?.let {
|
||||||
|
if (reversed) it.reversed() else it
|
||||||
|
} ?: parentRepo.getAll(k, reversed)
|
||||||
|
}
|
||||||
|
override suspend fun contains(k: Key, v: Value): Boolean = cache[k] ?.contains(v) ?: parentRepo.contains(k, v)
|
||||||
|
override suspend fun contains(k: Key): Boolean = cache.containsKey(k) || parentRepo.contains(k)
|
||||||
|
}
|
1
repos/cache/src/main/AndroidManifest.xml
vendored
Normal file
1
repos/cache/src/main/AndroidManifest.xml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="dev.inmo.micro_utils.repos.cache"/>
|
@ -11,6 +11,7 @@ String[] includes = [
|
|||||||
":pagination:ktor:server",
|
":pagination:ktor:server",
|
||||||
":mime_types",
|
":mime_types",
|
||||||
":repos:common",
|
":repos:common",
|
||||||
|
":repos:cache",
|
||||||
":repos:exposed",
|
":repos:exposed",
|
||||||
":repos:inmemory",
|
":repos:inmemory",
|
||||||
":repos:ktor:client",
|
":repos:ktor:client",
|
||||||
|
Loading…
Reference in New Issue
Block a user