improvements of cache repos

This commit is contained in:
InsanusMokrassar 2022-06-30 13:59:32 +06:00
parent 8ca10c00bb
commit 8bee354f04
9 changed files with 28 additions and 15 deletions

View File

@ -7,6 +7,11 @@
* `Ktor`: * `Ktor`:
* `Client`: * `Client`:
* `BodyPair` has been deprecated * `BodyPair` has been deprecated
* `Repos`:
* `Cache`:
* New interface `CacheRepo`
* New interface `FullCacheRepo`
* `actualize*` methods inside of full cache repos now open for overriding
## 0.11.10 ## 0.11.10

View File

@ -10,7 +10,7 @@ open class ReadCRUDCacheRepo<ObjectType, IdType>(
protected open val parentRepo: ReadCRUDRepo<ObjectType, IdType>, protected open val parentRepo: ReadCRUDRepo<ObjectType, IdType>,
protected open val kvCache: KVCache<IdType, ObjectType>, protected open val kvCache: KVCache<IdType, ObjectType>,
protected open val idGetter: (ObjectType) -> IdType protected open val idGetter: (ObjectType) -> IdType
) : ReadCRUDRepo<ObjectType, IdType> by parentRepo { ) : ReadCRUDRepo<ObjectType, IdType> by parentRepo, CacheRepo {
override suspend fun getById(id: IdType): ObjectType? = kvCache.get(id) ?: (parentRepo.getById(id) ?.also { override suspend fun getById(id: IdType): ObjectType? = kvCache.get(id) ?: (parentRepo.getById(id) ?.also {
kvCache.set(id, it) kvCache.set(id, it)
}) })
@ -28,7 +28,7 @@ open class WriteCRUDCacheRepo<ObjectType, IdType, InputValueType>(
protected open val kvCache: KVCache<IdType, ObjectType>, protected open val kvCache: KVCache<IdType, ObjectType>,
protected open val scope: CoroutineScope = CoroutineScope(Dispatchers.Default), protected open val scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
protected open val idGetter: (ObjectType) -> IdType protected open val idGetter: (ObjectType) -> IdType
) : WriteCRUDRepo<ObjectType, IdType, InputValueType> { ) : WriteCRUDRepo<ObjectType, IdType, InputValueType>, CacheRepo {
override val newObjectsFlow: Flow<ObjectType> by parentRepo::newObjectsFlow override val newObjectsFlow: Flow<ObjectType> by parentRepo::newObjectsFlow
override val updatedObjectsFlow: Flow<ObjectType> by parentRepo::updatedObjectsFlow override val updatedObjectsFlow: Flow<ObjectType> by parentRepo::updatedObjectsFlow
override val deletedObjectsIdsFlow: Flow<IdType> by parentRepo::deletedObjectsIdsFlow override val deletedObjectsIdsFlow: Flow<IdType> by parentRepo::deletedObjectsIdsFlow

View File

@ -0,0 +1,3 @@
package dev.inmo.micro_utils.repos.cache
interface CacheRepo

View File

@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.*
open class ReadKeyValueCacheRepo<Key,Value>( open class ReadKeyValueCacheRepo<Key,Value>(
protected open val parentRepo: ReadKeyValueRepo<Key, Value>, protected open val parentRepo: ReadKeyValueRepo<Key, Value>,
protected open val kvCache: KVCache<Key, Value>, protected open val kvCache: KVCache<Key, Value>,
) : ReadKeyValueRepo<Key,Value> by parentRepo { ) : ReadKeyValueRepo<Key,Value> by parentRepo, CacheRepo {
override suspend fun get(k: Key): Value? = kvCache.get(k) ?: parentRepo.get(k) ?.also { kvCache.set(k, it) } override suspend fun get(k: Key): Value? = kvCache.get(k) ?: parentRepo.get(k) ?.also { kvCache.set(k, it) }
override suspend fun contains(key: Key): Boolean = kvCache.contains(key) || parentRepo.contains(key) override suspend fun contains(key: Key): Boolean = kvCache.contains(key) || parentRepo.contains(key)
} }
@ -24,7 +24,7 @@ open class KeyValueCacheRepo<Key,Value>(
parentRepo: KeyValueRepo<Key, Value>, parentRepo: KeyValueRepo<Key, Value>,
kvCache: KVCache<Key, Value>, kvCache: KVCache<Key, Value>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) : ReadKeyValueCacheRepo<Key,Value>(parentRepo, kvCache), KeyValueRepo<Key,Value>, WriteKeyValueRepo<Key, Value> by parentRepo { ) : ReadKeyValueCacheRepo<Key,Value>(parentRepo, kvCache), KeyValueRepo<Key,Value>, WriteKeyValueRepo<Key, Value> by parentRepo, CacheRepo {
protected val onNewJob = parentRepo.onNewValue.onEach { kvCache.set(it.first, it.second) }.launchIn(scope) protected val onNewJob = parentRepo.onNewValue.onEach { kvCache.set(it.first, it.second) }.launchIn(scope)
protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope) protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope)
} }

