mirror of
				https://github.com/InsanusMokrassar/MicroUtils.git
				synced 2025-10-31 12:10:29 +00:00 
			
		
		
		
	Compare commits
	
		
			24 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ab42507275 | |||
| dcef844e20 | |||
| 3244708c1b | |||
| 73ac1f1741 | |||
| f104e9f352 | |||
| 393c9a7d06 | |||
| ea497ea488 | |||
|  | 5add89cad0 | ||
| 2db447d2ef | |||
| 31c83813e6 | |||
| 27483a282d | |||
| 48b816aa22 | |||
| 0065f94f52 | |||
| ccc0002eb2 | |||
| 15a2eee141 | |||
| b9faac71e5 | |||
| 0a4465de33 | |||
| f9dfd09628 | |||
| 8638d7afce | |||
| 8311793a43 | |||
| 0d552cfcd2 | |||
| 4b0f20dbd1 | |||
| cf531c949d | |||
| ba5c5f17d5 | 
							
								
								
									
										42
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,5 +1,47 @@ | |||||||
| # Changelog | # Changelog | ||||||
|  |  | ||||||
|  | ## 0.20.39 | ||||||
|  |  | ||||||
|  | * `Versions`: | ||||||
|  |     * `Kotlin`: `1.9.22` -> `1.9.23` | ||||||
|  |     * `Korlibs`: `5.3.2` -> `5.4.0` | ||||||
|  |     * `Okio`: `3.8.0` -> `3.9.0` | ||||||
|  |     * `Compose`: `1.6.0` -> `1.6.1` | ||||||
|  |     * `ComposeMaterial3`: `1.2.0` -> `1.2.1` | ||||||
|  |  | ||||||
|  | ## 0.20.38 | ||||||
|  |  | ||||||
|  | * `Versions`: | ||||||
|  |     * `Ktor`: `2.3.8` -> `2.3.9` | ||||||
|  |  | ||||||
|  | ## 0.20.37 | ||||||
|  |  | ||||||
|  | * `Versions`: | ||||||
|  |     * `Compose`: `1.5.12` -> `1.6.0` | ||||||
|  |     * `Exposed`: `0.47.0` -> `0.48.0` | ||||||
|  |  | ||||||
|  | ## 0.20.36 | ||||||
|  |  | ||||||
|  | * `Versions`: | ||||||
|  |     * `Serialization`: `1.6.2` -> `1.6.3` | ||||||
|  |     * `Korlibs`: `5.3.1` -> `5.3.2` | ||||||
|  | * `Repos`: | ||||||
|  |     * `Cache`: | ||||||
|  |         * Improve work and functionality of `actualizeAll` and subsequent functions | ||||||
|  |         * All internal repos `invalidate`/`actualizeAll` now use common `actualizeAll` functions | ||||||
|  |  | ||||||
|  | ## 0.20.35 | ||||||
|  |  | ||||||
|  | * `Versions`: | ||||||
|  |     * `Coroutines`: `1.7.3` -> `1.8.0` | ||||||
|  |     * `Material3`: `1.1.2` -> `1.2.0` | ||||||
|  |  | ||||||
|  | ## 0.20.34 | ||||||
|  |  | ||||||
|  | * `Repos`: | ||||||
|  |     * `Common`: | ||||||
|  |         * Improve default `set` realization of `KeyValuesRepo` | ||||||
|  |  | ||||||
| ## 0.20.33 | ## 0.20.33 | ||||||
|  |  | ||||||
| * `Colors` | * `Colors` | ||||||
|   | |||||||
| @@ -15,5 +15,5 @@ crypto_js_version=4.1.1 | |||||||
| # Project data | # Project data | ||||||
|  |  | ||||||
| group=dev.inmo | group=dev.inmo | ||||||
| version=0.20.33 | version=0.20.39 | ||||||
| android_code_version=239 | android_code_version=245 | ||||||
|   | |||||||
| @@ -1,32 +1,32 @@ | |||||||
| [versions] | [versions] | ||||||
|  |  | ||||||
| kt = "1.9.22" | kt = "1.9.23" | ||||||
| kt-serialization = "1.6.2" | kt-serialization = "1.6.3" | ||||||
| kt-coroutines = "1.7.3" | kt-coroutines = "1.8.0" | ||||||
|  |  | ||||||
| kslog = "1.3.2" | kslog = "1.3.2" | ||||||
|  |  | ||||||
| jb-compose = "1.5.12" | jb-compose = "1.6.1" | ||||||
| jb-exposed = "0.47.0" | jb-exposed = "0.48.0" | ||||||
| jb-dokka = "1.9.10" | jb-dokka = "1.9.20" | ||||||
|  |  | ||||||
| korlibs = "5.3.1" | korlibs = "5.4.0" | ||||||
| uuid = "0.8.2" | uuid = "0.8.2" | ||||||
|  |  | ||||||
| ktor = "2.3.8" | ktor = "2.3.9" | ||||||
|  |  | ||||||
| gh-release = "2.5.2" | gh-release = "2.5.2" | ||||||
|  |  | ||||||
| koin = "3.5.3" | koin = "3.5.3" | ||||||
|  |  | ||||||
| okio = "3.8.0" | okio = "3.9.0" | ||||||
|  |  | ||||||
| ksp = "1.9.22-1.0.17" | ksp = "1.9.23-1.0.19" | ||||||
| kotlin-poet = "1.16.0" | kotlin-poet = "1.16.0" | ||||||
|  |  | ||||||
| versions = "0.51.0" | versions = "0.51.0" | ||||||
|  |  | ||||||
| android-gradle = "8.2.2" | android-gradle = "8.3.0" | ||||||
| dexcount = "4.0.0" | dexcount = "4.0.0" | ||||||
|  |  | ||||||
| android-coreKtx = "1.12.0" | android-coreKtx = "1.12.0" | ||||||
| @@ -35,7 +35,7 @@ android-appCompat = "1.6.1" | |||||||
| android-fragment = "1.6.2" | android-fragment = "1.6.2" | ||||||
| android-espresso = "3.5.1" | android-espresso = "3.5.1" | ||||||
| android-test = "1.1.5" | android-test = "1.1.5" | ||||||
| android-compose-material3 = "1.1.2" | android-compose-material3 = "1.2.1" | ||||||
|  |  | ||||||
| android-props-minSdk = "21" | android-props-minSdk = "21" | ||||||
| android-props-compileSdk = "34" | android-props-compileSdk = "34" | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import dev.inmo.micro_utils.coroutines.withReadAcquire | |||||||
| import dev.inmo.micro_utils.coroutines.withWriteLock | import dev.inmo.micro_utils.coroutines.withWriteLock | ||||||
| import dev.inmo.micro_utils.repos.* | import dev.inmo.micro_utils.repos.* | ||||||
| import dev.inmo.micro_utils.repos.cache.cache.KVCache | 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 dev.inmo.micro_utils.repos.cache.util.actualizeAll | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
| @@ -29,7 +30,7 @@ open class ReadCRUDCacheRepo<ObjectType, IdType>( | |||||||
|             kvCache.getAll() |             kvCache.getAll() | ||||||
|         }.takeIf { it.size.toLong() == count() } ?: parentRepo.getAll().also { |         }.takeIf { it.size.toLong() == count() } ?: parentRepo.getAll().also { | ||||||
|             locker.withWriteLock { |             locker.withWriteLock { | ||||||
|                 kvCache.actualizeAll(true) { it } |                 kvCache.actualizeAll(clearMode = ActualizeAllClearMode.BeforeSet) { it } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -148,7 +149,9 @@ open class CRUDCacheRepo<ObjectType, IdType, InputValueType>( | |||||||
|     locker, |     locker, | ||||||
|     idGetter |     idGetter | ||||||
| ), | ), | ||||||
|     CRUDRepo<ObjectType, IdType, InputValueType> |     CRUDRepo<ObjectType, IdType, InputValueType> { | ||||||
|  |     override suspend fun invalidate() = kvCache.actualizeAll(parentRepo, locker = locker) | ||||||
|  | } | ||||||
|  |  | ||||||
| fun <ObjectType, IdType, InputType> CRUDRepo<ObjectType, IdType, InputType>.cached( | fun <ObjectType, IdType, InputType> CRUDRepo<ObjectType, IdType, InputType>.cached( | ||||||
|     kvCache: KVCache<IdType, ObjectType>, |     kvCache: KVCache<IdType, ObjectType>, | ||||||
|   | |||||||
| @@ -1,5 +1,11 @@ | |||||||
| package dev.inmo.micro_utils.repos.cache | package dev.inmo.micro_utils.repos.cache | ||||||
|  |  | ||||||
| interface CacheRepo { | interface InvalidatableRepo { | ||||||
|  |     /** | ||||||
|  |      * Invalidates its internal data. It __may__ lead to autoreload of data. In case when repo makes autoreload, | ||||||
|  |      * it must do loading of data __before__ clear | ||||||
|  |      */ | ||||||
|     suspend fun invalidate() |     suspend fun invalidate() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | typealias CacheRepo = InvalidatableRepo | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import dev.inmo.micro_utils.coroutines.withWriteLock | |||||||
| import dev.inmo.micro_utils.pagination.* | import dev.inmo.micro_utils.pagination.* | ||||||
| import dev.inmo.micro_utils.repos.* | import dev.inmo.micro_utils.repos.* | ||||||
| import dev.inmo.micro_utils.repos.cache.cache.KVCache | 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.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
| import kotlinx.coroutines.flow.* | import kotlinx.coroutines.flow.* | ||||||
| @@ -48,9 +49,7 @@ open class ReadKeyValueCacheRepo<Key,Value>( | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override suspend fun invalidate() = locker.withWriteLock { |     override suspend fun invalidate() = kvCache.actualizeAll(parentRepo, locker = locker) | ||||||
|         kvCache.clear() |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fun <Key, Value> ReadKeyValueRepo<Key, Value>.cached( | fun <Key, Value> ReadKeyValueRepo<Key, Value>.cached( | ||||||
| @@ -75,10 +74,6 @@ open class KeyValueCacheRepo<Key,Value>( | |||||||
|         } |         } | ||||||
|     }.launchIn(scope) |     }.launchIn(scope) | ||||||
|  |  | ||||||
|     override suspend fun invalidate() = locker.withWriteLock { |  | ||||||
|         kvCache.clear() |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     override suspend fun clear() { |     override suspend fun clear() { | ||||||
|         parentRepo.clear() |         parentRepo.clear() | ||||||
|         locker.withWriteLock { |         locker.withWriteLock { | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ import dev.inmo.micro_utils.pagination.* | |||||||
| import dev.inmo.micro_utils.pagination.utils.* | import dev.inmo.micro_utils.pagination.utils.* | ||||||
| import dev.inmo.micro_utils.repos.* | import dev.inmo.micro_utils.repos.* | ||||||
| import dev.inmo.micro_utils.repos.cache.cache.KVCache | 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.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
| import kotlinx.coroutines.flow.* | import kotlinx.coroutines.flow.* | ||||||
| @@ -47,9 +48,7 @@ open class ReadKeyValuesCacheRepo<Key,Value>( | |||||||
|         kvCache.contains(k) |         kvCache.contains(k) | ||||||
|     } || parentRepo.contains(k) |     } || parentRepo.contains(k) | ||||||
|  |  | ||||||
|     override suspend fun invalidate() = locker.withWriteLock { |     override suspend fun invalidate() = kvCache.actualizeAll(parentRepo, locker = locker) | ||||||
|         kvCache.clear() |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fun <Key, Value> ReadKeyValuesRepo<Key, Value>.cached( | fun <Key, Value> ReadKeyValuesRepo<Key, Value>.cached( | ||||||
| @@ -84,10 +83,6 @@ open class KeyValuesCacheRepo<Key,Value>( | |||||||
|             kvCache.unset(it) |             kvCache.unset(it) | ||||||
|         } |         } | ||||||
|     }.launchIn(scope) |     }.launchIn(scope) | ||||||
|  |  | ||||||
|     override suspend fun invalidate() = locker.withWriteLock { |  | ||||||
|         kvCache.clear() |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fun <Key, Value> KeyValuesRepo<Key, Value>.cached( | fun <Key, Value> KeyValuesRepo<Key, Value>.cached( | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import dev.inmo.micro_utils.repos.ReadCRUDRepo | |||||||
| import dev.inmo.micro_utils.repos.cache.fallback.ActionWrapper | import dev.inmo.micro_utils.repos.cache.fallback.ActionWrapper | ||||||
| import dev.inmo.micro_utils.repos.cache.util.actualizeAll | import dev.inmo.micro_utils.repos.cache.util.actualizeAll | ||||||
| import dev.inmo.micro_utils.repos.cache.FallbackCacheRepo | import dev.inmo.micro_utils.repos.cache.FallbackCacheRepo | ||||||
|  | import dev.inmo.micro_utils.repos.cache.util.ActualizeAllClearMode | ||||||
| import dev.inmo.micro_utils.repos.set | import dev.inmo.micro_utils.repos.set | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.delay | import kotlinx.coroutines.delay | ||||||
| @@ -56,7 +57,7 @@ open class AutoRecacheReadCRUDRepo<RegisteredObject, Id>( | |||||||
|     override suspend fun getAll(): Map<Id, RegisteredObject> = actionWrapper.wrap { |     override suspend fun getAll(): Map<Id, RegisteredObject> = actionWrapper.wrap { | ||||||
|         originalRepo.getAll() |         originalRepo.getAll() | ||||||
|     }.onSuccess { |     }.onSuccess { | ||||||
|         kvCache.actualizeAll(clear = true) { it } |         kvCache.actualizeAll(clearMode = ActualizeAllClearMode.BeforeSet) { it } | ||||||
|     }.getOrElse { |     }.getOrElse { | ||||||
|         kvCache.getAll() |         kvCache.getAll() | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import dev.inmo.micro_utils.repos.ReadKeyValueRepo | |||||||
| import dev.inmo.micro_utils.repos.cache.fallback.ActionWrapper | import dev.inmo.micro_utils.repos.cache.fallback.ActionWrapper | ||||||
| import dev.inmo.micro_utils.repos.cache.util.actualizeAll | import dev.inmo.micro_utils.repos.cache.util.actualizeAll | ||||||
| import dev.inmo.micro_utils.repos.cache.FallbackCacheRepo | import dev.inmo.micro_utils.repos.cache.FallbackCacheRepo | ||||||
|  | import dev.inmo.micro_utils.repos.cache.util.ActualizeAllClearMode | ||||||
| import dev.inmo.micro_utils.repos.set | import dev.inmo.micro_utils.repos.set | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.delay | import kotlinx.coroutines.delay | ||||||
| @@ -56,7 +57,7 @@ open class AutoRecacheReadKeyValueRepo<Id, RegisteredObject>( | |||||||
|     override suspend fun getAll(): Map<Id, RegisteredObject> = actionWrapper.wrap { |     override suspend fun getAll(): Map<Id, RegisteredObject> = actionWrapper.wrap { | ||||||
|         originalRepo.getAll() |         originalRepo.getAll() | ||||||
|     }.onSuccess { |     }.onSuccess { | ||||||
|         kvCache.actualizeAll(clear = true) { it } |         kvCache.actualizeAll(clearMode = ActualizeAllClearMode.BeforeSet) { it } | ||||||
|     }.getOrElse { |     }.getOrElse { | ||||||
|         kvCache.getAll() |         kvCache.getAll() | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import dev.inmo.micro_utils.pagination.Pagination | |||||||
| import dev.inmo.micro_utils.pagination.PaginationResult | import dev.inmo.micro_utils.pagination.PaginationResult | ||||||
| import dev.inmo.micro_utils.repos.* | import dev.inmo.micro_utils.repos.* | ||||||
| import dev.inmo.micro_utils.repos.cache.* | import dev.inmo.micro_utils.repos.cache.* | ||||||
|  | import dev.inmo.micro_utils.repos.cache.util.ActualizeAllClearMode | ||||||
| import dev.inmo.micro_utils.repos.cache.util.actualizeAll | import dev.inmo.micro_utils.repos.cache.util.actualizeAll | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
| @@ -42,7 +43,7 @@ open class FullReadCRUDCacheRepo<ObjectType, IdType>( | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     protected open suspend fun actualizeAll() { |     protected open suspend fun actualizeAll() { | ||||||
|         locker.withWriteLock { kvCache.actualizeAll(parentRepo) } |         kvCache.actualizeAll(parentRepo, locker = locker) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> = doOrTakeAndActualize( |     override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> = doOrTakeAndActualize( | ||||||
| @@ -72,7 +73,7 @@ open class FullReadCRUDCacheRepo<ObjectType, IdType>( | |||||||
|     override suspend fun getAll(): Map<IdType, ObjectType> = doOrTakeAndActualizeWithWriteLock( |     override suspend fun getAll(): Map<IdType, ObjectType> = doOrTakeAndActualizeWithWriteLock( | ||||||
|         { getAll().takeIf { it.isNotEmpty() }.optionalOrAbsentIfNull }, |         { getAll().takeIf { it.isNotEmpty() }.optionalOrAbsentIfNull }, | ||||||
|         { getAll() }, |         { getAll() }, | ||||||
|         { kvCache.actualizeAll(clear = true) { it } } |         { kvCache.actualizeAll(clearMode = ActualizeAllClearMode.BeforeSet) { it } } | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     override suspend fun getById(id: IdType): ObjectType? = doOrTakeAndActualizeWithWriteLock( |     override suspend fun getById(id: IdType): ObjectType? = doOrTakeAndActualizeWithWriteLock( | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ import dev.inmo.micro_utils.coroutines.withWriteLock | |||||||
| import dev.inmo.micro_utils.pagination.Pagination | import dev.inmo.micro_utils.pagination.Pagination | ||||||
| import dev.inmo.micro_utils.pagination.PaginationResult | import dev.inmo.micro_utils.pagination.PaginationResult | ||||||
| import dev.inmo.micro_utils.repos.* | import dev.inmo.micro_utils.repos.* | ||||||
|  | import dev.inmo.micro_utils.repos.cache.util.ActualizeAllClearMode | ||||||
| import dev.inmo.micro_utils.repos.cache.util.actualizeAll | import dev.inmo.micro_utils.repos.cache.util.actualizeAll | ||||||
| import dev.inmo.micro_utils.repos.pagination.getAll |  | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
| import kotlinx.coroutines.flow.* | import kotlinx.coroutines.flow.* | ||||||
| @@ -41,10 +41,7 @@ open class FullReadKeyValueCacheRepo<Key,Value>( | |||||||
|         actualize = { locker.withWriteLock { actualize(it) } } |         actualize = { locker.withWriteLock { actualize(it) } } | ||||||
|     ) |     ) | ||||||
|     protected open suspend fun actualizeAll() { |     protected open suspend fun actualizeAll() { | ||||||
|         locker.withWriteLock { |         kvCache.actualizeAll(parentRepo, locker) | ||||||
|             kvCache.clear() |  | ||||||
|             kvCache.set(parentRepo.getAll()) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override suspend fun get(k: Key): Value? = doOrTakeAndActualizeWithWriteLock( |     override suspend fun get(k: Key): Value? = doOrTakeAndActualizeWithWriteLock( | ||||||
| @@ -74,7 +71,7 @@ open class FullReadKeyValueCacheRepo<Key,Value>( | |||||||
|     override suspend fun getAll(): Map<Key, Value> = doOrTakeAndActualizeWithWriteLock( |     override suspend fun getAll(): Map<Key, Value> = doOrTakeAndActualizeWithWriteLock( | ||||||
|         { getAll().takeIf { it.isNotEmpty() }.optionalOrAbsentIfNull }, |         { getAll().takeIf { it.isNotEmpty() }.optionalOrAbsentIfNull }, | ||||||
|         { getAll() }, |         { getAll() }, | ||||||
|         { kvCache.actualizeAll(clear = true) { it } } |         { kvCache.actualizeAll(clearMode = ActualizeAllClearMode.BeforeSet) { it } } | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = doOrTakeAndActualize( |     override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = doOrTakeAndActualize( | ||||||
| @@ -150,9 +147,7 @@ open class FullKeyValueCacheRepo<Key,Value>( | |||||||
|     override suspend fun unsetWithValues(toUnset: List<Value>) = parentRepo.unsetWithValues(toUnset) |     override suspend fun unsetWithValues(toUnset: List<Value>) = parentRepo.unsetWithValues(toUnset) | ||||||
|  |  | ||||||
|     override suspend fun invalidate() { |     override suspend fun invalidate() { | ||||||
|         locker.withWriteLock { |         kvCache.actualizeAll(parentRepo, locker) | ||||||
|             kvCache.actualizeAll(parentRepo) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override suspend fun clear() { |     override suspend fun clear() { | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import dev.inmo.micro_utils.coroutines.withWriteLock | |||||||
| import dev.inmo.micro_utils.pagination.* | import dev.inmo.micro_utils.pagination.* | ||||||
| import dev.inmo.micro_utils.pagination.utils.* | import dev.inmo.micro_utils.pagination.utils.* | ||||||
| import dev.inmo.micro_utils.repos.* | import dev.inmo.micro_utils.repos.* | ||||||
|  | import dev.inmo.micro_utils.repos.cache.util.ActualizeAllClearMode | ||||||
| import dev.inmo.micro_utils.repos.cache.util.actualizeAll | import dev.inmo.micro_utils.repos.cache.util.actualizeAll | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
| @@ -41,15 +42,13 @@ open class FullReadKeyValuesCacheRepo<Key,Value>( | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     protected open suspend fun actualizeKey(k: Key) { |     protected open suspend fun actualizeKey(k: Key) { | ||||||
|         locker.withWriteLock { |         kvCache.actualizeAll(locker = locker, clearMode = ActualizeAllClearMode.Never) { | ||||||
|             kvCache.set(k, parentRepo.getAll(k)) |             mapOf(k to parentRepo.getAll(k)) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected open suspend fun actualizeAll() { |     protected open suspend fun actualizeAll() { | ||||||
|         locker.withWriteLock { |         kvCache.actualizeAll(parentRepo, locker = locker) | ||||||
|             kvCache.actualizeAll(parentRepo) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> { |     override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> { | ||||||
| @@ -187,9 +186,11 @@ open class FullKeyValuesCacheRepo<Key,Value>( | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     override suspend fun invalidate() { |     override suspend fun invalidate() { | ||||||
|         locker.withWriteLock { |         kvCache.actualizeAll(parentRepo, locker = locker) | ||||||
|             kvCache.actualizeAll(parentRepo) |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     override suspend fun set(toSet: Map<Key, List<Value>>) { | ||||||
|  |         super<KeyValuesRepo>.set(toSet) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override suspend fun removeWithValue(v: Value) { |     override suspend fun removeWithValue(v: Value) { | ||||||
|   | |||||||
| @@ -1,43 +1,169 @@ | |||||||
| package dev.inmo.micro_utils.repos.cache.util | package dev.inmo.micro_utils.repos.cache.util | ||||||
|  |  | ||||||
|  | import dev.inmo.micro_utils.coroutines.SmartRWLocker | ||||||
|  | import dev.inmo.micro_utils.coroutines.withWriteLock | ||||||
| import dev.inmo.micro_utils.repos.* | import dev.inmo.micro_utils.repos.* | ||||||
|  | import kotlinx.serialization.Serializable | ||||||
|  | import kotlin.js.JsName | ||||||
|  | import kotlin.jvm.JvmName | ||||||
|  |  | ||||||
| suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAll( | /** | ||||||
|     clear: Boolean = true, |  * `invalidate`/`actualizeAll` clearing mode. Declare when data in original repo will be cleared | ||||||
|  |  */ | ||||||
|  | @Serializable | ||||||
|  | sealed interface ActualizeAllClearMode { | ||||||
|  |     /** | ||||||
|  |      * Instruct user of this mode to clear internal data __before load__ of external data | ||||||
|  |      */ | ||||||
|  |     @Serializable | ||||||
|  |     data object BeforeLoad : ActualizeAllClearMode | ||||||
|  |     /** | ||||||
|  |      * Instruct user of this mode to clear internal data __after load__ of external data and __before set__ of internal data | ||||||
|  |      */ | ||||||
|  |     @Serializable | ||||||
|  |     data object BeforeSet : ActualizeAllClearMode | ||||||
|  |     /** | ||||||
|  |      * Instruct user of this mode to never clear internal data | ||||||
|  |      */ | ||||||
|  |     @Serializable | ||||||
|  |     data object Never : ActualizeAllClearMode | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithClearBeforeLoad( | ||||||
|     getAll: () -> Map<K, V> |     getAll: () -> Map<K, V> | ||||||
| ) { | ) { | ||||||
|     set( |     clear() | ||||||
|         getAll().also { |     val newData = getAll() | ||||||
|             if (clear) { |     set(newData) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithClearBeforeSet( | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     val newData = getAll() | ||||||
|  |     clear() | ||||||
|  |     set(newData) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithoutClear( | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     val newData = getAll() | ||||||
|  |     set(newData) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @JvmName("actualizeAllWithClearBeforeLoadWithLocker") | ||||||
|  | @JsName("actualizeAllWithClearBeforeLoadWithLocker") | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithClearBeforeLoad( | ||||||
|  |     locker: SmartRWLocker, | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     locker.withWriteLock { | ||||||
|         clear() |         clear() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     val newData = getAll() | ||||||
|  |     locker.withWriteLock { | ||||||
|  |         set(newData) | ||||||
|     } |     } | ||||||
|     ) | } | ||||||
|  |  | ||||||
|  | @JvmName("actualizeAllWithClearBeforeSetWithLocker") | ||||||
|  | @JsName("actualizeAllWithClearBeforeSetWithLocker") | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithClearBeforeSet( | ||||||
|  |     locker: SmartRWLocker, | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     val newData = getAll() | ||||||
|  |     locker.withWriteLock { | ||||||
|  |         clear() | ||||||
|  |         set(newData) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @JvmName("actualizeAllWithoutClearWithLocker") | ||||||
|  | @JsName("actualizeAllWithoutClearWithLocker") | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithoutClear( | ||||||
|  |     locker: SmartRWLocker, | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     val newData = getAll() | ||||||
|  |     locker.withWriteLock { | ||||||
|  |         set(newData) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithClearBeforeLoad( | ||||||
|  |     locker: SmartRWLocker? = null, | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     locker ?.let { | ||||||
|  |         actualizeAllWithClearBeforeLoad(locker = locker, getAll) | ||||||
|  |     } ?: actualizeAllWithClearBeforeLoad(getAll) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithClearBeforeSet( | ||||||
|  |     locker: SmartRWLocker? = null, | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     locker ?.let { | ||||||
|  |         actualizeAllWithClearBeforeSet(locker = locker, getAll) | ||||||
|  |     } ?: actualizeAllWithClearBeforeSet(getAll) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAllWithoutClear( | ||||||
|  |     locker: SmartRWLocker? = null, | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
|  | ) { | ||||||
|  |     locker ?.let { | ||||||
|  |         actualizeAllWithoutClear(locker = locker, getAll) | ||||||
|  |     } ?: actualizeAllWithoutClear(getAll) | ||||||
| } | } | ||||||
|  |  | ||||||
| suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAll( | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAll( | ||||||
|     repo: ReadKeyValueRepo<K, V>, |     locker: SmartRWLocker? = null, | ||||||
|     clear: Boolean = true, |     clearMode: ActualizeAllClearMode = ActualizeAllClearMode.BeforeSet, | ||||||
|  |     getAll: () -> Map<K, V> | ||||||
| ) { | ) { | ||||||
|     actualizeAll(clear) { |     when (clearMode) { | ||||||
|         repo.getAll() |         ActualizeAllClearMode.BeforeLoad -> locker ?.let { | ||||||
|  |             actualizeAllWithClearBeforeLoad(locker = locker, getAll) | ||||||
|  |         } ?: actualizeAllWithClearBeforeLoad(getAll) | ||||||
|  |         ActualizeAllClearMode.BeforeSet -> locker ?.let { | ||||||
|  |             actualizeAllWithClearBeforeSet(locker = locker, getAll) | ||||||
|  |         } ?: actualizeAllWithClearBeforeSet(getAll) | ||||||
|  |         ActualizeAllClearMode.Never -> locker ?.let { | ||||||
|  |             actualizeAllWithoutClear(locker = locker, getAll) | ||||||
|  |         } ?: actualizeAllWithoutClear(getAll) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAll( | ||||||
|  |     parentRepo: ReadKeyValueRepo<K, V>, | ||||||
|  |     locker: SmartRWLocker? = null, | ||||||
|  |     clearMode: ActualizeAllClearMode = ActualizeAllClearMode.BeforeSet, | ||||||
|  | ) { | ||||||
|  |     actualizeAll(locker, clearMode) { | ||||||
|  |         parentRepo.getAll() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| suspend inline fun <K, V> KeyValueRepo<K, List<V>>.actualizeAll( | suspend inline fun <K, V> KeyValueRepo<K, List<V>>.actualizeAll( | ||||||
|     repo: ReadKeyValuesRepo<K, V>, |     parentRepo: ReadKeyValuesRepo<K, V>, | ||||||
|     clear: Boolean = true, |     locker: SmartRWLocker? = null, | ||||||
|  |     clearMode: ActualizeAllClearMode = ActualizeAllClearMode.BeforeSet, | ||||||
| ) { | ) { | ||||||
|     actualizeAll(clear) { |     actualizeAll(locker, clearMode) { | ||||||
|         repo.getAll() |         parentRepo.getAll() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAll( | suspend inline fun <K, V> KeyValueRepo<K, V>.actualizeAll( | ||||||
|     repo: ReadCRUDRepo<V, K>, |     parentRepo: ReadCRUDRepo<V, K>, | ||||||
|     clear: Boolean = true, |     locker: SmartRWLocker? = null, | ||||||
|  |     clearMode: ActualizeAllClearMode = ActualizeAllClearMode.BeforeSet, | ||||||
| ) { | ) { | ||||||
|     actualizeAll(clear) { |     actualizeAll(locker, clearMode) { | ||||||
|         repo.getAll() |         parentRepo.getAll() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| package dev.inmo.micro_utils.repos | package dev.inmo.micro_utils.repos | ||||||
|  |  | ||||||
|  | import dev.inmo.micro_utils.common.diff | ||||||
| import dev.inmo.micro_utils.pagination.* | import dev.inmo.micro_utils.pagination.* | ||||||
| import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging | import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging | ||||||
| import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging | import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging | ||||||
| @@ -130,6 +131,14 @@ interface KeyValuesRepo<Key, Value> : ReadKeyValuesRepo<Key, Value>, WriteKeyVal | |||||||
|  |  | ||||||
|         remove(toRemove) |         remove(toRemove) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     override suspend fun set(toSet: Map<Key, List<Value>>) { | ||||||
|  |         toSet.forEach { (k, v) -> | ||||||
|  |             val diff = getAll(k).diff(v) | ||||||
|  |             remove(k, diff.removed.map { it.value }) | ||||||
|  |             add(k, diff.added.map { it.value }) | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| typealias OneToManyKeyValueRepo<Key,Value> = KeyValuesRepo<Key, Value> | typealias OneToManyKeyValueRepo<Key,Value> = KeyValuesRepo<Key, Value> | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user