Kotlin Scripting IDE performance: cache file attributes in memory.

This saves ~2 secs on file highlighting pass.
This commit is contained in:
Sergey Rostov
2018-07-25 11:05:11 +03:00
parent eb420a1e0f
commit adcabd2a5a
4 changed files with 32 additions and 19 deletions
@@ -6,13 +6,13 @@
package org.jetbrains.kotlin.idea.core.script
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.writeString
import java.io.DataInputStream
import java.io.DataOutputStream
var VirtualFile.scriptRelatedModuleName: String? by fileAttribute(
var VirtualFile.scriptRelatedModuleName: String? by cachedFileAttribute(
name = "kotlin-script-moduleName",
version = 1,
read = DataInputStream::readString,
@@ -22,7 +22,7 @@ import java.io.DataInput
import java.io.DataOutput
import kotlin.script.experimental.dependencies.ScriptDependencies
var VirtualFile.scriptDependencies: ScriptDependencies? by fileAttribute(
var VirtualFile.scriptDependencies: ScriptDependencies? by cachedFileAttribute(
name = "kotlin-script-dependencies",
version = 3,
read = {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.core.util
import com.intellij.openapi.util.NullableLazyKey
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileWithId
import com.intellij.openapi.vfs.newvfs.FileAttribute
@@ -15,11 +16,11 @@ import com.intellij.util.io.IOUtil.writeUTF
import java.io.*
import kotlin.reflect.KProperty
fun <T : Any> fileAttribute(
inline fun <T : Any> cachedFileAttribute(
name: String,
version: Int,
read: DataInputStream.() -> T,
write: DataOutputStream.(T) -> Unit
crossinline read: DataInputStream.() -> T,
crossinline write: DataOutputStream.(T) -> Unit
): FileAttributeProperty<T> {
return object : FileAttributeProperty<T>(name, version) {
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)
operator fun setValue(file: VirtualFile, property: KProperty<*>, newValue: T?) {
if (file !is VirtualFileWithId) return
@Suppress("LeakingThis")
private val cache = NullableLazyKey.create(
"FileAttributeProperty.$name",
this::computeValue
)
attribute.writeAttribute(file).use { output ->
output.writeNullable(newValue) { value ->
writeValue(output, value)
}
}
}
operator fun getValue(file: VirtualFile, property: KProperty<*>): T? {
private fun computeValue(file: VirtualFile): T? {
if (file !is VirtualFileWithId) return null
return attribute.readAttribute(file)?.use { input ->
@@ -52,12 +49,28 @@ abstract class FileAttributeProperty<T : Any>(name: String, version: Int, privat
}
} ?: 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.readFileList(): List<File> = readSeq(this) { readFile() }
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.writeFile(it: File) = writeString(it.canonicalPath)
@@ -6,9 +6,9 @@
package org.jetbrains.kotlin.idea.scratch.ui
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",
version = 1,
read = { ScratchPanelConfig(readBoolean(), readBoolean()) },