From f81f28569fa16d958f246f0442059bf0121042cf Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Mon, 2 Aug 2021 21:23:24 +0300 Subject: [PATCH] Get rid of last map in FastJarHandler --- .../cli/jvm/compiler/jarfs/FastJarHandler.kt | 23 +++++++++++-------- .../jvm/compiler/jarfs/FastJarVirtualFile.kt | 12 +++++----- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarHandler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarHandler.kt index 9c148511f21..719dc82cd46 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarHandler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarHandler.kt @@ -14,15 +14,15 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) { private val myRoot: VirtualFile? internal val file = File(path) - private val ourEntryMap: Map private val cachedManifest: ByteArray? init { + val entries: List RandomAccessFile(file, "r").use { randomAccessFile -> val mappedByteBuffer = randomAccessFile.channel.map(FileChannel.MapMode.READ_ONLY, 0, randomAccessFile.length()) try { - ourEntryMap = mappedByteBuffer.parseCentralDirectory().associateBy { it.relativePath } - cachedManifest = ourEntryMap[MANIFEST_PATH]?.let(mappedByteBuffer::contentsToByteArray) + entries = mappedByteBuffer.parseCentralDirectory() + cachedManifest = entries.singleOrNull { it.relativePath == MANIFEST_PATH }?.let(mappedByteBuffer::contentsToByteArray) } finally { with(fileSystem) { mappedByteBuffer.unmapBuffer() @@ -30,12 +30,14 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) { } } - myRoot = FastJarVirtualFile(this, "", -1, null) + myRoot = FastJarVirtualFile(this, "", -1, myParent = null, entryDescription = null) - val filesByRelativePath = HashMap(ourEntryMap.size) + // ByteArrayCharSequence should not be used instead of String + // because the former class does not support equals/hashCode properly + val filesByRelativePath = HashMap(entries.size) filesByRelativePath[""] = myRoot - for (entryDescription in ourEntryMap.values) { + for (entryDescription in entries) { if (!entryDescription.isDirectory) { createFile(entryDescription, filesByRelativePath) } else { @@ -59,7 +61,8 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) { return FastJarVirtualFile( this, shortName, if (entry.isDirectory) -1 else entry.uncompressedSize, - parentFile + parentFile, + entry, ) } @@ -68,7 +71,7 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) { val (parentPath, shortName) = entryName.splitPath() val parentFile = getOrCreateDirectory(parentPath, directories) - FastJarVirtualFile(this, shortName, -1, parentFile) + FastJarVirtualFile(this, shortName, -1, parentFile, entryDescription = null) } } @@ -87,9 +90,9 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) { return myRoot?.findFileByRelativePath(pathInJar) } - fun contentsToByteArray(relativePath: String): ByteArray { + fun contentsToByteArray(zipEntryDescription: ZipEntryDescription): ByteArray { + val relativePath = zipEntryDescription.relativePath if (relativePath == MANIFEST_PATH) return cachedManifest ?: throw FileNotFoundException("$file!/$relativePath") - val zipEntryDescription = ourEntryMap[relativePath] ?: throw FileNotFoundException("$file!/$relativePath") return fileSystem.cachedOpenFileHandles[file].use { synchronized(it) { it.get().second.contentsToByteArray(zipEntryDescription) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarVirtualFile.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarVirtualFile.kt index 37ba1cfc6c4..0dd4c9ee8bc 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarVirtualFile.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/jarfs/FastJarVirtualFile.kt @@ -4,7 +4,6 @@ */ package org.jetbrains.kotlin.cli.jvm.compiler.jarfs -import com.intellij.openapi.util.Couple import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VirtualFile @@ -17,7 +16,8 @@ internal class FastJarVirtualFile( private val myHandler: FastJarHandler, private val myName: CharSequence, private val myLength: Int, - private val myParent: FastJarVirtualFile? + private val myParent: FastJarVirtualFile?, + private val entryDescription: ZipEntryDescription?, ) : VirtualFile() { private var myChildrenArray = EMPTY_ARRAY @@ -85,10 +85,8 @@ internal class FastJarVirtualFile( @Throws(IOException::class) override fun contentsToByteArray(): ByteArray { - val pair: Couple = FastJarFileSystem.splitPath( - path - ) - return myHandler.contentsToByteArray(pair.second) + if (entryDescription == null) return EMPTY_BYTE_ARRAY + return myHandler.contentsToByteArray(entryDescription) } override fun getTimeStamp(): Long = 0 @@ -106,3 +104,5 @@ internal class FastJarVirtualFile( return 0 } } + +private val EMPTY_BYTE_ARRAY = ByteArray(0)