Simplify InlineFunctionsFilesMap

This commit is contained in:
Alexey Tsvetkov
2015-09-03 21:01:21 +03:00
parent 21b6b41112
commit 3d9d6d356b
2 changed files with 86 additions and 86 deletions
@@ -21,7 +21,6 @@ import com.intellij.util.io.BooleanDataDescriptor
import com.intellij.util.io.DataExternalizer import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.IOUtil import com.intellij.util.io.IOUtil
import com.intellij.util.io.KeyDescriptor import com.intellij.util.io.KeyDescriptor
import gnu.trove.THashMap
import gnu.trove.THashSet import gnu.trove.THashSet
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.jps.builders.BuildTarget import org.jetbrains.jps.builders.BuildTarget
@@ -36,6 +35,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.jps.build.GeneratedJvmClass import org.jetbrains.kotlin.jps.build.GeneratedJvmClass
import org.jetbrains.kotlin.jps.build.KotlinBuilder import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.incremental.storage.BasicMap import org.jetbrains.kotlin.jps.incremental.storage.BasicMap
import org.jetbrains.kotlin.jps.incremental.storage.BasicStringMap
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
@@ -321,7 +321,7 @@ public class IncrementalCacheImpl(
maps.forEach { it.close () } maps.forEach { it.close () }
} }
private inner class ProtoMap(storageFile: File) : BasicMap<ByteArray>(storageFile, ByteArrayExternalizer) { private inner class ProtoMap(storageFile: File) : BasicStringMap<ByteArray>(storageFile, ByteArrayExternalizer) {
public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean, checkChangesIsOpenPart: Boolean = true): ChangesInfo { public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean, checkChangesIsOpenPart: Boolean = true): ChangesInfo {
val header = kotlinClass.classHeader val header = kotlinClass.classHeader
@@ -406,7 +406,7 @@ public class IncrementalCacheImpl(
} }
} }
private inner class ConstantsMap(storageFile: File) : BasicMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) { private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
private fun getConstantsMap(bytes: ByteArray): Map<String, Any>? { private fun getConstantsMap(bytes: ByteArray): Map<String, Any>? {
val result = HashMap<String, Any>() val result = HashMap<String, Any>()
@@ -509,7 +509,7 @@ public class IncrementalCacheImpl(
} }
} }
private inner class InlineFunctionsMap(storageFile: File) : BasicMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) { private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long> { private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long> {
val result = HashMap<String, Long>() val result = HashMap<String, Long>()
@@ -585,7 +585,7 @@ public class IncrementalCacheImpl(
value.dumpMap { java.lang.Long.toHexString(it) } value.dumpMap { java.lang.Long.toHexString(it) }
} }
private inner class PackagePartMap(storageFile: File) : BasicMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) { private inner class PackagePartMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
public fun addPackagePart(className: JvmClassName) { public fun addPackagePart(className: JvmClassName) {
storage.put(className.getInternalName(), true) storage.put(className.getInternalName(), true)
} }
@@ -601,7 +601,7 @@ public class IncrementalCacheImpl(
override fun dumpValue(value: Boolean) = "" override fun dumpValue(value: Boolean) = ""
} }
private inner class SourceToClassesMap(storageFile: File) : BasicMap<List<String>>(storageFile, StringListExternalizer) { private inner class SourceToClassesMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
override val keyDescriptor: KeyDescriptor<String> override val keyDescriptor: KeyDescriptor<String>
get() = PathStringDescriptor.INSTANCE get() = PathStringDescriptor.INSTANCE
@@ -620,7 +620,7 @@ public class IncrementalCacheImpl(
override fun dumpValue(value: List<String>) = value.toString() override fun dumpValue(value: List<String>) = value.toString()
} }
private inner class ClassToSourcesMap(storageFile: File) : BasicMap<Collection<String>>(storageFile, PathCollectionExternalizer) { private inner class ClassToSourcesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathCollectionExternalizer) {
public fun get(className: JvmClassName): Collection<String> = public fun get(className: JvmClassName): Collection<String> =
storage[className.internalName] ?: emptySet() storage[className.internalName] ?: emptySet()
@@ -638,7 +638,7 @@ public class IncrementalCacheImpl(
value.dumpCollection() value.dumpCollection()
} }
private inner class DirtyOutputClassesMap(storageFile: File) : BasicMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) { private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
public fun markDirty(className: String) { public fun markDirty(className: String) {
storage.put(className, true) storage.put(className, true)
} }
@@ -654,7 +654,7 @@ public class IncrementalCacheImpl(
override fun dumpValue(value: Boolean) = "" override fun dumpValue(value: Boolean) = ""
} }
private inner class DirtyInlineFunctionsMap(storageFile: File) : BasicMap<List<String>>(storageFile, StringListExternalizer) { private inner class DirtyInlineFunctionsMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
public fun getEntries(): Map<JvmClassName, List<String>> = public fun getEntries(): Map<JvmClassName, List<String>> =
storage.allKeysWithExistingMapping storage.allKeysWithExistingMapping
.toMap(JvmClassName::byInternalName) { storage[it] } .toMap(JvmClassName::byInternalName) { storage[it] }
@@ -667,65 +667,36 @@ public class IncrementalCacheImpl(
value.dumpCollection() value.dumpCollection()
} }
/** /**
* Mapping: sourceFile->{inlineFunction->...targetFiles} * Mapping: (sourceFile+inlineFunction)->(targetFiles)
* *
* Where: * Where:
* * sourceFile - path to some kotlin source * * sourceFile - path to some kotlin source
* * inlineFunction - jvmSignature of some inline function in source file * * inlineFunction - jvmSignature of some inline function in source file
* * target files - collection of files inlineFunction has been inlined to * * target files - collection of files inlineFunction has been inlined to
*/ */
private inner class InlineFunctionsFilesMap(storageFile: File) : BasicMap<Map<String, Collection<String>>>(storageFile, StringToPathsMapExternalizer) { private inner class InlineFunctionsFilesMap(storageFile: File) : BasicMap<PathFunctionPair, Collection<String>>(storageFile, PathCollectionExternalizer) {
override val keyDescriptor: KeyDescriptor<String> override val keyDescriptor: KeyDescriptor<PathFunctionPair>
get() = PathStringDescriptor() get() = PathFunctionPairKeyDescriptor
private val cache = THashMap<String, MutableMap<String, MutableCollection<String>>>(FileUtil.PATH_HASHING_STRATEGY)
public fun add(sourcePath: String, jvmSignature: String, targetPath: String) { public fun add(sourcePath: String, jvmSignature: String, targetPath: String) {
val mapping = getMappingFromCache(sourcePath.normalizedPath) val key = PathFunctionPair(sourcePath, jvmSignature)
val paths = mapping.getOrPut(jvmSignature) { THashSet(FileUtil.PATH_HASHING_STRATEGY) } storage.appendData(key) { out ->
paths.add(targetPath.normalizedPath) IOUtil.writeUTF(out, targetPath)
}
public fun get(sourceFile: String, jvmSignature: String): Collection<String> {
val normalizedPath = sourceFile.normalizedPath
if (normalizedPath !in cache && !storage.containsMapping(normalizedPath)) return emptySet()
val mapping = getMappingFromCache(normalizedPath)
return mapping[jvmSignature] ?: emptySet()
}
override fun clean() {
cache.clear()
super.clean()
}
override fun flush(memoryCachesOnly: Boolean) {
for ((k, v) in cache) {
storage.put(k, v)
} }
super.flush(memoryCachesOnly)
} }
override fun dumpValue(value: Map<String, Collection<String>>) = public fun get(sourcePath: String, jvmSignature: String): Collection<String> {
value.dumpMap { it.dumpCollection() } val key = PathFunctionPair(sourcePath, jvmSignature)
return storage[key] ?: emptySet()
private fun getMappingFromCache(sourcePath: String): MutableMap<String, MutableCollection<String>> {
val cachedValue = cache[sourcePath]
if (cachedValue != null) return cachedValue
val mapping = storage[sourcePath] ?: emptyMap()
val mutableMapping = hashMapOf<String, MutableCollection<String>>()
for ((k, v) in mapping) {
val paths = THashSet(v, FileUtil.PATH_HASHING_STRATEGY)
mutableMapping[k] = paths
}
cache[sourcePath] = mutableMapping
return mutableMapping
} }
override fun dumpKey(key: PathFunctionPair): String =
"(${key.path}, ${key.function})"
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
} }
} }
@@ -821,27 +792,6 @@ private object StringToLongMapExternalizer : StringMapExternalizer<Long>() {
} }
} }
private object StringToPathsMapExternalizer : StringMapExternalizer<Collection<String>>() {
override fun readValue(input: DataInput): Collection<String> {
val size = input.readInt()
val paths = THashSet(size, FileUtil.PATH_HASHING_STRATEGY)
repeat(size) {
paths.add(IOUtil.readUTF(input))
}
return paths
}
override fun writeValue(output: DataOutput, value: Collection<String>) {
output.writeInt(value.size())
for (path in value) {
IOUtil.writeUTF(output, path)
}
}
}
private object StringListExternalizer : DataExternalizer<List<String>> { private object StringListExternalizer : DataExternalizer<List<String>> {
override fun save(out: DataOutput, value: List<String>) { override fun save(out: DataOutput, value: List<String>) {
value.forEach { IOUtil.writeUTF(out, it) } value.forEach { IOUtil.writeUTF(out, it) }
@@ -877,9 +827,6 @@ private object PathCollectionExternalizer : DataExternalizer<Collection<String>>
private val File.normalizedPath: String private val File.normalizedPath: String
get() = FileUtil.toSystemIndependentName(canonicalPath) get() = FileUtil.toSystemIndependentName(canonicalPath)
private val String.normalizedPath: String
get() = FileUtil.toSystemIndependentName(this)
TestOnly TestOnly
private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): String = private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): String =
StringBuilder { StringBuilder {
@@ -898,3 +845,46 @@ private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): St
TestOnly TestOnly
public fun <T : Comparable<T>> Collection<T>.dumpCollection(): String = public fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
"[${sort().map(Any::toString).join(", ")}]" "[${sort().map(Any::toString).join(", ")}]"
private class PathFunctionPair(
public val path: String,
public val function: String
): Comparable<PathFunctionPair> {
override fun compareTo(other: PathFunctionPair): Int {
val pathComp = FileUtil.comparePaths(path, other.path)
if (pathComp != 0) return pathComp
return function.compareTo(other.function)
}
override fun equals(other: Any?): Boolean =
when (other) {
is PathFunctionPair ->
FileUtil.pathsEqual(path, other.path) && function == other.function
else ->
false
}
override fun hashCode(): Int = 31 * FileUtil.pathHashCode(path) + function.hashCode()
}
private object PathFunctionPairKeyDescriptor : KeyDescriptor<PathFunctionPair> {
override fun getHashCode(value: PathFunctionPair): Int =
value.hashCode()
override fun isEqual(val1: PathFunctionPair, val2: PathFunctionPair): Boolean =
val1 == val2
override fun read(`in`: DataInput): PathFunctionPair {
val path = IOUtil.readUTF(`in`)
val function = IOUtil.readUTF(`in`)
return PathFunctionPair(path, function)
}
override fun save(out: DataOutput, value: PathFunctionPair) {
IOUtil.writeUTF(out, value.path)
IOUtil.writeUTF(out, value.function)
}
}
@@ -25,16 +25,15 @@ import org.jetbrains.kotlin.utils.Printer
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
public abstract class BasicMap<V>( public abstract class BasicMap<K : Comparable<K>, V>(
private val storageFile: File, private val storageFile: File,
private val valueExternalizer: DataExternalizer<V> private val valueExternalizer: DataExternalizer<V>
) { ) {
protected open val keyDescriptor: KeyDescriptor<String> protected abstract val keyDescriptor: KeyDescriptor<K>
get() = EnumeratorStringDescriptor()
protected var storage: PersistentHashMap<String, V> = createMap() protected var storage: PersistentHashMap<K, V> = createMap()
public fun contains(key: String): Boolean = storage.containsMapping(key) public fun contains(key: K): Boolean = storage.containsMapping(key)
public open fun clean() { public open fun clean() {
try { try {
@@ -74,7 +73,7 @@ public abstract class BasicMap<V>(
pushIndent() pushIndent()
for (key in storage.getAllKeysWithExistingMapping().sort()) { for (key in storage.getAllKeysWithExistingMapping().sort()) {
println("$key -> ${dumpValue(storage[key])}") println("${dumpKey(key)} -> ${dumpValue(storage[key])}")
} }
popIndent() popIndent()
@@ -84,8 +83,19 @@ public abstract class BasicMap<V>(
}.toString() }.toString()
} }
protected abstract fun dumpKey(key: K): String
protected abstract fun dumpValue(value: V): String protected abstract fun dumpValue(value: V): String
private fun createMap(): PersistentHashMap<String, V> = private fun createMap(): PersistentHashMap<K, V> =
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer) PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}
public abstract class BasicStringMap<V>(
private val storageFile: File,
private val valueExternalizer: DataExternalizer<V>
) : BasicMap<String, V>(storageFile, valueExternalizer) {
override val keyDescriptor: KeyDescriptor<String>
get() = EnumeratorStringDescriptor()
override fun dumpKey(key: String): String = key
} }