From 6e67d3edaf6f7af4062e0cbf086a3d5ae673e205 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Thu, 3 Sep 2015 21:01:21 +0300 Subject: [PATCH] Simplify InlineFunctionsFilesMap Original commit: 3d9d6d356b098d983e045846af5dd8a1cb14fd09 --- .../jps/incremental/IncrementalCacheImpl.kt | 148 ++++++++---------- .../jps/incremental/storage/BasicMap.kt | 24 ++- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt index 37fbb257bf9..2925f03dadc 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt @@ -21,7 +21,6 @@ import com.intellij.util.io.BooleanDataDescriptor import com.intellij.util.io.DataExternalizer import com.intellij.util.io.IOUtil import com.intellij.util.io.KeyDescriptor -import gnu.trove.THashMap import gnu.trove.THashSet import org.jetbrains.annotations.TestOnly 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.KotlinBuilder 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.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.ModuleMapping @@ -321,7 +321,7 @@ public class IncrementalCacheImpl( maps.forEach { it.close () } } - private inner class ProtoMap(storageFile: File) : BasicMap(storageFile, ByteArrayExternalizer) { + private inner class ProtoMap(storageFile: File) : BasicStringMap(storageFile, ByteArrayExternalizer) { public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean, checkChangesIsOpenPart: Boolean = true): ChangesInfo { val header = kotlinClass.classHeader @@ -406,7 +406,7 @@ public class IncrementalCacheImpl( } } - private inner class ConstantsMap(storageFile: File) : BasicMap>(storageFile, ConstantsMapExternalizer) { + private inner class ConstantsMap(storageFile: File) : BasicStringMap>(storageFile, ConstantsMapExternalizer) { private fun getConstantsMap(bytes: ByteArray): Map? { val result = HashMap() @@ -509,7 +509,7 @@ public class IncrementalCacheImpl( } } - private inner class InlineFunctionsMap(storageFile: File) : BasicMap>(storageFile, StringToLongMapExternalizer) { + private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap>(storageFile, StringToLongMapExternalizer) { private fun getInlineFunctionsMap(bytes: ByteArray): Map { val result = HashMap() @@ -585,7 +585,7 @@ public class IncrementalCacheImpl( value.dumpMap { java.lang.Long.toHexString(it) } } - private inner class PackagePartMap(storageFile: File) : BasicMap(storageFile, BooleanDataDescriptor.INSTANCE) { + private inner class PackagePartMap(storageFile: File) : BasicStringMap(storageFile, BooleanDataDescriptor.INSTANCE) { public fun addPackagePart(className: JvmClassName) { storage.put(className.getInternalName(), true) } @@ -601,7 +601,7 @@ public class IncrementalCacheImpl( override fun dumpValue(value: Boolean) = "" } - private inner class SourceToClassesMap(storageFile: File) : BasicMap>(storageFile, StringListExternalizer) { + private inner class SourceToClassesMap(storageFile: File) : BasicStringMap>(storageFile, StringListExternalizer) { override val keyDescriptor: KeyDescriptor get() = PathStringDescriptor.INSTANCE @@ -620,7 +620,7 @@ public class IncrementalCacheImpl( override fun dumpValue(value: List) = value.toString() } - private inner class ClassToSourcesMap(storageFile: File) : BasicMap>(storageFile, PathCollectionExternalizer) { + private inner class ClassToSourcesMap(storageFile: File) : BasicStringMap>(storageFile, PathCollectionExternalizer) { public fun get(className: JvmClassName): Collection = storage[className.internalName] ?: emptySet() @@ -638,7 +638,7 @@ public class IncrementalCacheImpl( value.dumpCollection() } - private inner class DirtyOutputClassesMap(storageFile: File) : BasicMap(storageFile, BooleanDataDescriptor.INSTANCE) { + private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap(storageFile, BooleanDataDescriptor.INSTANCE) { public fun markDirty(className: String) { storage.put(className, true) } @@ -654,7 +654,7 @@ public class IncrementalCacheImpl( override fun dumpValue(value: Boolean) = "" } - private inner class DirtyInlineFunctionsMap(storageFile: File) : BasicMap>(storageFile, StringListExternalizer) { + private inner class DirtyInlineFunctionsMap(storageFile: File) : BasicStringMap>(storageFile, StringListExternalizer) { public fun getEntries(): Map> = storage.allKeysWithExistingMapping .toMap(JvmClassName::byInternalName) { storage[it] } @@ -667,65 +667,36 @@ public class IncrementalCacheImpl( value.dumpCollection() } + /** - * Mapping: sourceFile->{inlineFunction->...targetFiles} + * Mapping: (sourceFile+inlineFunction)->(targetFiles) * * Where: * * sourceFile - path to some kotlin source * * inlineFunction - jvmSignature of some inline function in source file * * target files - collection of files inlineFunction has been inlined to */ - private inner class InlineFunctionsFilesMap(storageFile: File) : BasicMap>>(storageFile, StringToPathsMapExternalizer) { - override val keyDescriptor: KeyDescriptor - get() = PathStringDescriptor() - - private val cache = THashMap>>(FileUtil.PATH_HASHING_STRATEGY) + private inner class InlineFunctionsFilesMap(storageFile: File) : BasicMap>(storageFile, PathCollectionExternalizer) { + override val keyDescriptor: KeyDescriptor + get() = PathFunctionPairKeyDescriptor public fun add(sourcePath: String, jvmSignature: String, targetPath: String) { - val mapping = getMappingFromCache(sourcePath.normalizedPath) - val paths = mapping.getOrPut(jvmSignature) { THashSet(FileUtil.PATH_HASHING_STRATEGY) } - paths.add(targetPath.normalizedPath) - } - - public fun get(sourceFile: String, jvmSignature: String): Collection { - 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) + val key = PathFunctionPair(sourcePath, jvmSignature) + storage.appendData(key) { out -> + IOUtil.writeUTF(out, targetPath) } - - super.flush(memoryCachesOnly) } - override fun dumpValue(value: Map>) = - value.dumpMap { it.dumpCollection() } - - private fun getMappingFromCache(sourcePath: String): MutableMap> { - val cachedValue = cache[sourcePath] - if (cachedValue != null) return cachedValue - - val mapping = storage[sourcePath] ?: emptyMap() - val mutableMapping = hashMapOf>() - - for ((k, v) in mapping) { - val paths = THashSet(v, FileUtil.PATH_HASHING_STRATEGY) - mutableMapping[k] = paths - } - - cache[sourcePath] = mutableMapping - return mutableMapping + public fun get(sourcePath: String, jvmSignature: String): Collection { + val key = PathFunctionPair(sourcePath, jvmSignature) + return storage[key] ?: emptySet() } + + override fun dumpKey(key: PathFunctionPair): String = + "(${key.path}, ${key.function})" + + override fun dumpValue(value: Collection) = + value.dumpCollection() } } @@ -821,27 +792,6 @@ private object StringToLongMapExternalizer : StringMapExternalizer() { } } -private object StringToPathsMapExternalizer : StringMapExternalizer>() { - override fun readValue(input: DataInput): Collection { - 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) { - output.writeInt(value.size()) - - for (path in value) { - IOUtil.writeUTF(output, path) - } - } -} - private object StringListExternalizer : DataExternalizer> { override fun save(out: DataOutput, value: List) { value.forEach { IOUtil.writeUTF(out, it) } @@ -877,9 +827,6 @@ private object PathCollectionExternalizer : DataExternalizer> private val File.normalizedPath: String get() = FileUtil.toSystemIndependentName(canonicalPath) -private val String.normalizedPath: String - get() = FileUtil.toSystemIndependentName(this) - TestOnly private fun , V> Map.dumpMap(dumpValue: (V)->String): String = StringBuilder { @@ -898,3 +845,46 @@ private fun , V> Map.dumpMap(dumpValue: (V)->String): St TestOnly public fun > Collection.dumpCollection(): String = "[${sort().map(Any::toString).join(", ")}]" + +private class PathFunctionPair( + public val path: String, + public val function: String +): Comparable { + 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 { + 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) + } + +} diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/storage/BasicMap.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/storage/BasicMap.kt index 995a47303e9..064748680df 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/storage/BasicMap.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/storage/BasicMap.kt @@ -25,16 +25,15 @@ import org.jetbrains.kotlin.utils.Printer import java.io.File import java.io.IOException -public abstract class BasicMap( +public abstract class BasicMap, V>( private val storageFile: File, private val valueExternalizer: DataExternalizer ) { - protected open val keyDescriptor: KeyDescriptor - get() = EnumeratorStringDescriptor() + protected abstract val keyDescriptor: KeyDescriptor - protected var storage: PersistentHashMap = createMap() + protected var storage: PersistentHashMap = createMap() - public fun contains(key: String): Boolean = storage.containsMapping(key) + public fun contains(key: K): Boolean = storage.containsMapping(key) public open fun clean() { try { @@ -74,7 +73,7 @@ public abstract class BasicMap( pushIndent() for (key in storage.getAllKeysWithExistingMapping().sort()) { - println("$key -> ${dumpValue(storage[key])}") + println("${dumpKey(key)} -> ${dumpValue(storage[key])}") } popIndent() @@ -84,8 +83,19 @@ public abstract class BasicMap( }.toString() } + protected abstract fun dumpKey(key: K): String protected abstract fun dumpValue(value: V): String - private fun createMap(): PersistentHashMap = + private fun createMap(): PersistentHashMap = PersistentHashMap(storageFile, keyDescriptor, valueExternalizer) +} + +public abstract class BasicStringMap( + private val storageFile: File, + private val valueExternalizer: DataExternalizer +) : BasicMap(storageFile, valueExternalizer) { + override val keyDescriptor: KeyDescriptor + get() = EnumeratorStringDescriptor() + + override fun dumpKey(key: String): String = key } \ No newline at end of file