Kotlin Scripting IDE performance: cache file attributes in memory.
This saves ~2 secs on file highlighting pass.
This commit is contained in:
@@ -6,13 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.idea.core.script
|
package org.jetbrains.kotlin.idea.core.script
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import org.jetbrains.kotlin.idea.core.util.fileAttribute
|
import org.jetbrains.kotlin.idea.core.util.cachedFileAttribute
|
||||||
import org.jetbrains.kotlin.idea.core.util.readString
|
import org.jetbrains.kotlin.idea.core.util.readString
|
||||||
import org.jetbrains.kotlin.idea.core.util.writeString
|
import org.jetbrains.kotlin.idea.core.util.writeString
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
|
|
||||||
var VirtualFile.scriptRelatedModuleName: String? by fileAttribute(
|
var VirtualFile.scriptRelatedModuleName: String? by cachedFileAttribute(
|
||||||
name = "kotlin-script-moduleName",
|
name = "kotlin-script-moduleName",
|
||||||
version = 1,
|
version = 1,
|
||||||
read = DataInputStream::readString,
|
read = DataInputStream::readString,
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ import java.io.DataInput
|
|||||||
import java.io.DataOutput
|
import java.io.DataOutput
|
||||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||||
|
|
||||||
var VirtualFile.scriptDependencies: ScriptDependencies? by fileAttribute(
|
var VirtualFile.scriptDependencies: ScriptDependencies? by cachedFileAttribute(
|
||||||
name = "kotlin-script-dependencies",
|
name = "kotlin-script-dependencies",
|
||||||
version = 3,
|
version = 3,
|
||||||
read = {
|
read = {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.core.util
|
package org.jetbrains.kotlin.idea.core.util
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.NullableLazyKey
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.VirtualFileWithId
|
import com.intellij.openapi.vfs.VirtualFileWithId
|
||||||
import com.intellij.openapi.vfs.newvfs.FileAttribute
|
import com.intellij.openapi.vfs.newvfs.FileAttribute
|
||||||
@@ -15,11 +16,11 @@ import com.intellij.util.io.IOUtil.writeUTF
|
|||||||
import java.io.*
|
import java.io.*
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
fun <T : Any> fileAttribute(
|
inline fun <T : Any> cachedFileAttribute(
|
||||||
name: String,
|
name: String,
|
||||||
version: Int,
|
version: Int,
|
||||||
read: DataInputStream.() -> T,
|
crossinline read: DataInputStream.() -> T,
|
||||||
write: DataOutputStream.(T) -> Unit
|
crossinline write: DataOutputStream.(T) -> Unit
|
||||||
): FileAttributeProperty<T> {
|
): FileAttributeProperty<T> {
|
||||||
return object : FileAttributeProperty<T>(name, version) {
|
return object : FileAttributeProperty<T>(name, version) {
|
||||||
override fun readValue(input: DataInputStream): T = read(input)
|
override fun readValue(input: DataInputStream): T = read(input)
|
||||||
@@ -33,17 +34,13 @@ abstract class FileAttributeProperty<T : Any>(name: String, version: Int, privat
|
|||||||
|
|
||||||
private val attribute = FileAttribute(name, version, false)
|
private val attribute = FileAttribute(name, version, false)
|
||||||
|
|
||||||
operator fun setValue(file: VirtualFile, property: KProperty<*>, newValue: T?) {
|
@Suppress("LeakingThis")
|
||||||
if (file !is VirtualFileWithId) return
|
private val cache = NullableLazyKey.create(
|
||||||
|
"FileAttributeProperty.$name",
|
||||||
|
this::computeValue
|
||||||
|
)
|
||||||
|
|
||||||
attribute.writeAttribute(file).use { output ->
|
private fun computeValue(file: VirtualFile): T? {
|
||||||
output.writeNullable(newValue) { value ->
|
|
||||||
writeValue(output, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun getValue(file: VirtualFile, property: KProperty<*>): T? {
|
|
||||||
if (file !is VirtualFileWithId) return null
|
if (file !is VirtualFileWithId) return null
|
||||||
|
|
||||||
return attribute.readAttribute(file)?.use { input ->
|
return attribute.readAttribute(file)?.use { input ->
|
||||||
@@ -52,12 +49,28 @@ abstract class FileAttributeProperty<T : Any>(name: String, version: Int, privat
|
|||||||
}
|
}
|
||||||
} ?: default
|
} ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun setValue(file: VirtualFile, property: KProperty<*>, newValue: T?) {
|
||||||
|
if (file !is VirtualFileWithId) return
|
||||||
|
|
||||||
|
attribute.writeAttribute(file).use { output ->
|
||||||
|
output.writeNullable(newValue) { value ->
|
||||||
|
writeValue(output, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear cache
|
||||||
|
file.putUserData(cache, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun getValue(file: VirtualFile, property: KProperty<*>): T? =
|
||||||
|
cache.getValue(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DataInput.readStringList(): List<String> = readSeq(this) { readString() }
|
fun DataInput.readStringList(): List<String> = readSeq(this) { readString() }
|
||||||
fun DataInput.readFileList(): List<File> = readSeq(this) { readFile() }
|
fun DataInput.readFileList(): List<File> = readSeq(this) { readFile() }
|
||||||
fun DataInput.readString(): String = readUTF(this)
|
fun DataInput.readString(): String = readUTF(this)
|
||||||
fun DataInput.readFile() = readUTF(this).let { File(it) }
|
fun DataInput.readFile() = File(readUTF(this))
|
||||||
|
|
||||||
fun DataOutput.writeFileList(iterable: Iterable<File>) = writeSeq(this, iterable.toList()) { writeFile(it) }
|
fun DataOutput.writeFileList(iterable: Iterable<File>) = writeSeq(this, iterable.toList()) { writeFile(it) }
|
||||||
fun DataOutput.writeFile(it: File) = writeString(it.canonicalPath)
|
fun DataOutput.writeFile(it: File) = writeString(it.canonicalPath)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.idea.scratch.ui
|
package org.jetbrains.kotlin.idea.scratch.ui
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import org.jetbrains.kotlin.idea.core.util.fileAttribute
|
import org.jetbrains.kotlin.idea.core.util.cachedFileAttribute
|
||||||
|
|
||||||
var VirtualFile.scratchPanelConfig: ScratchPanelConfig? by fileAttribute(
|
var VirtualFile.scratchPanelConfig: ScratchPanelConfig? by cachedFileAttribute(
|
||||||
name = "kotlin-scratch-panel-config",
|
name = "kotlin-scratch-panel-config",
|
||||||
version = 1,
|
version = 1,
|
||||||
read = { ScratchPanelConfig(readBoolean(), readBoolean()) },
|
read = { ScratchPanelConfig(readBoolean(), readBoolean()) },
|
||||||
|
|||||||
Reference in New Issue
Block a user