commonMain.dev.inmo.micro_utils.repos.cache.KeyValuesCacheRepo.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of micro_utils.repos.cache-jvm Show documentation
Show all versions of micro_utils.repos.cache-jvm Show documentation
It is set of projects with micro tools for avoiding of routines coding
package dev.inmo.micro_utils.repos.cache
import dev.inmo.micro_utils.coroutines.SmartRWLocker
import dev.inmo.micro_utils.coroutines.withReadAcquire
import dev.inmo.micro_utils.coroutines.withWriteLock
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.*
import dev.inmo.micro_utils.repos.*
import dev.inmo.micro_utils.repos.cache.cache.KVCache
import dev.inmo.micro_utils.repos.cache.util.actualizeAll
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
open class ReadKeyValuesCacheRepo(
protected open val parentRepo: ReadKeyValuesRepo,
protected open val kvCache: KVCache>,
protected val locker: SmartRWLocker = SmartRWLocker(),
) : ReadKeyValuesRepo by parentRepo, CommonCacheRepo {
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult {
return locker.withReadAcquire {
getAll(k, reversed)
}.paginate(
pagination
)
}
override suspend fun getAll(k: Key, reversed: Boolean): List {
return locker.withReadAcquire {
kvCache.get(k)
} ?.let {
if (reversed) it.reversed() else it
} ?: parentRepo.getAll(k, reversed).also {
locker.withWriteLock {
kvCache.set(k, it)
}
}
}
override suspend fun contains(k: Key, v: Value): Boolean = locker.withReadAcquire {
kvCache.get(k)
} ?.contains(v) ?: (parentRepo.contains(k, v).also {
if (it) {
locker.withWriteLock {
kvCache.unset(k) // clear as invalid
}
}
})
override suspend fun contains(k: Key): Boolean = locker.withReadAcquire {
kvCache.contains(k)
} || parentRepo.contains(k)
override suspend fun invalidate() = kvCache.actualizeAll(parentRepo, locker = locker)
}
fun ReadKeyValuesRepo.cached(
kvCache: KVCache>,
locker: SmartRWLocker = SmartRWLocker(),
) = ReadKeyValuesCacheRepo(this, kvCache, locker)
open class KeyValuesCacheRepo(
parentRepo: KeyValuesRepo,
kvCache: KVCache>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
locker: SmartRWLocker = SmartRWLocker(),
) : ReadKeyValuesCacheRepo(parentRepo, kvCache, locker), KeyValuesRepo, WriteKeyValuesRepo by parentRepo, CommonCacheRepo {
protected val onNewJob = parentRepo.onNewValue.onEach { (k, v) ->
locker.withWriteLock {
kvCache.set(
k,
kvCache.get(k) ?.plus(v) ?: return@onEach
)
}
}.launchIn(scope)
protected val onRemoveJob = parentRepo.onValueRemoved.onEach { (k, v) ->
locker.withWriteLock {
kvCache.set(
k,
kvCache.get(k)?.minus(v) ?: return@onEach
)
}
}.launchIn(scope)
protected val onDataClearedJob = parentRepo.onDataCleared.onEach {
locker.withWriteLock {
kvCache.unset(it)
}
}.launchIn(scope)
}
fun KeyValuesRepo.cached(
kvCache: KVCache>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
locker: SmartRWLocker = SmartRWLocker(),
) = KeyValuesCacheRepo(this, kvCache, scope, locker)
© 2015 - 2024 Weber Informatics LLC | Privacy Policy