Optimize Strings representation at FastJarHandler

This commit is contained in:
Denis.Zharkov
2021-08-03 18:23:11 +03:00
committed by teamcityserver
parent 4e66fd29e0
commit bc75a21852
3 changed files with 52 additions and 11 deletions
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cli.jvm.compiler.jarfs
class ByteArrayCharSequence(
private val bytes: ByteArray,
private val start: Int = 0,
private val end: Int = bytes.size
) : CharSequence {
override fun hashCode(): Int {
error("Do not try computing hashCode ByteArrayCharSequence")
}
override fun equals(other: Any?): Boolean {
error("Do not try comparing ByteArrayCharSequence")
}
override val length get() = end - start
override fun get(index: Int): Char = bytes[index + start].toChar()
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
if (startIndex == 0 && endIndex == length) return this
return ByteArrayCharSequence(bytes, start + startIndex, start + endIndex)
}
override fun toString(): String {
val chars = CharArray(length)
for (i in 0 until length) {
chars[i] = bytes[i + start].toChar()
}
return String(chars)
}
}
@@ -4,6 +4,7 @@
*/
package org.jetbrains.kotlin.cli.jvm.compiler.jarfs
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VirtualFile
import java.io.File
import java.io.FileNotFoundException
@@ -22,7 +23,9 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) {
val mappedByteBuffer = randomAccessFile.channel.map(FileChannel.MapMode.READ_ONLY, 0, randomAccessFile.length())
try {
entries = mappedByteBuffer.parseCentralDirectory()
cachedManifest = entries.singleOrNull { it.relativePath == MANIFEST_PATH }?.let(mappedByteBuffer::contentsToByteArray)
cachedManifest =
entries.singleOrNull { StringUtil.equals(MANIFEST_PATH, it.relativePath) }
?.let(mappedByteBuffer::contentsToByteArray)
} finally {
with(fileSystem) {
mappedByteBuffer.unmapBuffer()
@@ -66,8 +69,8 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) {
)
}
private fun getOrCreateDirectory(entryName: String, directories: MutableMap<String, FastJarVirtualFile>): FastJarVirtualFile {
return directories.getOrPut(entryName) {
private fun getOrCreateDirectory(entryName: CharSequence, directories: MutableMap<String, FastJarVirtualFile>): FastJarVirtualFile {
return directories.getOrPut(entryName.toString()) {
val (parentPath, shortName) = entryName.splitPath()
val parentFile = getOrCreateDirectory(parentPath, directories)
@@ -75,7 +78,7 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) {
}
}
private fun String.splitPath(): Pair<String, String> {
private fun CharSequence.splitPath(): Pair<CharSequence, CharSequence> {
var slashIndex = this.length - 1
while (slashIndex >= 0 && this[slashIndex] != '/') {
@@ -83,7 +86,7 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) {
}
if (slashIndex == -1) return Pair("", this)
return Pair(substring(0, slashIndex), substring(slashIndex + 1))
return Pair(subSequence(0, slashIndex), subSequence(slashIndex + 1, this.length))
}
fun findFileByPath(pathInJar: String): VirtualFile? {
@@ -92,7 +95,7 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) {
fun contentsToByteArray(zipEntryDescription: ZipEntryDescription): ByteArray {
val relativePath = zipEntryDescription.relativePath
if (relativePath == MANIFEST_PATH) return cachedManifest ?: throw FileNotFoundException("$file!/$relativePath")
if (StringUtil.equals(relativePath, MANIFEST_PATH)) return cachedManifest ?: throw FileNotFoundException("$file!/$relativePath")
return fileSystem.cachedOpenFileHandles[file].use {
synchronized(it) {
it.get().second.contentsToByteArray(zipEntryDescription)
@@ -12,12 +12,12 @@ import java.util.zip.Inflater
class ZipEntryDescription(
val relativePath: String,
val relativePath: CharSequence,
val compressedSize: Int,
val uncompressedSize: Int,
val offsetInFile: Int,
val compressionKind: CompressionKind,
val fileNameSize: Int
val fileNameSize: Int,
) {
enum class CompressionKind {
@@ -101,7 +101,7 @@ fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
val name =
if (bytesForName.all { it >= 0 })
String(bytesForName.asASCICharArray())
ByteArrayCharSequence(bytesForName)
else
String(bytesForName, Charsets.UTF_8)
@@ -126,6 +126,4 @@ fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
return result
}
private fun ByteArray.asASCICharArray(): CharArray = CharArray(size) { this@asASCICharArray[it].toChar() }
private fun ByteBuffer.getUnsignedShort(offset: Int): Int = java.lang.Short.toUnsignedInt(getShort(offset))