mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
[rdct] IJPL-190480: Use Proper API
GitOrigin-RevId: 2245830bae1b1611ae8bed8c0886e308c65b992e
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7933bb5302
commit
4d6d5776ff
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -1164,6 +1164,8 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/turboComplete/languages/kotlin/k1/intellij.turboComplete.languages.kotlin.k1.iml" filepath="$PROJECT_DIR$/plugins/turboComplete/languages/kotlin/k1/intellij.turboComplete.languages.kotlin.k1.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/turboComplete/intellij.turboComplete.tests.iml" filepath="$PROJECT_DIR$/plugins/turboComplete/intellij.turboComplete.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer-core/intellij.uiDesigner.iml" filepath="$PROJECT_DIR$/plugins/ui-designer-core/intellij.uiDesigner.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/managed-cache/util.io.cache/intellij.util.io.cache.iml" filepath="$PROJECT_DIR$/platform/managed-cache/util.io.cache/intellij.util.io.cache.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/managed-cache/util.io.cache.backend/intellij.util.io.cache.backend.iml" filepath="$PROJECT_DIR$/platform/managed-cache/util.io.cache.backend/intellij.util.io.cache.backend.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/changeReminder/intellij.vcs.changeReminder.iml" filepath="$PROJECT_DIR$/plugins/changeReminder/intellij.vcs.changeReminder.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/git4idea/intellij.vcs.git.iml" filepath="$PROJECT_DIR$/plugins/git4idea/intellij.vcs.git.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/git-modal-commit/intellij.vcs.git.commit.modal.iml" filepath="$PROJECT_DIR$/plugins/git-modal-commit/intellij.vcs.git.commit.modal.iml" />
|
||||
|
||||
@@ -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"]
|
||||
)
|
||||
|
||||
@@ -1,31 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
|
||||
<compilerSettings>
|
||||
<option name="additionalArguments" value="-Xjvm-default=all" />
|
||||
</compilerSettings>
|
||||
<compilerArguments>
|
||||
<stringArguments>
|
||||
<stringArg name="jvmTarget" arg="17" />
|
||||
<stringArg name="apiVersion" arg="2.2" />
|
||||
<stringArg name="languageVersion" arg="2.2" />
|
||||
</stringArguments>
|
||||
<arrayArguments>
|
||||
<arrayArg name="pluginClasspaths">
|
||||
<args>
|
||||
<arg>$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
</args>
|
||||
</arrayArg>
|
||||
<arrayArg name="pluginOptions" />
|
||||
</arrayArguments>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
@@ -45,10 +19,5 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.util.coroutines" />
|
||||
<orderEntry type="module" module-name="intellij.platform.kernel" />
|
||||
<orderEntry type="module" module-name="intellij.platform.pasta" />
|
||||
<orderEntry type="module" module-name="intellij.platform.project" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-json" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.concurrency" />
|
||||
<orderEntry type="module" module-name="intellij.platform.kernel.backend" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -2,12 +2,10 @@
|
||||
<dependencies>
|
||||
<module name="intellij.platform.backend"/>
|
||||
<module name="intellij.platform.editor"/>
|
||||
<module name="intellij.platform.kernel.backend"/>
|
||||
</dependencies>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<editorFactoryListener implementation="com.intellij.platform.editor.backend.BackendEditorFactoryListener"/>
|
||||
<applicationService serviceImplementation="com.intellij.platform.editor.backend.BackendEditors"
|
||||
client="remote"/>
|
||||
<platform.rpc.backend.remoteApiProvider implementation="com.intellij.platform.editor.backend.zombie.RemoteManagedCacheApiImplProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -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<String, ManagedCache<RemoteManagedCacheDto, RemoteManagedCacheDto>>()
|
||||
fun get(cacheId: CacheId): ManagedCache<RemoteManagedCacheDto, RemoteManagedCacheDto> {
|
||||
return storage[cacheId.name]!!
|
||||
}
|
||||
suspend fun create(cacheId: CacheId): List<PrefetchedRemoteCacheValue> {
|
||||
// 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<RemoteManagedCacheDto> {
|
||||
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<RemoteManagedCacheDto> {
|
||||
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<RemoteManagedCacheManager>()?.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<PrefetchedRemoteCacheValue> {
|
||||
val project = cacheId.projectId.findProjectOrNull() ?: return emptyList()
|
||||
return project.serviceAsync<RemoteManagedCacheManager>().create(cacheId)
|
||||
}
|
||||
}
|
||||
@@ -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"]
|
||||
)
|
||||
|
||||
@@ -1,31 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
|
||||
<compilerSettings>
|
||||
<option name="additionalArguments" value="-Xjvm-default=all" />
|
||||
</compilerSettings>
|
||||
<compilerArguments>
|
||||
<stringArguments>
|
||||
<stringArg name="jvmTarget" arg="17" />
|
||||
<stringArg name="apiVersion" arg="2.2" />
|
||||
<stringArg name="languageVersion" arg="2.2" />
|
||||
</stringArguments>
|
||||
<arrayArguments>
|
||||
<arrayArg name="pluginClasspaths">
|
||||
<args>
|
||||
<arg>$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
</args>
|
||||
</arrayArg>
|
||||
<arrayArg name="pluginOptions" />
|
||||
</arrayArguments>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
@@ -41,6 +15,5 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.kernel" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
|
||||
<orderEntry type="module" module-name="intellij.platform.pasta" />
|
||||
<orderEntry type="module" module-name="intellij.platform.project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -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>(
|
||||
EditorEntity::class.java.name,
|
||||
"com.intellij.platform.editor",
|
||||
|
||||
@@ -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 <V> toValue(externalizer: DataExternalizer<V>): V = ByteArrayInputStream(data).use {
|
||||
DataInputStream(it).use { dataInput ->
|
||||
externalizer.read(dataInput)
|
||||
}
|
||||
}
|
||||
companion object {
|
||||
fun<V> V.fromValue(externalizer: DataExternalizer<V>): RemoteManagedCacheDto {
|
||||
return ByteArrayOutputStream().use {bao ->
|
||||
DataOutputStream(bao).use { dataOutput: DataOutput ->
|
||||
externalizer.save(dataOutput, this)
|
||||
RemoteManagedCacheDto(bao.toByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
platform/managed-cache/util.io.cache.backend/BUILD.bazel
Normal file
30
platform/managed-cache/util.io.cache.backend/BUILD.bazel
Normal file
@@ -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
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
|
||||
<compilerSettings>
|
||||
<option name="additionalArguments" value="-Xjvm-default=all" />
|
||||
</compilerSettings>
|
||||
<compilerArguments>
|
||||
<stringArguments>
|
||||
<stringArg name="jvmTarget" arg="17" />
|
||||
<stringArg name="apiVersion" arg="2.2" />
|
||||
<stringArg name="languageVersion" arg="2.2" />
|
||||
</stringArguments>
|
||||
<arrayArguments>
|
||||
<arrayArg name="pluginClasspaths">
|
||||
<args>
|
||||
<arg>$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
</args>
|
||||
</arrayArg>
|
||||
<arrayArg name="pluginOptions" />
|
||||
</arrayArguments>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.intellij.util.io.cache.backend" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-stdlib" level="project" />
|
||||
<orderEntry type="library" name="jetbrains-annotations" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.kernel.backend" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-json" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-coroutines-core" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.util" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
|
||||
<orderEntry type="module" module-name="intellij.util.io.cache" />
|
||||
<orderEntry type="module" module-name="intellij.platform.concurrency" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,9 @@
|
||||
<idea-plugin>
|
||||
<dependencies>
|
||||
<module name="intellij.platform.kernel.backend"/>
|
||||
<module name="intellij.platform.backend"/>
|
||||
</dependencies>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<platform.rpc.backend.remoteApiProvider implementation="com.intellij.util.io.cache.backend.RemoteManagedCacheApiImplProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -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<String, ManagedCache<ByteArray, ByteArray>>()
|
||||
fun get(cacheId: CacheId): ManagedCache<ByteArray, ByteArray> {
|
||||
return storage[cacheId.name]!!
|
||||
}
|
||||
suspend fun create(cacheId: CacheId, buildParams: RemoteManagedCacheBuildParams): List<PrefetchedRemoteCacheValue> {
|
||||
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<ByteArray> {
|
||||
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<ByteArray> {
|
||||
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<RemoteManagedCacheManager>()?.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<PrefetchedRemoteCacheValue> {
|
||||
val project = cacheId.projectId.findProjectOrNull() ?: return emptyList()
|
||||
return project.serviceAsync<RemoteManagedCacheManager>().create(cacheId, buildParams)
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
26
platform/managed-cache/util.io.cache/BUILD.bazel
Normal file
26
platform/managed-cache/util.io.cache/BUILD.bazel
Normal file
@@ -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
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
|
||||
<compilerSettings>
|
||||
<option name="additionalArguments" value="-Xjvm-default=all" />
|
||||
</compilerSettings>
|
||||
<compilerArguments>
|
||||
<stringArguments>
|
||||
<stringArg name="jvmTarget" arg="17" />
|
||||
<stringArg name="apiVersion" arg="2.2" />
|
||||
<stringArg name="languageVersion" arg="2.2" />
|
||||
</stringArguments>
|
||||
<arrayArguments>
|
||||
<arrayArg name="pluginClasspaths">
|
||||
<args>
|
||||
<arg>$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/jetbrains/fleet/rhizomedb-compiler-plugin/2.2.0-RC2-0.1/rhizomedb-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
<arg>$MAVEN_REPOSITORY$/com/jetbrains/fleet/rpc-compiler-plugin/2.2.0-RC2-0.1/rpc-compiler-plugin-2.2.0-RC2-0.1.jar</arg>
|
||||
</args>
|
||||
</arrayArg>
|
||||
<arrayArg name="pluginOptions" />
|
||||
</arrayArguments>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/">
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.intellij.util.io.cache" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-stdlib" level="project" />
|
||||
<orderEntry type="library" name="jetbrains-annotations" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.kernel" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-json" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-coroutines-core" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,2 @@
|
||||
<idea-plugin>
|
||||
</idea-plugin>
|
||||
@@ -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
|
||||
@@ -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)
|
||||
class PrefetchedRemoteCacheValue(val key: ByteArray, val value: ByteArray)
|
||||
@@ -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<Unit> {
|
||||
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<PrefetchedRemoteCacheValue>
|
||||
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<PrefetchedRemoteCacheValue>
|
||||
|
||||
companion object {
|
||||
suspend fun getInstance(): RemoteManagedCacheApi {
|
||||
@@ -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<K, V>: ManagedCache<K, V> {
|
||||
/**
|
||||
* A deferred content that delivered from remote source
|
||||
*/
|
||||
val preloadedContent: Deferred<List<Map.Entry<K, V>>>
|
||||
}
|
||||
@Serializable
|
||||
data class RemoteManagedCacheBuildParams(val serdeVersion: Int)
|
||||
@@ -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<Necropolis>()
|
||||
|
||||
private val NECROMANCER_EP = ExtensionPointName<NecromancerAwaker<Zombie>>("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<String, Path> {
|
||||
// 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,
|
||||
|
||||
@@ -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<K, V> createCache(
|
||||
cacheName: String,
|
||||
keyExternalizer: DataExternalizer<K>,
|
||||
valueExternalizer: DataExternalizer<V>,
|
||||
project: Project,
|
||||
coroutineScope: CoroutineScope
|
||||
): RemoteManagedCache<K, V>
|
||||
companion object {
|
||||
val EP: ExtensionPointName<RemoteCacheFactory> = ExtensionPointName<RemoteCacheFactory>("com.intellij.remoteManagedCacheFactory")
|
||||
fun<K, V> tryCreateCache(
|
||||
cacheName: String,
|
||||
keyExternalizer: DataExternalizer<K>,
|
||||
valueExternalizer: DataExternalizer<V>,
|
||||
project: Project,
|
||||
coroutineScope: CoroutineScope
|
||||
): RemoteManagedCache<K, V>? {
|
||||
val remoteCacheFactory = EP.findFirstSafe { true }
|
||||
return remoteCacheFactory?.createCache(cacheName, keyExternalizer, valueExternalizer, project, coroutineScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Z: Zombie>(
|
||||
private val localCache: Cache<Z>,
|
||||
private val remoteCache: RemoteCache<Z>?
|
||||
) : Cache<Z> {
|
||||
override suspend fun put(key: Int, value: FingerprintedZombie<Z>) {
|
||||
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<Z>? {
|
||||
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 <Z: Zombie> create(
|
||||
cacheName: String,
|
||||
necromancy: Necromancy<Z>,
|
||||
project: Project,
|
||||
coroutineScope: CoroutineScope
|
||||
): RemoteLocalCache<Z> {
|
||||
val localCache = createLocalCache(cacheName, necromancy, project, coroutineScope)
|
||||
val remoteCache = RemoteCacheFactory
|
||||
.tryCreateCache<Int, FingerprintedZombie<Z>>(
|
||||
cacheName,
|
||||
EnumeratorIntegerDescriptor.INSTANCE,
|
||||
FingerprintedExternalizer(necromancy),
|
||||
project,
|
||||
coroutineScope
|
||||
)
|
||||
remoteCache?.preload(coroutineScope, localCache)
|
||||
return RemoteLocalCache(
|
||||
localCache = localCache,
|
||||
remoteCache = remoteCache,
|
||||
)
|
||||
}
|
||||
private fun<Z: Zombie> RemoteCache<Z>.preload(coroutineScope: CoroutineScope, localCache: Cache<Z>) = coroutineScope.launch {
|
||||
val preloadedFromReload = preloadedContent.await()
|
||||
preloadedFromReload.forEach { (key, value) -> localCache.put(key, value) }
|
||||
}
|
||||
|
||||
private fun<Z: Zombie> createLocalCache(cacheName: String, necromancy: Necromancy<Z>, project: Project, coroutineScope: CoroutineScope): Cache<Z> {
|
||||
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<Z : Zombie>(
|
||||
private val necromancy: Necromancy<Z>,
|
||||
) : DataExternalizer<FingerprintedZombie<Z>> {
|
||||
|
||||
override fun read(input: DataInput): FingerprintedZombie<Z> {
|
||||
val fingerprint = readLONG(input)
|
||||
val zombie = necromancy.exhumeZombie(input)
|
||||
return FingerprintedZombieImpl(fingerprint, zombie)
|
||||
}
|
||||
|
||||
override fun save(output: DataOutput, value: FingerprintedZombie<Z>) {
|
||||
writeLONG(output, value.fingerprint())
|
||||
necromancy.buryZombie(output, value.zombie())
|
||||
}
|
||||
}
|
||||
@@ -45,16 +45,17 @@ class ManagedPersistentCache<K, V> @OptIn(ExperimentalCoroutinesApi::class) cons
|
||||
withPersistentMap(opName="put") { map ->
|
||||
map.put(key, value)
|
||||
}
|
||||
|
||||
forceAsync()
|
||||
}
|
||||
|
||||
suspend fun entries(): List<Map.Entry<K, V>> = withPersistentMap(opName = "entries") { map ->
|
||||
suspend fun entries(): List<Map.Entry<K, V>> {
|
||||
return withPersistentMap(opName = "entries") { map ->
|
||||
val list = buildList {
|
||||
map.processExistingKeys { key -> add(Entry<K, V>(key, map.get(key)!!)) }
|
||||
}
|
||||
list
|
||||
}.orEmpty()
|
||||
}
|
||||
|
||||
override suspend fun get(key: K): V? {
|
||||
return withPersistentMap(opName="get") { map ->
|
||||
|
||||
@@ -579,7 +579,6 @@
|
||||
<extensionPoint name="mac.dockMenuActions" interface="com.intellij.ui.mac.MacDockMenuActions" dynamic="false"/>
|
||||
|
||||
<extensionPoint name="textEditorNecromancerAwaker" interface="com.intellij.openapi.editor.impl.zombie.NecromancerAwaker" dynamic="true"/>
|
||||
<extensionPoint name="remoteManagedCacheFactory" interface="com.intellij.openapi.editor.impl.zombie.RemoteCacheFactory" dynamic="true"/>
|
||||
|
||||
<extensionPoint name="toolbarQuickAction" beanClass="com.intellij.ide.ui.customization.ToolbarAddQuickActionInfoBean" dynamic="true">
|
||||
<with attribute="implementationClass" implements="com.intellij.ide.ui.customization.ToolbarAddQuickActionInfo"/>
|
||||
|
||||
@@ -38,9 +38,11 @@
|
||||
-->
|
||||
<module name="intellij.platform.find" loading="embedded"/>
|
||||
<module name="intellij.platform.find.backend"/>
|
||||
<module name="intellij.platform.editor" loading="embedded"/>
|
||||
<module name="intellij.platform.editor"/>
|
||||
<module name="intellij.platform.editor.backend"/>
|
||||
<module name="intellij.platform.editor.frontend"/>
|
||||
<module name="intellij.util.io.cache" loading="embedded"/>
|
||||
<module name="intellij.util.io.cache.backend"/>
|
||||
|
||||
<module name="intellij.platform.debugger.impl.frontend"/>
|
||||
<module name="intellij.platform.debugger.impl.backend"/>
|
||||
|
||||
Reference in New Issue
Block a user