Skip to content

Commit

Permalink
fix(spdx-utils): Fix a performance issue in SpdxExpression::and()
Browse files Browse the repository at this point in the history
31b9be8 introduced an `equals()` into `SpdxCompoundExpression::and`. For
packages with large amounts of detected licenses including ones with
`OR` operators, the performance of the `and` function becomes so poor
that the evaluator runs for 3 days (with the open source `ort-config`
rules, without terminating. Also the reporter performance degrades from
less than 30 seconds to 3 hours.

Unfortunately the call tree involved is so complicated that there is no
simple fix for this. `equals()` involves recursive `validChoices()`
calls which in turn call `equals()` again when computing distinctness or
inserting further `SpdxExpressions` into sets.

Revert the change to fix the problem in a timely manner. Note that it
makes sense to bring back the now reverted functionality, but the code
should be refactored first to produce more managable call trees.

Fixes: #9902.

This reverts commit 31b9be8.

Signed-off-by: Frank Viernau <[email protected]>
  • Loading branch information
fviernau committed Feb 7, 2025
1 parent c96f2e8 commit a212b72
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 6 deletions.
6 changes: 2 additions & 4 deletions utils/spdx/src/main/kotlin/SpdxExpression.kt
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,12 @@ sealed class SpdxExpression {
/**
* Concatenate [this][SpdxExpression] and [other] using [SpdxOperator.AND].
*/
infix fun and(other: SpdxExpression) =
takeIf { this == other } ?: SpdxCompoundExpression(SpdxOperator.AND, listOf(this, other))
infix fun and(other: SpdxExpression) = SpdxCompoundExpression(SpdxOperator.AND, listOf(this, other))

/**
* Concatenate [this][SpdxExpression] and [other] using [SpdxOperator.OR].
*/
infix fun or(other: SpdxExpression) =
takeIf { this == other } ?: SpdxCompoundExpression(SpdxOperator.OR, listOf(this, other))
infix fun or(other: SpdxExpression) = SpdxCompoundExpression(SpdxOperator.OR, listOf(this, other))
}

/**
Expand Down
4 changes: 2 additions & 2 deletions utils/spdx/src/test/kotlin/SpdxExpressionChoiceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,9 @@ class SpdxExpressionChoiceTest : WordSpec({
val choices = "(a OR b) AND (a OR b)".toSpdx().validChoices()

choices.map { it.toString() } should containExactlyInAnyOrder(
"a",
"a AND a",
"b AND a",
"b"
"b AND b"
)
}

Expand Down

0 comments on commit a212b72

Please sign in to comment.