commonMain.dev.inmo.micro_utils.repos.cache.CRUDCacheRepo.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.repos.*
import dev.inmo.micro_utils.repos.cache.cache.KVCache
import dev.inmo.micro_utils.repos.cache.util.ActualizeAllClearMode
import dev.inmo.micro_utils.repos.cache.util.actualizeAll
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
open class ReadCRUDCacheRepo(
protected open val parentRepo: ReadCRUDRepo,
protected open val kvCache: KVCache,
protected val locker: SmartRWLocker = SmartRWLocker(),
protected open val idGetter: (ObjectType) -> IdType
) : ReadCRUDRepo by parentRepo, CommonCacheRepo {
override suspend fun getById(id: IdType): ObjectType? = locker.withReadAcquire {
kvCache.get(id)
} ?: (parentRepo.getById(id) ?.also {
locker.withWriteLock {
kvCache.set(id, it)
}
})
override suspend fun getAll(): Map {
return locker.withReadAcquire {
kvCache.getAll()
}.takeIf { it.size.toLong() == count() } ?: parentRepo.getAll().also {
locker.withWriteLock {
kvCache.actualizeAll(clearMode = ActualizeAllClearMode.BeforeSet) { it }
}
}
}
override suspend fun contains(id: IdType): Boolean = locker.withReadAcquire {
kvCache.contains(id)
} || parentRepo.contains(id)
override suspend fun invalidate() = locker.withWriteLock {
kvCache.clear()
}
}
fun ReadCRUDRepo.cached(
kvCache: KVCache,
locker: SmartRWLocker = SmartRWLocker(),
idGetter: (ObjectType) -> IdType
) = ReadCRUDCacheRepo(this, kvCache, locker, idGetter)
open class WriteCRUDCacheRepo(
protected open val parentRepo: WriteCRUDRepo,
protected open val kvCache: KeyValueRepo,
protected open val scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
protected val locker: SmartRWLocker = SmartRWLocker(),
protected open val idGetter: (ObjectType) -> IdType
) : WriteCRUDRepo, CommonCacheRepo {
override val newObjectsFlow: Flow by parentRepo::newObjectsFlow
override val updatedObjectsFlow: Flow by parentRepo::updatedObjectsFlow
override val deletedObjectsIdsFlow: Flow by parentRepo::deletedObjectsIdsFlow
val createdObjectsFlowJob = parentRepo.newObjectsFlow.onEach {
locker.withWriteLock {
kvCache.set(idGetter(it), it)
}
}.launchIn(scope)
val updatedObjectsFlowJob = parentRepo.updatedObjectsFlow.onEach {
locker.withWriteLock {
kvCache.set(idGetter(it), it)
}
}.launchIn(scope)
val deletedObjectsFlowJob = parentRepo.deletedObjectsIdsFlow.onEach {
locker.withWriteLock {
kvCache.unset(it)
}
}.launchIn(scope)
override suspend fun deleteById(ids: List) = parentRepo.deleteById(ids).also {
locker.withWriteLock {
kvCache.unset(ids)
}
}
override suspend fun update(values: List>): List {
val updated = parentRepo.update(values)
locker.withWriteLock {
kvCache.unset(values.map { it.id })
kvCache.set(updated.associateBy { idGetter(it) })
}
return updated
}
override suspend fun update(id: IdType, value: InputValueType): ObjectType? {
return parentRepo.update(id, value) ?.also {
locker.withWriteLock {
kvCache.unset(id)
kvCache.set(idGetter(it), it)
}
}
}
override suspend fun create(values: List): List {
val created = parentRepo.create(values)
locker.withWriteLock {
kvCache.set(
created.associateBy { idGetter(it) }
)
}
return created
}
override suspend fun invalidate() = locker.withWriteLock {
kvCache.clear()
}
}
fun WriteCRUDRepo.caching(
kvCache: KVCache,
scope: CoroutineScope,
locker: SmartRWLocker = SmartRWLocker(),
idGetter: (ObjectType) -> IdType
) = WriteCRUDCacheRepo(this, kvCache, scope, locker, idGetter)
open class CRUDCacheRepo(
override val parentRepo: CRUDRepo,
kvCache: KVCache,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
locker: SmartRWLocker = SmartRWLocker(),
idGetter: (ObjectType) -> IdType
) : ReadCRUDCacheRepo(
parentRepo,
kvCache,
locker,
idGetter
),
WriteCRUDRepo by WriteCRUDCacheRepo(
parentRepo,
kvCache,
scope,
locker,
idGetter
),
CRUDRepo {
override suspend fun invalidate() = kvCache.actualizeAll(parentRepo, locker = locker)
}
fun CRUDRepo.cached(
kvCache: KVCache,
scope: CoroutineScope,
locker: SmartRWLocker = SmartRWLocker(),
idGetter: (ObjectType) -> IdType
) = CRUDCacheRepo(this, kvCache, scope, locker, idGetter)
© 2015 - 2024 Weber Informatics LLC | Privacy Policy