[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:
committed by
Space Team
parent
e4406638bd
commit
8f22d6d36e
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user