Skip to content

Commit

Permalink
fix: add cache for OrtDependency model objects to OrtModelBuilder
Browse files Browse the repository at this point in the history
Only create one 'OrtDependency' for each 'ResolvedComponentResult'.
The 'ResolvedComponentResult' is immutable and therefore all
'OrtDependency' object derived from the same 'ResolvedComponentResult'
have the same content. Hence, we can reuse these objects to save memory
and computation time.

Without this, large builds seem to run forever:
oss-review-toolkit#9763

This PR is a refined version of the fix posted in the error description
of oss-review-toolkit#9763

Signed-off-by: Jendrik Johannes <[email protected]>
  • Loading branch information
jjohannes committed Jan 23, 2025
1 parent 1d9c9c8 commit 60bbc2e
Showing 1 changed file with 14 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.artifacts.component.ProjectComponentSelector
import org.gradle.api.artifacts.result.DependencyResult
import org.gradle.api.artifacts.result.ResolvedArtifactResult
import org.gradle.api.artifacts.result.ResolvedComponentResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.artifacts.result.UnresolvedDependencyResult
import org.gradle.api.internal.GradleInternal
Expand All @@ -56,6 +57,9 @@ internal class OrtModelBuilder : ToolingModelBuilder {
private val warnings = mutableListOf<String>()
private val globalDependencySubtrees = mutableMapOf<String, List<OrtDependency>>()

// Only create one 'OrtDependency' for each 'ResolvedComponentResult'
private val ortDependencyCache = mutableMapOf<ResolvedComponentResult, OrtDependency>()

override fun canBuild(modelName: String): Boolean = modelName == OrtDependencyTreeModel::class.java.name

override fun buildAll(modelName: String, project: Project): OrtDependencyTreeModel {
Expand Down Expand Up @@ -165,6 +169,10 @@ internal class OrtModelBuilder : ToolingModelBuilder {
// Cut the graph on cyclic dependencies.
if (id in visited) return@mapNotNull null

if (ortDependencyCache.containsKey(selectedComponent)) {
return@mapNotNull ortDependencyCache[selectedComponent]
}

when (id) {
is ModuleComponentIdentifier -> {
val pomFile = if (selectedComponent is ResolvedComponentResultInternal) {
Expand Down Expand Up @@ -211,7 +219,7 @@ internal class OrtModelBuilder : ToolingModelBuilder {
selectedComponent.dependencies.toOrtDependencies(poms, visited + id)
}

OrtDependencyImpl(
val dependency = OrtDependencyImpl(
groupId = id.group,
artifactId = id.module,
version = id.version,
Expand All @@ -232,13 +240,15 @@ internal class OrtModelBuilder : ToolingModelBuilder {
},
localPath = null
)
ortDependencyCache[selectedComponent] = dependency
dependency
}

is ProjectComponentIdentifier -> {
val moduleId = selectedComponent.moduleVersion ?: return@mapNotNull null
val dependencies = selectedComponent.dependencies.toOrtDependencies(poms, visited + id)

OrtDependencyImpl(
val dependency = OrtDependencyImpl(
groupId = moduleId.group,
artifactId = moduleId.name,
version = moduleId.version.takeUnless { it == "unspecified" }.orEmpty(),
Expand All @@ -251,6 +261,8 @@ internal class OrtModelBuilder : ToolingModelBuilder {
mavenModel = null,
localPath = id.projectPath
)
ortDependencyCache[selectedComponent] = dependency
dependency
}

else -> {
Expand Down

0 comments on commit 60bbc2e

Please sign in to comment.