diff --git a/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipFileSystemAccessor.kt b/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipFileSystemAccessor.kt index 0a95c722129..a74b2a8fae7 100644 --- a/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipFileSystemAccessor.kt +++ b/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipFileSystemAccessor.kt @@ -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(initialCapacity, loadFactor, true) { + override fun removeEldestEntry(eldest: Map.Entry?): Boolean { + if (size > cacheLimit) { + eldest?.value?.close() + return true + } + return false + } + } + + override fun 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 + } + } +} diff --git a/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipUtil.kt b/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipUtil.kt index 4d01e871e2b..c78daf40388 100644 --- a/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipUtil.kt +++ b/compiler/util-io/src/org/jetbrains/kotlin/konan/file/ZipUtil.kt @@ -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.