[fleet] rename multiplatform ConcurrentHashMap

Renaming will prevent misuse of multiplatform collection in non-fleet projects.

GitOrigin-RevId: 50e78f7240be32ef71207a7ae50e4aa485f217ac
This commit is contained in:
Alexander Zolotov
2025-11-08 18:46:14 +00:00
committed by intellij-monorepo-bot
parent dedc339a98
commit 44816cafd8
12 changed files with 94 additions and 36 deletions
@@ -1,12 +1,12 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package fleet.kernel.rebase
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
internal class Memoizer<T> {
data class WithEpoch<T>(val value: T, val epoch: Int)
private val m = ConcurrentHashMap<Any, WithEpoch<T>>()
private val m = MultiplatformConcurrentHashMap<Any, WithEpoch<T>>()
private var epoch: Int = 0
fun nextEpoch() {
@@ -1,7 +1,7 @@
package com.jetbrains.lsp.implementation
import com.jetbrains.lsp.protocol.*
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
import fleet.util.logging.logger
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.ReceiveChannel
@@ -41,7 +41,7 @@ suspend fun withLsp(
body: suspend CoroutineScope.(LspClient) -> Unit,
) {
coroutineScope {
val outgoingRequests = ConcurrentHashMap<StringOrInt, OutgoingRequest>()
val outgoingRequests = MultiplatformConcurrentHashMap<StringOrInt, OutgoingRequest>()
val idGen = AtomicInt(0)
val lspClient = object : LspClient {
override suspend fun <Params, Result, Error> request(
@@ -104,7 +104,7 @@ suspend fun withLsp(
launch(createCoroutineContext(lspClient)) {
withSupervisor { supervisor ->
val incomingRequestsJobs = ConcurrentHashMap<StringOrInt, Job>()
val incomingRequestsJobs = MultiplatformConcurrentHashMap<StringOrInt, Job>()
incoming.consumeEach { jsonMessage ->
when {
jsonMessage !is JsonObject || jsonMessage["jsonrpc"] != JsonPrimitive("2.0") -> {
@@ -6,11 +6,11 @@ import fleet.util.multiplatform.linkToActual
/**
* On JVM, this is a wrapper for [java.util.concurrent.ConcurrentHashMap]
*
* @see [ConcurrentHashMapJvm] and [ConcurrentHashMapWasmJs] actual implementations
* @see [MultiplatformMultiplatformConcurrentHashMapJvmImpl] and [MultiplatformConcurrentHashMapWasmJsImpl] actual implementations
*/
fun <K, V> ConcurrentHashMap(): ConcurrentHashMap<K, V> = linkToActual()
fun <K, V> MultiplatformConcurrentHashMap(): MultiplatformConcurrentHashMap<K, V> = linkToActual()
interface ConcurrentHashMap<K, V>: MutableMap<K, V> {
interface MultiplatformConcurrentHashMap<K, V>: MutableMap<K, V> {
fun putIfAbsent(key: K, value: V): V?
fun computeIfAbsent(key: K, f: (K) -> V): V
@@ -0,0 +1,58 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package fleet.multiplatform.shims
import java.util.concurrent.ConcurrentHashMap as JavaConcurrentHashMap
/**
* @deprecated Use [java.util.concurrent.ConcurrentHashMap]
*
* Factory method is not supposed to be used outside the KMP context.
*
* Moreover, using it may lead to quite tricky bugs while using extension methods on MutableMap,
* that are not ready for concurrent execution, instead of the one defined on ConcurrentHashMap (e.g. `getOrPut function)
*/
@Deprecated("Use ConcurrentHashMap from java.util.concurrent", ReplaceWith("ConcurrentHashMap<K, V>()", "java.util.concurrent.ConcurrentHashMap"))
fun <K, V> ConcurrentHashMap(): ConcurrentHashMap<K, V> = ConcurrentHashMapImpl<K, V>(JavaConcurrentHashMap<K, V>())
/**
* @deprecated Use [java.util.concurrent.ConcurrentHashMap]
*
* Interface is not supposed to be used outside the KMP context.
*
* Moreover, using it may lead to quite tricky bugs while using extension methods on MutableMap,
* that are not ready for concurrent execution, instead of the one defined on ConcurrentHashMap (e.g. `getOrPut function)
*/
@Deprecated("Use ConcurrentHashMap from java.util.concurrent", ReplaceWith("ConcurrentHashMap<K, V>", "java.util.concurrent.ConcurrentHashMap"))
interface ConcurrentHashMap<K, V> : MutableMap<K, V> {
fun putIfAbsent(key: K, value: V): V?
fun computeIfAbsent(key: K, f: (K) -> V): V
fun computeIfPresent(key: K, f: (K, V) -> V): V?
fun compute(key: K, f: (K, V?) -> V?): V?
fun remove(key: K, value: V): Boolean
}
private class ConcurrentHashMapImpl<K, V>(private val hashMap: JavaConcurrentHashMap<K, V>) : MutableMap<K, V> by hashMap, ConcurrentHashMap<K, V> {
override fun remove(key: K, value: V): Boolean {
return hashMap.remove(key, value)
}
override fun putIfAbsent(key: K, value: V): V? {
return hashMap.putIfAbsent(key, value)
}
override fun computeIfAbsent(key: K, f: (K) -> V): V {
return hashMap.computeIfAbsent(key, f)
}
override fun computeIfPresent(key: K, f: (K, V) -> V): V? {
return hashMap.computeIfPresent(key, f)
}
override fun compute(key: K, f: (K, V?) -> V?): V? {
return hashMap.compute(key, f)
}
}
@@ -6,9 +6,9 @@ import fleet.util.multiplatform.Actual
import java.util.concurrent.ConcurrentHashMap as JavaConcurrentHashMap
@Actual
internal fun <K, V> ConcurrentHashMapJvm(): ConcurrentHashMap<K, V> = MultiplatformConcurrentHashMap(JavaConcurrentHashMap())
internal fun <K, V> MultiplatformConcurrentHashMapJvm(): MultiplatformConcurrentHashMap<K, V> = MultiplatformMultiplatformConcurrentHashMapJvmImpl(JavaConcurrentHashMap())
private class MultiplatformConcurrentHashMap<K, V>(val hashMap: JavaConcurrentHashMap<K, V>) : MutableMap<K, V> by hashMap, ConcurrentHashMap<K, V> {
private class MultiplatformMultiplatformConcurrentHashMapJvmImpl<K, V>(val hashMap: JavaConcurrentHashMap<K, V>) : MutableMap<K, V> by hashMap, MultiplatformConcurrentHashMap<K, V> {
override fun remove(key: K, value: V): Boolean {
return hashMap.remove(key, value)
}
@@ -5,9 +5,9 @@ package fleet.multiplatform.shims
import fleet.util.multiplatform.Actual
@Actual
fun <K, V> ConcurrentHashMapWasmJs(): ConcurrentHashMap<K, V> = ConcurrentHashMapWasm(mutableMapOf())
fun <K, V> MultiplatformConcurrentHashMapWasmJs(): MultiplatformConcurrentHashMap<K, V> = MultiplatformConcurrentHashMapWasmJsImpl(mutableMapOf())
internal fun <K, V> ConcurrentHashMapWasm(base: MutableMap<K, V>): ConcurrentHashMap<K, V> = object : MutableMap<K, V> by base, ConcurrentHashMap<K, V> {
internal fun <K, V> MultiplatformConcurrentHashMapWasmJsImpl(base: MutableMap<K, V>): MultiplatformConcurrentHashMap<K, V> = object : MutableMap<K, V> by base, MultiplatformConcurrentHashMap<K, V> {
override fun putIfAbsent(key: K, value: V): V? {
return if (!containsKey(key)) {
put(key, value)
@@ -5,7 +5,7 @@ import com.jetbrains.rhizomedb.EID
import com.jetbrains.rhizomedb.MAX_PART
import com.jetbrains.rhizomedb.Part
import com.jetbrains.rhizomedb.withPart
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
import kotlin.concurrent.atomics.AtomicInt
import kotlin.concurrent.atomics.incrementAndFetch
@@ -14,7 +14,7 @@ sealed interface EidGen {
private val eidGens: Array<AtomicInt> = Array(MAX_PART + 1) { AtomicInt(0) }.also {
it[0].store(17)
}
private val eidMemo: ConcurrentHashMap<String, EID> = ConcurrentHashMap()
private val eidMemo: MultiplatformConcurrentHashMap<String, EID> = MultiplatformConcurrentHashMap()
override fun freshEID(part: Part): EID =
withPart(eidGens[part].incrementAndFetch(), part)
@@ -18,7 +18,7 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.consumeEach
import kotlinx.serialization.json.Json
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashSet
import fleet.util.async.withSupervisor
import kotlinx.serialization.builtins.serializer
@@ -33,10 +33,10 @@ class RpcExecutor private constructor(
private val rpcCallDispatcher: CoroutineDispatcher?,
) {
private val remoteObjects = ConcurrentHashMap<InstanceId, ServiceImplementation>()
private val resources = ConcurrentHashMap<InstanceId, Job>()
private val children: ConcurrentHashMap<InstanceId, Set<InstanceId>> = ConcurrentHashMap()
private val parents: ConcurrentHashMap<InstanceId, InstanceId> = ConcurrentHashMap()
private val remoteObjects = MultiplatformConcurrentHashMap<InstanceId, ServiceImplementation>()
private val resources = MultiplatformConcurrentHashMap<InstanceId, Job>()
private val children: MultiplatformConcurrentHashMap<InstanceId, Set<InstanceId>> = MultiplatformConcurrentHashMap()
private val parents: MultiplatformConcurrentHashMap<InstanceId, InstanceId> = MultiplatformConcurrentHashMap()
companion object {
internal val logger = KLoggers.logger(RpcExecutor::class)
@@ -100,10 +100,10 @@ class RpcExecutor private constructor(
}
}
private val requestJobs = ConcurrentHashMap<UID, CompletableJob>()
private val routeRequests = ConcurrentHashMap<UID/*route*/, MultiplatformConcurrentHashSet<UID/*requestId*/>>()
private val channels = ConcurrentHashMap<UID, InternalStreamDescriptor>()
private val routeChannels = ConcurrentHashMap<UID/*route*/, MultiplatformConcurrentHashSet<UID/*channelId*/>>()
private val requestJobs = MultiplatformConcurrentHashMap<UID, CompletableJob>()
private val routeRequests = MultiplatformConcurrentHashMap<UID/*route*/, MultiplatformConcurrentHashSet<UID/*requestId*/>>()
private val channels = MultiplatformConcurrentHashMap<UID, InternalStreamDescriptor>()
private val routeChannels = MultiplatformConcurrentHashMap<UID/*route*/, MultiplatformConcurrentHashSet<UID/*channelId*/>>()
private suspend fun send(message: TransportMessage) {
sendSuspend(::sendAsync, message)
@@ -12,7 +12,7 @@ import kotlinx.coroutines.channels.consume
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.selects.select
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
import fleet.rpc.EndpointKind
class ServerRequestDispatcher(private val connectionListener: ConnectionListener?) : RequestDispatcher {
@@ -22,7 +22,7 @@ class ServerRequestDispatcher(private val connectionListener: ConnectionListener
}
private val bannedEndpoints = MutableStateFlow<Set<UID>>(emptySet())
private val connections = ConcurrentHashMap<UID, SendChannel<TransportMessage>>()
private val connections = MultiplatformConcurrentHashMap<UID, SendChannel<TransportMessage>>()
fun ban(route: UID) {
bannedEndpoints.update { it + route }
@@ -1,7 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package fleet.rpc.client
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
import fleet.multiplatform.shims.newSingleThreadCoroutineDispatcher
import fleet.rpc.RemoteApiDescriptor
import fleet.rpc.RemoteKind
@@ -81,13 +81,13 @@ private class RpcClient(
element.second?.invoke(RpcClientDisconnectedException("Request channel closed", null))
}
private val grayList = ConcurrentHashMap<UID, CompletableDeferred<Unit>>()
private val grayList = MultiplatformConcurrentHashMap<UID, CompletableDeferred<Unit>>()
private val outgoingRpc = ConcurrentHashMap<UID, OngoingRequest>()
private val completedRpc = ConcurrentHashMap<UID, TransferredResource>()
private val streams = ConcurrentHashMap<UID, InternalStreamDescriptor>()
private val remoteResources = ConcurrentHashMap<InstanceId, Set<Pair<InstanceId, RemoteResource>>>()
private val resourceParents = ConcurrentHashMap<InstanceId, InstanceId>()
private val outgoingRpc = MultiplatformConcurrentHashMap<UID, OngoingRequest>()
private val completedRpc = MultiplatformConcurrentHashMap<UID, TransferredResource>()
private val streams = MultiplatformConcurrentHashMap<UID, InternalStreamDescriptor>()
private val remoteResources = MultiplatformConcurrentHashMap<InstanceId, Set<Pair<InstanceId, RemoteResource>>>()
private val resourceParents = MultiplatformConcurrentHashMap<InstanceId, InstanceId>()
private val remoteObjectFactory = this.asHandlerFactory().tracing()
@@ -5,7 +5,7 @@ import fleet.rpc.RemoteApi
import fleet.rpc.RemoteApiDescriptor
import fleet.rpc.core.InstanceId
import fleet.util.UID
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
interface ProxyCache<K : Any> {
fun <T : Any> proxy(remoteApiDescriptor: RemoteApiDescriptor<*>, key: K, proxy: () -> T): T
@@ -16,7 +16,7 @@ fun <K : Any> proxyCache(): ProxyCache<K> {
data class ProxyCacheValue(val proxy: Any,
val remoteApiDescriptor: RemoteApiDescriptor<*>)
val cache = ConcurrentHashMap<K, ProxyCacheValue>()
val cache = MultiplatformConcurrentHashMap<K, ProxyCacheValue>()
return object : ProxyCache<K> {
@Suppress("UNCHECKED_CAST")
override fun <T : Any> proxy(remoteApiDescriptor: RemoteApiDescriptor<*>, key: K, proxy: () -> T): T =
@@ -14,7 +14,7 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.consumeEach
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.MultiplatformConcurrentHashMap
import fleet.multiplatform.shims.multiplatformIO
private object TcpProxy {
@@ -37,7 +37,7 @@ private fun ServerSocket.port(): Int? {
}
}
private val selectorManagers = ConcurrentHashMap<Job, ActorSelectorManager>()
private val selectorManagers = MultiplatformConcurrentHashMap<Job, ActorSelectorManager>()
@OptIn(InternalCoroutinesApi::class) // unfortunately necessary to unblock selector manager on cancellation
private fun getSelectorManager(parentJob: Job): ActorSelectorManager =