From ccde2c6a297d1d8f83e446f04f3fe0e79985fdc7 Mon Sep 17 00:00:00 2001 From: Yang Date: Sun, 30 Apr 2023 13:43:02 +1000 Subject: [PATCH] Use `ConcurrentHashMap` for JVM target. --- cache4k/build.gradle.kts | 3 +- .../cache4k/ConcurrentMutableMap.kt | 10 +++++++ .../cache4k/KeyedSynchronizer.kt | 5 ++-- .../reactivecircus/cache4k/RealCache.kt | 5 ++-- .../cache4k/ConcurrentMutableMap.kt | 29 +++++++++++++++++++ .../cache4k/ConcurrentMutableMap.kt | 29 +++++++++++++++++++ 6 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt create mode 100644 cache4k/src/jvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt create mode 100644 cache4k/src/nonJvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt diff --git a/cache4k/build.gradle.kts b/cache4k/build.gradle.kts index d0731bc..9a8e6fa 100644 --- a/cache4k/build.gradle.kts +++ b/cache4k/build.gradle.kts @@ -11,6 +11,7 @@ kotlin { implementation(libs.atomicfu) } } + val jvmMain by getting val nonJvmMain by getting { dependencies { dependsOn(commonMain) @@ -30,7 +31,7 @@ kotlin { } val jvmLincheck by getting { dependencies { - dependsOn(commonMain) + dependsOn(jvmMain) implementation(kotlin("test-junit5")) implementation(libs.lincheck) } diff --git a/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt b/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt new file mode 100644 index 0000000..bd98ee0 --- /dev/null +++ b/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt @@ -0,0 +1,10 @@ +package io.github.reactivecircus.cache4k + +internal expect class ConcurrentMutableMap() { + val size: Int + val values: Collection + operator fun get(key: Key): Value? + fun put(key: Key, value: Value): Value? + fun remove(key: Key): Value? + fun clear() +} diff --git a/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/KeyedSynchronizer.kt b/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/KeyedSynchronizer.kt index 3f7e1bc..d9f006f 100644 --- a/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/KeyedSynchronizer.kt +++ b/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/KeyedSynchronizer.kt @@ -1,6 +1,5 @@ package io.github.reactivecircus.cache4k -import co.touchlab.stately.collections.IsoMutableMap import kotlinx.atomicfu.locks.reentrantLock import kotlinx.atomicfu.locks.withLock import kotlinx.coroutines.sync.Mutex @@ -11,7 +10,7 @@ import kotlinx.coroutines.sync.withLock */ internal class KeyedSynchronizer { - private val keyBasedMutexes = IsoMutableMap() + private val keyBasedMutexes = ConcurrentMutableMap() private val mapLock = reentrantLock() @@ -40,7 +39,7 @@ internal class KeyedSynchronizer { mutexEntry.counter++ // save the lock entry to the map if it has just been created if (keyBasedMutexes[key] == null) { - keyBasedMutexes[key] = mutexEntry + keyBasedMutexes.put(key, mutexEntry) } return mutexEntry.mutex diff --git a/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/RealCache.kt b/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/RealCache.kt index 08e6b5b..48e2541 100644 --- a/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/RealCache.kt +++ b/cache4k/src/commonMain/kotlin/io/github/reactivecircus/cache4k/RealCache.kt @@ -1,6 +1,5 @@ package io.github.reactivecircus.cache4k -import co.touchlab.stately.collections.IsoMutableMap import co.touchlab.stately.collections.IsoMutableSet import kotlinx.atomicfu.AtomicRef import kotlinx.atomicfu.atomic @@ -38,7 +37,7 @@ internal class RealCache( private val eventListener: CacheEventListener?, ) : Cache { - private val cacheEntries = IsoMutableMap>() + private val cacheEntries = ConcurrentMutableMap>() /** * Whether to perform size based evictions. @@ -138,7 +137,7 @@ internal class RealCache( writeTimeMark = atomic(nowTimeMark), ) recordWrite(newEntry) - cacheEntries[key] = newEntry + cacheEntries.put(key, newEntry) } onEvent( oldValue?.let { diff --git a/cache4k/src/jvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt b/cache4k/src/jvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt new file mode 100644 index 0000000..40ee1e5 --- /dev/null +++ b/cache4k/src/jvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt @@ -0,0 +1,29 @@ +package io.github.reactivecircus.cache4k + +import java.util.concurrent.ConcurrentHashMap + +internal actual class ConcurrentMutableMap { + private val map = ConcurrentHashMap() + + actual val size: Int + get() = map.size + + actual val values: Collection + get() = map.values + + actual operator fun get(key: Key): Value? { + return map[key] + } + + actual fun put(key: Key, value: Value): Value? { + return map.put(key, value) + } + + actual fun remove(key: Key): Value? { + return map.remove(key) + } + + actual fun clear() { + map.clear() + } +} diff --git a/cache4k/src/nonJvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt b/cache4k/src/nonJvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt new file mode 100644 index 0000000..a43c0c2 --- /dev/null +++ b/cache4k/src/nonJvmMain/kotlin/io/github/reactivecircus/cache4k/ConcurrentMutableMap.kt @@ -0,0 +1,29 @@ +package io.github.reactivecircus.cache4k + +import co.touchlab.stately.collections.IsoMutableMap + +internal actual class ConcurrentMutableMap { + private val map = IsoMutableMap() + + actual val size: Int + get() = map.size + + actual val values: Collection + get() = map.values + + actual operator fun get(key: Key): Value? { + return map[key] + } + + actual fun put(key: Key, value: Value): Value? { + return map.put(key, value) + } + + actual fun remove(key: Key): Value? { + return map.remove(key) + } + + actual fun clear() { + map.clear() + } +}