[KLIB] Add a cacheable ZIP file system accessor

Creating a ZipFileSystem object is an expensive operation.
 A cacheable ZIP file system accessor caches ZipFileSystem
 objects and may improve the performance of the in place
 metadata reading operations from klibs.

Related to KT-51712
This commit is contained in:
Alexander Korepanov
2023-02-28 17:14:37 +01:00
committed by Space Team
parent e4406638bd
commit 8f22d6d36e
2 changed files with 37 additions and 1 deletions
@@ -16,3 +16,39 @@ object ZipFileSystemInPlaceAccessor : ZipFileSystemAccessor {
return zipFile.withZipFileSystem(action)
}
}
class ZipFileSystemCacheableAccessor(private val cacheLimit: Int) : ZipFileSystemAccessor {
private val loadFactor = 0.75f
private val initialCapacity = (1f + cacheLimit.toFloat() / loadFactor).toInt()
private val openedFileSystems = object : LinkedHashMap<File, FileSystem>(initialCapacity, loadFactor, true) {
override fun removeEldestEntry(eldest: Map.Entry<File, FileSystem>?): Boolean {
if (size > cacheLimit) {
eldest?.value?.close()
return true
}
return false
}
}
override fun <T> withZipFileSystem(zipFile: File, action: (FileSystem) -> T): T {
val fileSystem = openedFileSystems.getOrPut(zipFile) { zipFile.zipFileSystem() }
return action(fileSystem)
}
fun reset() {
var lastException: Exception? = null
for (fileSystem in openedFileSystems.values) {
try {
fileSystem.close()
} catch (e: Exception) {
lastException = e
}
}
openedFileSystems.clear()
lastException?.let {
throw it
}
}
}
@@ -17,7 +17,7 @@ import java.util.zip.ZipException
// See also:
// https://bugs.java.com/bugdatabase/view_bug.do?bug_id=7001822
// https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6994161
private fun File.zipFileSystem(create: Boolean = false): FileSystem {
internal fun File.zipFileSystem(create: Boolean = false): FileSystem {
val attributes = hashMapOf("create" to create.toString())
// There is no FileSystems.newFileSystem overload accepting the attribute map.