View File

@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.*
open class ReadKeyValuesCacheRepo<Key,Value>( open class ReadKeyValuesCacheRepo<Key,Value>(
protected open val parentRepo: ReadKeyValuesRepo<Key, Value>, protected open val parentRepo: ReadKeyValuesRepo<Key, Value>,
protected open val kvCache: KVCache<Key, List<Value>> protected open val kvCache: KVCache<Key, List<Value>>
) : ReadKeyValuesRepo<Key,Value> by parentRepo { ) : ReadKeyValuesRepo<Key,Value> by parentRepo, CacheRepo {
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> { override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> {
return kvCache.get(k) ?.paginate( return kvCache.get(k) ?.paginate(
pagination.let { if (reversed) it.reverse(count(k)) else it } pagination.let { if (reversed) it.reverse(count(k)) else it }
@ -38,7 +38,7 @@ open class KeyValuesCacheRepo<Key,Value>(
parentRepo: KeyValuesRepo<Key, Value>, parentRepo: KeyValuesRepo<Key, Value>,
kvCache: KVCache<Key, List<Value>>, kvCache: KVCache<Key, List<Value>>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) : ReadKeyValuesCacheRepo<Key,Value>(parentRepo, kvCache), KeyValuesRepo<Key,Value>, WriteKeyValuesRepo<Key,Value> by parentRepo { ) : ReadKeyValuesCacheRepo<Key,Value>(parentRepo, kvCache), KeyValuesRepo<Key,Value>, WriteKeyValuesRepo<Key,Value> by parentRepo, CacheRepo {
protected val onNewJob = parentRepo.onNewValue.onEach { kvCache.set(it.first, kvCache.get(it.first) ?.plus(it.second) ?: listOf(it.second)) }.launchIn(scope) protected val onNewJob = parentRepo.onNewValue.onEach { kvCache.set(it.first, kvCache.get(it.first) ?.plus(it.second) ?: listOf(it.second)) }.launchIn(scope)
protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.set(it.first, kvCache.get(it.first) ?.minus(it.second) ?: return@onEach) }.launchIn(scope) protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.set(it.first, kvCache.get(it.first) ?.minus(it.second) ?: return@onEach) }.launchIn(scope)
protected val onDataClearedJob = parentRepo.onDataCleared.onEach { kvCache.unset(it) }.launchIn(scope) protected val onDataClearedJob = parentRepo.onDataCleared.onEach { kvCache.unset(it) }.launchIn(scope)

View File

@ -15,7 +15,7 @@ open class FullReadCRUDCacheRepo<ObjectType, IdType>(
protected open val parentRepo: ReadCRUDRepo<ObjectType, IdType>, protected open val parentRepo: ReadCRUDRepo<ObjectType, IdType>,
protected open val kvCache: FullKVCache<IdType, ObjectType>, protected open val kvCache: FullKVCache<IdType, ObjectType>,
protected open val idGetter: (ObjectType) -> IdType protected open val idGetter: (ObjectType) -> IdType
) : ReadCRUDRepo<ObjectType, IdType> { ) : ReadCRUDRepo<ObjectType, IdType>, FullCacheRepo {
protected inline fun <T> doOrTakeAndActualize( protected inline fun <T> doOrTakeAndActualize(
action: FullKVCache<IdType, ObjectType>.() -> Optional<T>, action: FullKVCache<IdType, ObjectType>.() -> Optional<T>,
actionElse: ReadCRUDRepo<ObjectType, IdType>.() -> T, actionElse: ReadCRUDRepo<ObjectType, IdType>.() -> T,
@ -31,7 +31,7 @@ open class FullReadCRUDCacheRepo<ObjectType, IdType>(
error("The result should be returned above") error("The result should be returned above")
} }
protected suspend fun actualizeAll() { protected open suspend fun actualizeAll() {
kvCache.clear() kvCache.clear()
doForAllWithNextPaging { doForAllWithNextPaging {
parentRepo.getByPagination(it).also { parentRepo.getByPagination(it).also {

View File

@ -0,0 +1,5 @@
package dev.inmo.micro_utils.repos.cache.full
import dev.inmo.micro_utils.repos.cache.CacheRepo
interface FullCacheRepo : CacheRepo

View File

@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.*
open class FullReadKeyValueCacheRepo<Key,Value>( open class FullReadKeyValueCacheRepo<Key,Value>(
protected open val parentRepo: ReadKeyValueRepo<Key, Value>, protected open val parentRepo: ReadKeyValueRepo<Key, Value>,
protected open val kvCache: FullKVCache<Key, Value>, protected open val kvCache: FullKVCache<Key, Value>,
) : ReadKeyValueRepo<Key, Value> { ) : ReadKeyValueRepo<Key, Value>, FullCacheRepo {
protected inline fun <T> doOrTakeAndActualize( protected inline fun <T> doOrTakeAndActualize(
action: FullKVCache<Key, Value>.() -> Optional<T>, action: FullKVCache<Key, Value>.() -> Optional<T>,
actionElse: ReadKeyValueRepo<Key, Value>.() -> T, actionElse: ReadKeyValueRepo<Key, Value>.() -> T,
@ -28,7 +28,7 @@ open class FullReadKeyValueCacheRepo<Key,Value>(
} }
error("The result should be returned above") error("The result should be returned above")
} }
protected suspend fun actualizeAll() { protected open suspend fun actualizeAll() {
kvCache.clear() kvCache.clear()
kvCache.set(parentRepo.getAll { keys(it) }.toMap()) kvCache.set(parentRepo.getAll { keys(it) }.toMap())
} }
@ -78,7 +78,7 @@ open class FullWriteKeyValueCacheRepo<Key,Value>(
protected open val parentRepo: WriteKeyValueRepo<Key, Value>, protected open val parentRepo: WriteKeyValueRepo<Key, Value>,
protected open val kvCache: FullKVCache<Key, Value>, protected open val kvCache: FullKVCache<Key, Value>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) : WriteKeyValueRepo<Key, Value> by parentRepo { ) : WriteKeyValueRepo<Key, Value> by parentRepo, FullCacheRepo {
protected val onNewJob = parentRepo.onNewValue.onEach { kvCache.set(it.first, it.second) }.launchIn(scope) protected val onNewJob = parentRepo.onNewValue.onEach { kvCache.set(it.first, it.second) }.launchIn(scope)
protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope) protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope)
} }

View File

@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.*
open class FullReadKeyValuesCacheRepo<Key,Value>( open class FullReadKeyValuesCacheRepo<Key,Value>(
protected open val parentRepo: ReadKeyValuesRepo<Key, Value>, protected open val parentRepo: ReadKeyValuesRepo<Key, Value>,
protected open val kvCache: FullKVCache<Key, List<Value>>, protected open val kvCache: FullKVCache<Key, List<Value>>,
) : ReadKeyValuesRepo<Key, Value> { ) : ReadKeyValuesRepo<Key, Value>, FullCacheRepo {
protected inline fun <T> doOrTakeAndActualize( protected inline fun <T> doOrTakeAndActualize(
action: FullKVCache<Key, List<Value>>.() -> Optional<T>, action: FullKVCache<Key, List<Value>>.() -> Optional<T>,
actionElse: ReadKeyValuesRepo<Key, Value>.() -> T, actionElse: ReadKeyValuesRepo<Key, Value>.() -> T,
@ -28,11 +28,11 @@ open class FullReadKeyValuesCacheRepo<Key,Value>(
error("The result should be returned above") error("The result should be returned above")
} }
protected suspend fun actualizeKey(k: Key) { protected open suspend fun actualizeKey(k: Key) {
kvCache.set(k, parentRepo.getAll(k)) kvCache.set(k, parentRepo.getAll(k))
} }
protected suspend fun actualizeAll() { protected open suspend fun actualizeAll() {
doAllWithCurrentPaging { kvCache.keys(it).also { kvCache.unset(it.results) } } doAllWithCurrentPaging { kvCache.keys(it).also { kvCache.unset(it.results) } }
kvCache.set(parentRepo.getAll()) kvCache.set(parentRepo.getAll())
} }
@ -112,7 +112,7 @@ open class FullWriteKeyValuesCacheRepo<Key,Value>(
protected open val parentRepo: WriteKeyValuesRepo<Key, Value>, protected open val parentRepo: WriteKeyValuesRepo<Key, Value>,
protected open val kvCache: FullKVCache<Key, List<Value>>, protected open val kvCache: FullKVCache<Key, List<Value>>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) : WriteKeyValuesRepo<Key, Value> by parentRepo { ) : WriteKeyValuesRepo<Key, Value> by parentRepo, FullCacheRepo {
protected val onNewJob = parentRepo.onNewValue.onEach { protected val onNewJob = parentRepo.onNewValue.onEach {
kvCache.set( kvCache.set(
it.first, it.first,