From 9a8a6d7c15cf18d10a57e4bb26081895c7adc8b3 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurkevich Date: Wed, 24 Mar 2021 18:07:20 +0300 Subject: [PATCH] [workspace model] IDEA-265068 Speedup the search of existing `FilePathNode` with the same `contentId` To simplify the change we use `ObjectOpenCustomHashSet` with custom hashing strategy base on `FilePathNode.contentId` It will increase memory usage from 45Mb to 49Mb for project attached to the ticket which contains 200k of objects. GitOrigin-RevId: a80b3ce3fcd6a075115de14ad6bb439fdfedde15 --- .../impl/url/VirtualFileUrlManagerImpl.kt | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/url/VirtualFileUrlManagerImpl.kt b/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/url/VirtualFileUrlManagerImpl.kt index 5c83dd3c3d88..20b58e429f6a 100644 --- a/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/url/VirtualFileUrlManagerImpl.kt +++ b/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/url/VirtualFileUrlManagerImpl.kt @@ -2,14 +2,15 @@ package com.intellij.workspaceModel.storage.impl.url import com.intellij.openapi.util.io.FileUtil -import com.intellij.util.SmartList import com.intellij.util.io.URLUtil import com.intellij.workspaceModel.storage.impl.IntIdGenerator import com.intellij.workspaceModel.storage.impl.VirtualFileNameStore import com.intellij.workspaceModel.storage.url.VirtualFileUrl import com.intellij.workspaceModel.storage.url.VirtualFileUrlManager +import it.unimi.dsi.fastutil.Hash.Strategy import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import it.unimi.dsi.fastutil.ints.IntArrayList +import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet open class VirtualFileUrlManagerImpl : VirtualFileUrlManager { private val idGenerator = IntIdGenerator() @@ -236,12 +237,10 @@ open class VirtualFileUrlManagerImpl : VirtualFileUrlManager { internal inner class FilePathNode(val nodeId: Int, val contentId: Int, val parent: FilePathNode? = null) { private var virtualFileUrl: VirtualFileUrl? = null - private var children: MutableList? = null + private var children: ObjectOpenCustomHashSet? = null fun findChild(nameId: Int): FilePathNode? { - // If search of child node will be slow, replace SmartList to THashSet - // For now SmartList reduce 500Kb memory on IDEA project - return children?.find { it.contentId == nameId } + return children?.get(FilePathNode(0, nameId)) } fun getSubtreeNodes(): List { @@ -276,7 +275,7 @@ open class VirtualFileUrlManagerImpl : VirtualFileUrlManager { fun isEmpty() = children == null || children!!.isEmpty() private fun createChildrenList() { - if (children == null) children = SmartList() + if (children == null) children = ObjectOpenCustomHashSet(HASHING_STRATEGY) } fun print(): String { @@ -304,4 +303,20 @@ open class VirtualFileUrlManagerImpl : VirtualFileUrlManager { } } } + + private companion object { + val HASHING_STRATEGY: Strategy = object : Strategy { + override fun equals(node1: FilePathNode?, node2: FilePathNode?): Boolean { + if (node1 === node2) { + return true + } + if (node1 == null || node2 == null) { + return false + } + return node1.contentId == node2.contentId + } + + override fun hashCode(node: FilePathNode?): Int = node?.contentId ?: 0 + } + } } \ No newline at end of file