diff --git a/.idea/modules.xml b/.idea/modules.xml
index b39b2d000b72..7fc95d05d318 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -1164,6 +1164,8 @@
+
+
diff --git a/platform/editor/backend/BUILD.bazel b/platform/editor/backend/BUILD.bazel
index 40bfba7b4cdf..d8fbf4dcc8fd 100644
--- a/platform/editor/backend/BUILD.bazel
+++ b/platform/editor/backend/BUILD.bazel
@@ -24,11 +24,6 @@ jvm_library(
"//platform/util/coroutines",
"//platform/kernel/shared:kernel",
"//platform/kernel/pasta",
- "//platform/project/shared:project",
- "@lib//:kotlinx-serialization-json",
- "@lib//:kotlinx-serialization-core",
- "//platform/util/concurrency",
- "//platform/kernel/backend",
],
runtime_deps = [":backend_resources"]
)
diff --git a/platform/editor/backend/intellij.platform.editor.backend.iml b/platform/editor/backend/intellij.platform.editor.backend.iml
index c7e298f4f002..7737a7a36f63 100644
--- a/platform/editor/backend/intellij.platform.editor.backend.iml
+++ b/platform/editor/backend/intellij.platform.editor.backend.iml
@@ -1,31 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar
- $MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar
- $MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar
-
-
-
-
-
-
-
-
@@ -45,10 +19,5 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/platform/editor/backend/resources/intellij.platform.editor.backend.xml b/platform/editor/backend/resources/intellij.platform.editor.backend.xml
index 5d5c62e37b82..e8afe5d8ef1a 100644
--- a/platform/editor/backend/resources/intellij.platform.editor.backend.xml
+++ b/platform/editor/backend/resources/intellij.platform.editor.backend.xml
@@ -2,12 +2,10 @@
-
-
diff --git a/platform/editor/backend/src/zombie/RemoteManagedCacheApiImpl.kt b/platform/editor/backend/src/zombie/RemoteManagedCacheApiImpl.kt
deleted file mode 100644
index 5ec64a2bef20..000000000000
--- a/platform/editor/backend/src/zombie/RemoteManagedCacheApiImpl.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.platform.editor.backend.zombie
-
-import com.intellij.concurrency.ConcurrentCollectionFactory
-import com.intellij.openapi.components.Service
-import com.intellij.openapi.components.serviceAsync
-import com.intellij.openapi.editor.impl.zombie.necropolisCacheNameAndPath
-import com.intellij.openapi.project.Project
-import com.intellij.platform.editor.zombie.rpc.CacheId
-import com.intellij.platform.editor.zombie.rpc.PrefetchedRemoteCacheValue
-import com.intellij.platform.editor.zombie.rpc.RemoteManagedCacheApi
-import com.intellij.platform.editor.zombie.rpc.RemoteManagedCacheDto
-import com.intellij.platform.project.findProjectOrNull
-import com.intellij.util.io.DataExternalizer
-import com.intellij.util.io.KeyDescriptor
-import com.intellij.util.io.PersistentMapBuilder
-import com.intellij.util.io.cache.ManagedCache
-import com.intellij.util.io.cache.ManagedPersistentCache
-import kotlinx.coroutines.CoroutineScope
-import java.io.DataInput
-import java.io.DataOutput
-
-@Service(Service.Level.PROJECT)
-private class RemoteManagedCacheManager(private val project: Project, private val coroutineScope: CoroutineScope) {
- private val storage = ConcurrentCollectionFactory.createConcurrentMap>()
- fun get(cacheId: CacheId): ManagedCache {
- return storage[cacheId.name]!!
- }
- suspend fun create(cacheId: CacheId): List {
- // RD and monolith caches could be handled, since Necropolis is loaded on backend too
- val (name, path) = necropolisCacheNameAndPath("${cacheId.name}-backend", project)
- val builder = PersistentMapBuilder.newBuilder(
- path,
- MyKeyDescriptor(),
- Externalizer(),
- ).withVersion(SERDE_VERSION)
- val cache = ManagedPersistentCache(name, builder, coroutineScope)
- storage[cacheId.name] = cache
- return cache.entries().map { (key, value) -> PrefetchedRemoteCacheValue(key, value) }
- }
-
- private open class Externalizer : DataExternalizer {
- override fun save(out: DataOutput, value: RemoteManagedCacheDto) {
- out.writeInt(value.data.size)
- out.write(value.data)
- }
-
- override fun read(`in`: DataInput): RemoteManagedCacheDto {
- val dataSize = `in`.readInt()
- val data = ByteArray(dataSize)
- `in`.readFully(data)
- return RemoteManagedCacheDto(data)
- }
- }
-
- private class MyKeyDescriptor : Externalizer(), KeyDescriptor {
- override fun getHashCode(value: RemoteManagedCacheDto): Int = value.data.contentHashCode()
- override fun isEqual(val1: RemoteManagedCacheDto?, val2: RemoteManagedCacheDto?): Boolean {
- return val1?.data?.contentEquals(val2?.data) ?: (val2 == null)
- }
- }
-
- companion object {
- private const val SERDE_VERSION = 1
- }
-}
-
-internal class RemoteManagedCacheApiImpl: RemoteManagedCacheApi {
- private suspend fun CacheId.cache() = projectId.findProjectOrNull()?.serviceAsync()?.get(this)
- override suspend fun get(cacheId: CacheId, key: RemoteManagedCacheDto): RemoteManagedCacheDto? {
- return cacheId.cache()?.get(key)
- }
-
- override suspend fun put(cacheId: CacheId, key: RemoteManagedCacheDto, value: RemoteManagedCacheDto?) {
- cacheId.cache()?.let {
- if (value == null) {
- it.remove(key)
- } else {
- it.put(key, value)
- }
- }
- }
-
- override suspend fun createPrefetchFlow(cacheId: CacheId): List {
- val project = cacheId.projectId.findProjectOrNull() ?: return emptyList()
- return project.serviceAsync().create(cacheId)
- }
-}
\ No newline at end of file
diff --git a/platform/editor/shared/BUILD.bazel b/platform/editor/shared/BUILD.bazel
index 1439ad9c951a..1887c4de50ee 100644
--- a/platform/editor/shared/BUILD.bazel
+++ b/platform/editor/shared/BUILD.bazel
@@ -20,7 +20,6 @@ jvm_library(
"//platform/kernel/shared:kernel",
"//platform/platform-impl:ide-impl",
"//platform/kernel/pasta",
- "//platform/project/shared:project",
],
runtime_deps = [":editor_resources"]
)
diff --git a/platform/editor/shared/intellij.platform.editor.iml b/platform/editor/shared/intellij.platform.editor.iml
index acdd6e234662..431038e4e82e 100644
--- a/platform/editor/shared/intellij.platform.editor.iml
+++ b/platform/editor/shared/intellij.platform.editor.iml
@@ -1,31 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar
- $MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar
- $MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar
-
-
-
-
-
-
-
-
@@ -41,6 +15,5 @@
-
\ No newline at end of file
diff --git a/platform/editor/shared/src/EditorEntity.kt b/platform/editor/shared/src/EditorEntity.kt
index 6a8a0a690cfc..9964e5874177 100644
--- a/platform/editor/shared/src/EditorEntity.kt
+++ b/platform/editor/shared/src/EditorEntity.kt
@@ -20,7 +20,6 @@ data class EditorEntity(override val eid: EID) : Entity {
val id: EditorId by idAttr
val clientId: ClientId by clientIdAttr
- @Internal
companion object : DurableEntityType(
EditorEntity::class.java.name,
"com.intellij.platform.editor",
diff --git a/platform/editor/shared/src/zombie/rpc/RemoteManagedCacheDto.kt b/platform/editor/shared/src/zombie/rpc/RemoteManagedCacheDto.kt
deleted file mode 100644
index 2299baf58e5e..000000000000
--- a/platform/editor/shared/src/zombie/rpc/RemoteManagedCacheDto.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.platform.editor.zombie.rpc
-
-import com.intellij.util.io.DataExternalizer
-import kotlinx.serialization.Serializable
-import org.jetbrains.annotations.ApiStatus
-import java.io.*
-
-@Serializable
-@ApiStatus.Internal
-class RemoteManagedCacheDto(
- val data: ByteArray,
-) {
- fun toValue(externalizer: DataExternalizer): V = ByteArrayInputStream(data).use {
- DataInputStream(it).use { dataInput ->
- externalizer.read(dataInput)
- }
- }
- companion object {
- fun V.fromValue(externalizer: DataExternalizer): RemoteManagedCacheDto {
- return ByteArrayOutputStream().use {bao ->
- DataOutputStream(bao).use { dataOutput: DataOutput ->
- externalizer.save(dataOutput, this)
- RemoteManagedCacheDto(bao.toByteArray())
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/platform/managed-cache/util.io.cache.backend/BUILD.bazel b/platform/managed-cache/util.io.cache.backend/BUILD.bazel
new file mode 100644
index 000000000000..d7f42b576050
--- /dev/null
+++ b/platform/managed-cache/util.io.cache.backend/BUILD.bazel
@@ -0,0 +1,30 @@
+### auto-generated section `build intellij.util.io.cache.backend` start
+load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_resources")
+
+jvm_resources(
+ name = "util.io.cache.backend_resources",
+ files = glob(["resources/**/*"]),
+ strip_prefix = "resources"
+)
+
+jvm_library(
+ name = "util.io.cache.backend",
+ module_name = "intellij.util.io.cache.backend",
+ visibility = ["//visibility:public"],
+ srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True),
+ deps = [
+ "@lib//:kotlin-stdlib",
+ "@lib//:jetbrains-annotations",
+ "//platform/kernel/backend",
+ "@lib//:kotlinx-serialization-core",
+ "@lib//:kotlinx-serialization-json",
+ "@lib//:kotlinx-coroutines-core",
+ "//platform/project/shared:project",
+ "//platform/util",
+ "//platform/platform-impl:ide-impl",
+ "//platform/managed-cache/util.io.cache",
+ "//platform/util/concurrency",
+ ],
+ runtime_deps = [":util.io.cache.backend_resources"]
+)
+### auto-generated section `build intellij.util.io.cache.backend` end
\ No newline at end of file
diff --git a/platform/managed-cache/util.io.cache.backend/intellij.util.io.cache.backend.iml b/platform/managed-cache/util.io.cache.backend/intellij.util.io.cache.backend.iml
new file mode 100644
index 000000000000..e62a33fcd448
--- /dev/null
+++ b/platform/managed-cache/util.io.cache.backend/intellij.util.io.cache.backend.iml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar
+ $MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar
+ $MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/managed-cache/util.io.cache.backend/resources/intellij.util.io.cache.backend.xml b/platform/managed-cache/util.io.cache.backend/resources/intellij.util.io.cache.backend.xml
new file mode 100644
index 000000000000..2b3d02304b1a
--- /dev/null
+++ b/platform/managed-cache/util.io.cache.backend/resources/intellij.util.io.cache.backend.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/platform/managed-cache/util.io.cache.backend/src/RemoteManagedCacheApiImpl.kt b/platform/managed-cache/util.io.cache.backend/src/RemoteManagedCacheApiImpl.kt
new file mode 100644
index 000000000000..91516bc6dc2b
--- /dev/null
+++ b/platform/managed-cache/util.io.cache.backend/src/RemoteManagedCacheApiImpl.kt
@@ -0,0 +1,89 @@
+// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.util.io.cache.backend
+
+import com.intellij.concurrency.ConcurrentCollectionFactory
+import com.intellij.openapi.application.PathManager
+import com.intellij.openapi.components.Service
+import com.intellij.openapi.components.serviceAsync
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.project.getProjectCacheFileName
+import com.intellij.platform.project.findProjectOrNull
+import com.intellij.util.io.DataExternalizer
+import com.intellij.util.io.KeyDescriptor
+import com.intellij.util.io.PersistentMapBuilder
+import com.intellij.util.io.cache.*
+import kotlinx.coroutines.CoroutineScope
+import java.io.DataInput
+import java.io.DataOutput
+import java.nio.file.Path
+
+private fun remoteCacheLocation(): Path {
+ return PathManager.getSystemDir().resolve("remote-cache")
+}
+
+@Service(Service.Level.PROJECT)
+private class RemoteManagedCacheManager(private val project: Project, private val coroutineScope: CoroutineScope) {
+ private val storage = ConcurrentCollectionFactory.createConcurrentMap>()
+ fun get(cacheId: CacheId): ManagedCache {
+ return storage[cacheId.name]!!
+ }
+ suspend fun create(cacheId: CacheId, buildParams: RemoteManagedCacheBuildParams): List {
+ val path = getCacheDir(cacheId.name, project)
+ val builder = PersistentMapBuilder.newBuilder(
+ path,
+ MyKeyDescriptor(),
+ Externalizer(),
+ ).withVersion(buildParams.serdeVersion)
+ val cache = ManagedPersistentCache(cacheId.name, builder, coroutineScope)
+ storage[cacheId.name] = cache
+ return cache.entries().map { (key, value) -> PrefetchedRemoteCacheValue(key, value) }
+ }
+
+ private fun getCacheDir(cacheName: String, project: Project): Path {
+ val projectPart = project.getProjectCacheFileName(hashSeparator = "")
+ return remoteCacheLocation().resolve("$cacheName-$projectPart").resolve(cacheName)
+ }
+
+ private open class Externalizer : DataExternalizer {
+ override fun save(out: DataOutput, value: ByteArray) {
+ out.writeInt(value.size)
+ out.write(value)
+ }
+
+ override fun read(`in`: DataInput): ByteArray {
+ val dataSize = `in`.readInt()
+ val data = ByteArray(dataSize)
+ `in`.readFully(data)
+ return data
+ }
+ }
+
+ private class MyKeyDescriptor : Externalizer(), KeyDescriptor {
+ override fun getHashCode(value: ByteArray): Int = value.contentHashCode()
+ override fun isEqual(val1: ByteArray?, val2: ByteArray?): Boolean {
+ return val1?.contentEquals(val2) ?: (val2 == null)
+ }
+ }
+}
+
+internal class RemoteManagedCacheApiImpl: RemoteManagedCacheApi {
+ private suspend fun CacheId.cache() = projectId.findProjectOrNull()?.serviceAsync()?.get(this)
+ override suspend fun get(cacheId: CacheId, key: ByteArray): ByteArray? {
+ return cacheId.cache()?.get(key)
+ }
+
+ override suspend fun put(cacheId: CacheId, key: ByteArray, value: ByteArray?) {
+ cacheId.cache()?.let {
+ if (value == null) {
+ it.remove(key)
+ } else {
+ it.put(key, value)
+ }
+ }
+ }
+
+ override suspend fun createCacheAndProvideEntries(cacheId: CacheId, buildParams: RemoteManagedCacheBuildParams): List {
+ val project = cacheId.projectId.findProjectOrNull() ?: return emptyList()
+ return project.serviceAsync().create(cacheId, buildParams)
+ }
+}
\ No newline at end of file
diff --git a/platform/editor/backend/src/zombie/RemoteManagedCacheApiImplProvider.kt b/platform/managed-cache/util.io.cache.backend/src/RemoteManagedCacheApiImplProvider.kt
similarity index 78%
rename from platform/editor/backend/src/zombie/RemoteManagedCacheApiImplProvider.kt
rename to platform/managed-cache/util.io.cache.backend/src/RemoteManagedCacheApiImplProvider.kt
index 87f37521107d..4c06c631964c 100644
--- a/platform/editor/backend/src/zombie/RemoteManagedCacheApiImplProvider.kt
+++ b/platform/managed-cache/util.io.cache.backend/src/RemoteManagedCacheApiImplProvider.kt
@@ -1,8 +1,8 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.platform.editor.backend.zombie
+package com.intellij.util.io.cache.backend
-import com.intellij.platform.editor.zombie.rpc.RemoteManagedCacheApi
import com.intellij.platform.rpc.backend.RemoteApiProvider
+import com.intellij.util.io.cache.RemoteManagedCacheApi
import fleet.rpc.remoteApiDescriptor
private class RemoteManagedCacheApiImplProvider : RemoteApiProvider {
diff --git a/platform/managed-cache/util.io.cache/BUILD.bazel b/platform/managed-cache/util.io.cache/BUILD.bazel
new file mode 100644
index 000000000000..3a156ba5d296
--- /dev/null
+++ b/platform/managed-cache/util.io.cache/BUILD.bazel
@@ -0,0 +1,26 @@
+### auto-generated section `build intellij.util.io.cache` start
+load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_resources")
+
+jvm_resources(
+ name = "util.io.cache_resources",
+ files = glob(["resources/**/*"]),
+ strip_prefix = "resources"
+)
+
+jvm_library(
+ name = "util.io.cache",
+ module_name = "intellij.util.io.cache",
+ visibility = ["//visibility:public"],
+ srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True),
+ deps = [
+ "@lib//:kotlin-stdlib",
+ "@lib//:jetbrains-annotations",
+ "//platform/kernel/shared:kernel",
+ "@lib//:kotlinx-serialization-core",
+ "@lib//:kotlinx-serialization-json",
+ "@lib//:kotlinx-coroutines-core",
+ "//platform/project/shared:project",
+ ],
+ runtime_deps = [":util.io.cache_resources"]
+)
+### auto-generated section `build intellij.util.io.cache` end
\ No newline at end of file
diff --git a/platform/managed-cache/util.io.cache/intellij.util.io.cache.iml b/platform/managed-cache/util.io.cache/intellij.util.io.cache.iml
new file mode 100644
index 000000000000..3de6d0503e2c
--- /dev/null
+++ b/platform/managed-cache/util.io.cache/intellij.util.io.cache.iml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar
+ $MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar
+ $MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/managed-cache/util.io.cache/resources/intellij.util.io.cache.xml b/platform/managed-cache/util.io.cache/resources/intellij.util.io.cache.xml
new file mode 100644
index 000000000000..164f46cfcfb2
--- /dev/null
+++ b/platform/managed-cache/util.io.cache/resources/intellij.util.io.cache.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/platform/editor/shared/src/zombie/rpc/CacheId.kt b/platform/managed-cache/util.io.cache/src/CacheId.kt
similarity index 87%
rename from platform/editor/shared/src/zombie/rpc/CacheId.kt
rename to platform/managed-cache/util.io.cache/src/CacheId.kt
index f41262791e2d..8dd90f537831 100644
--- a/platform/editor/shared/src/zombie/rpc/CacheId.kt
+++ b/platform/managed-cache/util.io.cache/src/CacheId.kt
@@ -1,5 +1,5 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.platform.editor.zombie.rpc
+package com.intellij.util.io.cache
import com.intellij.platform.project.ProjectId
import kotlinx.serialization.Serializable
diff --git a/platform/editor/shared/src/zombie/rpc/PrefetchedRemoteCacheValue.kt b/platform/managed-cache/util.io.cache/src/PrefetchedRemoteCacheValue.kt
similarity index 62%
rename from platform/editor/shared/src/zombie/rpc/PrefetchedRemoteCacheValue.kt
rename to platform/managed-cache/util.io.cache/src/PrefetchedRemoteCacheValue.kt
index 9111f212b37c..513c5424731d 100644
--- a/platform/editor/shared/src/zombie/rpc/PrefetchedRemoteCacheValue.kt
+++ b/platform/managed-cache/util.io.cache/src/PrefetchedRemoteCacheValue.kt
@@ -1,9 +1,9 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.platform.editor.zombie.rpc
+package com.intellij.util.io.cache
import kotlinx.serialization.Serializable
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
@Serializable
-class PrefetchedRemoteCacheValue(val key: RemoteManagedCacheDto, val value: RemoteManagedCacheDto)
\ No newline at end of file
+class PrefetchedRemoteCacheValue(val key: ByteArray, val value: ByteArray)
\ No newline at end of file
diff --git a/platform/editor/shared/src/zombie/rpc/RemoteManagedCacheApi.kt b/platform/managed-cache/util.io.cache/src/RemoteManagedCacheApi.kt
similarity index 60%
rename from platform/editor/shared/src/zombie/rpc/RemoteManagedCacheApi.kt
rename to platform/managed-cache/util.io.cache/src/RemoteManagedCacheApi.kt
index 3499bb9cdb09..647ab6f3d413 100644
--- a/platform/editor/shared/src/zombie/rpc/RemoteManagedCacheApi.kt
+++ b/platform/managed-cache/util.io.cache/src/RemoteManagedCacheApi.kt
@@ -1,5 +1,5 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.platform.editor.zombie.rpc
+package com.intellij.util.io.cache
import com.intellij.platform.rpc.RemoteApiProviderService
import fleet.rpc.RemoteApi
@@ -10,10 +10,10 @@ import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
@Rpc
interface RemoteManagedCacheApi : RemoteApi {
- suspend fun get(cacheId: CacheId, key: RemoteManagedCacheDto): RemoteManagedCacheDto?
- suspend fun put(cacheId: CacheId, key: RemoteManagedCacheDto, value: RemoteManagedCacheDto?)
- // Used for linearization on creation & pre-fetching
- suspend fun createPrefetchFlow(cacheId: CacheId): List
+ suspend fun get(cacheId: CacheId, key: ByteArray): ByteArray?
+ suspend fun put(cacheId: CacheId, key: ByteArray, value: ByteArray?)
+ // Used for linearization on creation and pre-fetching
+ suspend fun createCacheAndProvideEntries(cacheId: CacheId, buildParams: RemoteManagedCacheBuildParams): List
companion object {
suspend fun getInstance(): RemoteManagedCacheApi {
diff --git a/platform/platform-impl/src/com/intellij/util/io/cache/RemoteManagedCache.kt b/platform/managed-cache/util.io.cache/src/RemoteManagedCacheBuildParams.kt
similarity index 50%
rename from platform/platform-impl/src/com/intellij/util/io/cache/RemoteManagedCache.kt
rename to platform/managed-cache/util.io.cache/src/RemoteManagedCacheBuildParams.kt
index c41c2361416d..698223f8c58a 100644
--- a/platform/platform-impl/src/com/intellij/util/io/cache/RemoteManagedCache.kt
+++ b/platform/managed-cache/util.io.cache/src/RemoteManagedCacheBuildParams.kt
@@ -1,13 +1,9 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.util.io.cache
-import kotlinx.coroutines.Deferred
+import kotlinx.serialization.Serializable
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
-interface RemoteManagedCache: ManagedCache {
- /**
- * A deferred content that delivered from remote source
- */
- val preloadedContent: Deferred>>
-}
\ No newline at end of file
+@Serializable
+data class RemoteManagedCacheBuildParams(val serdeVersion: Int)
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/Necropolis.kt b/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/Necropolis.kt
index 4e4393e3d036..ff79b8d474cc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/Necropolis.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/Necropolis.kt
@@ -21,10 +21,8 @@ import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.FileIdAdapter
-import com.intellij.openapi.project.getProjectCacheFileName
import com.intellij.openapi.vfs.VirtualFile
import kotlinx.coroutines.*
-import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.TestOnly
import java.nio.file.Path
import java.util.concurrent.CancellationException
@@ -34,21 +32,10 @@ private val LOG: Logger = logger()
private val NECROMANCER_EP = ExtensionPointName>("com.intellij.textEditorNecromancerAwaker")
-@ApiStatus.Internal
-fun necropolisPath(): Path {
+internal fun necropolisPath(): Path {
return PathManager.getSystemDir().resolve("editor")
}
-@ApiStatus.Internal
-fun necropolisCacheNameAndPath(graveName: String, project: Project): Pair {
- // IJPL-157893 the cache should survive project renaming
- val projectName = project.getProjectCacheFileName(hashSeparator="-")
- val projectPath = necropolisPath().resolve(projectName)
- val cacheName = "$graveName-$projectName" // name should be unique across the application
- val cachePath = projectPath.resolve(graveName).resolve(graveName)
- return cacheName to cachePath
-}
-
/**
* Service managing all necromancers.
*
@@ -74,7 +61,6 @@ class Necropolis(private val project: Project, private val coroutineScope: Corou
}
}
-
suspend fun spawnZombies(
project: Project,
file: VirtualFile,
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/RemoteCacheFactory.kt b/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/RemoteCacheFactory.kt
deleted file mode 100644
index fd50e4548fee..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/RemoteCacheFactory.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.openapi.editor.impl.zombie
-
-import com.intellij.openapi.extensions.ExtensionPointName
-import com.intellij.openapi.project.Project
-import com.intellij.util.io.DataExternalizer
-import com.intellij.util.io.cache.RemoteManagedCache
-import kotlinx.coroutines.CoroutineScope
-
-interface RemoteCacheFactory {
- fun createCache(
- cacheName: String,
- keyExternalizer: DataExternalizer,
- valueExternalizer: DataExternalizer,
- project: Project,
- coroutineScope: CoroutineScope
- ): RemoteManagedCache
- companion object {
- val EP: ExtensionPointName = ExtensionPointName("com.intellij.remoteManagedCacheFactory")
- fun tryCreateCache(
- cacheName: String,
- keyExternalizer: DataExternalizer,
- valueExternalizer: DataExternalizer,
- project: Project,
- coroutineScope: CoroutineScope
- ): RemoteManagedCache? {
- val remoteCacheFactory = EP.findFirstSafe { true }
- return remoteCacheFactory?.createCache(cacheName, keyExternalizer, valueExternalizer, project, coroutineScope)
- }
- }
-}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/RemoteLocalCache.kt b/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/RemoteLocalCache.kt
deleted file mode 100644
index e708693507c0..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/zombie/RemoteLocalCache.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package com.intellij.openapi.editor.impl.zombie
-
-import com.intellij.openapi.project.Project
-import com.intellij.util.io.DataExternalizer
-import com.intellij.util.io.DataInputOutputUtil.readLONG
-import com.intellij.util.io.DataInputOutputUtil.writeLONG
-import com.intellij.util.io.EnumeratorIntegerDescriptor
-import com.intellij.util.io.PersistentMapBuilder
-import com.intellij.util.io.cache.ManagedPersistentCache
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.async
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import java.io.DataInput
-import java.io.DataOutput
-
-internal class RemoteLocalCache(
- private val localCache: Cache,
- private val remoteCache: RemoteCache?
-) : Cache {
- override suspend fun put(key: Int, value: FingerprintedZombie) {
- coroutineScope {
- async { localCache.put(key, value) }
- async { remoteCache?.put(key, value) }
- }
- }
-
- suspend fun prefetch(id: Int) {
- if (localCache.get(id) != null) return
- remoteCache?.get(id)?.let { localCache.put(id, it) }
- }
-
- override suspend fun get(key: Int): FingerprintedZombie? {
- return localCache.get(key) ?: remoteCache?.get(key)?.also { localCache.put(key, it) }
- }
-
- override suspend fun remove(key: Int) {
- coroutineScope {
- async { localCache.remove(key) }
- async { remoteCache?.remove(key) }
- }
- }
-
- companion object {
- @Suppress("UNCHECKED_CAST")
- fun create(
- cacheName: String,
- necromancy: Necromancy,
- project: Project,
- coroutineScope: CoroutineScope
- ): RemoteLocalCache {
- val localCache = createLocalCache(cacheName, necromancy, project, coroutineScope)
- val remoteCache = RemoteCacheFactory
- .tryCreateCache>(
- cacheName,
- EnumeratorIntegerDescriptor.INSTANCE,
- FingerprintedExternalizer(necromancy),
- project,
- coroutineScope
- )
- remoteCache?.preload(coroutineScope, localCache)
- return RemoteLocalCache(
- localCache = localCache,
- remoteCache = remoteCache,
- )
- }
- private fun RemoteCache.preload(coroutineScope: CoroutineScope, localCache: Cache) = coroutineScope.launch {
- val preloadedFromReload = preloadedContent.await()
- preloadedFromReload.forEach { (key, value) -> localCache.put(key, value) }
- }
-
- private fun createLocalCache(cacheName: String, necromancy: Necromancy, project: Project, coroutineScope: CoroutineScope): Cache {
- val (cacheName, cachePath) = necropolisCacheNameAndPath(cacheName, project)
- val builder = PersistentMapBuilder.newBuilder(
- cachePath,
- EnumeratorIntegerDescriptor.INSTANCE,
- FingerprintedExternalizer(necromancy),
- ).withVersion(necromancy.spellLevel())
- return if (necromancy.isDeepBury()) {
- ManagedPersistentCache(cacheName, builder, coroutineScope)
- } else {
- // TODO: heap implementation
- ManagedPersistentCache(cacheName, builder, coroutineScope)
- }
- }
- }
-}
-
-private class FingerprintedExternalizer(
- private val necromancy: Necromancy,
-) : DataExternalizer> {
-
- override fun read(input: DataInput): FingerprintedZombie {
- val fingerprint = readLONG(input)
- val zombie = necromancy.exhumeZombie(input)
- return FingerprintedZombieImpl(fingerprint, zombie)
- }
-
- override fun save(output: DataOutput, value: FingerprintedZombie) {
- writeLONG(output, value.fingerprint())
- necromancy.buryZombie(output, value.zombie())
- }
-}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/util/io/cache/ManagedPersistentCache.kt b/platform/platform-impl/src/com/intellij/util/io/cache/ManagedPersistentCache.kt
index 89f12336f376..eb9d79678267 100644
--- a/platform/platform-impl/src/com/intellij/util/io/cache/ManagedPersistentCache.kt
+++ b/platform/platform-impl/src/com/intellij/util/io/cache/ManagedPersistentCache.kt
@@ -45,16 +45,17 @@ class ManagedPersistentCache @OptIn(ExperimentalCoroutinesApi::class) cons
withPersistentMap(opName="put") { map ->
map.put(key, value)
}
-
forceAsync()
}
- suspend fun entries(): List> = withPersistentMap(opName = "entries") { map ->
+ suspend fun entries(): List> {
+ return withPersistentMap(opName = "entries") { map ->
val list = buildList {
map.processExistingKeys { key -> add(Entry(key, map.get(key)!!)) }
}
list
}.orEmpty()
+ }
override suspend fun get(key: K): V? {
return withPersistentMap(opName="get") { map ->
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index 80d03c2a2dcb..b1b087d7a4a7 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -579,7 +579,6 @@
-
diff --git a/platform/platform-resources/src/META-INF/essential-modules.xml b/platform/platform-resources/src/META-INF/essential-modules.xml
index 65301631ccc4..612e58faec4d 100644
--- a/platform/platform-resources/src/META-INF/essential-modules.xml
+++ b/platform/platform-resources/src/META-INF/essential-modules.xml
@@ -38,9 +38,11 @@
-->
-
+
+
+