From 87a3a925ee6cc81b81a3f2b0790048fef97c0f38 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 24 Mar 2025 13:36:04 +0600 Subject: [PATCH] add multilocking for key-based lockers --- .../coroutines/SmartKeyRWLocker.kt | 41 +++++++++++++++++++ .../cache/full/FullKeyValuesCacheRepo.kt | 1 - .../direct/DirectFullKeyValueCacheRepo.kt | 3 -- .../direct/DirectFullKeyValuesCacheRepo.kt | 1 - 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt index ac296566760..017e1c5009f 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt @@ -152,6 +152,27 @@ suspend inline fun SmartKeyRWLocker.withReadAcquire(key: T, action: () } } +@OptIn(ExperimentalContracts::class) +suspend inline fun SmartKeyRWLocker.withReadAcquires(keys: Iterable, action: () -> R): R { + contract { + callsInPlace(action, InvocationKind.EXACTLY_ONCE) + } + + val acquired = mutableSetOf() + try { + keys.forEach { + acquireRead(it) + acquired.add(it) + } + return action() + } finally { + acquired.forEach { + releaseRead(it) + } + } +} +suspend inline fun SmartKeyRWLocker.withReadAcquires(vararg keys: T, action: () -> R): R = withReadAcquires(keys.asIterable(), action) + @OptIn(ExperimentalContracts::class) suspend inline fun SmartKeyRWLocker.withWriteLock(key: T, action: () -> R): R { contract { @@ -164,4 +185,24 @@ suspend inline fun SmartKeyRWLocker.withWriteLock(key: T, action: () - } finally { unlockWrite(key) } +} + +@OptIn(ExperimentalContracts::class) +suspend inline fun SmartKeyRWLocker.withWriteLocks(keys: Iterable, action: () -> R): R { + contract { + callsInPlace(action, InvocationKind.EXACTLY_ONCE) + } + + val locked = mutableSetOf() + try { + keys.forEach { + lockWrite(it) + locked.add(it) + } + return action() + } finally { + locked.forEach { + unlockWrite(it) + } + } } \ No newline at end of file diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt index 524afa732c8..e6cc8f73317 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt @@ -11,7 +11,6 @@ import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.annotations.OverrideRequireManualInvalidation import dev.inmo.micro_utils.repos.cache.util.ActualizeAllClearMode import dev.inmo.micro_utils.repos.cache.util.actualizeAll -import dev.inmo.micro_utils.repos.pagination.maxPagePagination import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.* diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValueCacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValueCacheRepo.kt index 099d2b71d03..e257ec5c84e 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValueCacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValueCacheRepo.kt @@ -8,9 +8,6 @@ import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.PaginationResult import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.annotations.OverrideRequireManualInvalidation -import dev.inmo.micro_utils.repos.cache.full.FullKeyValueCacheRepo -import dev.inmo.micro_utils.repos.cache.full.FullReadKeyValueCacheRepo -import dev.inmo.micro_utils.repos.cache.full.FullWriteKeyValueCacheRepo import dev.inmo.micro_utils.repos.cache.util.actualizeAll import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValuesCacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValuesCacheRepo.kt index c4d3d827446..7829fd7520a 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValuesCacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/direct/DirectFullKeyValuesCacheRepo.kt @@ -1,6 +1,5 @@ package dev.inmo.micro_utils.repos.cache.full.direct -import dev.inmo.micro_utils.common.* import dev.inmo.micro_utils.coroutines.SmartRWLocker import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions import dev.inmo.micro_utils.coroutines.withReadAcquire