Skip to content

Commit b9503bb

Browse files
authored
Reduce duplicated SimpleRelocator to improve performance (#1271)
* Mark includes and excludes ad MutableSet, so that we can override `equals` and `hashcode`. * Mark `withDebug` for testing * Reduce duplicates for `packageRelocators` * Revert "Mark `withDebug` for testing" This reverts commit 6a16b57. * Check relocator count in `autoRelocation` * Remove `ObjectFactory` from ctor * Update changelog * Cleanups
1 parent 26e6d4d commit b9503bb

File tree

10 files changed

+66
-55
lines changed

10 files changed

+66
-55
lines changed

api/shadow.api

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,21 @@ public final class com/github/jengelman/gradle/plugins/shadow/relocation/Relocat
130130
}
131131

132132
public class com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator : com/github/jengelman/gradle/plugins/shadow/relocation/Relocator {
133-
public fun <init> (Lorg/gradle/api/model/ObjectFactory;)V
134-
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Ljava/lang/String;)V
135-
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Ljava/lang/String;Ljava/lang/String;)V
136-
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V
137-
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V
138-
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Z)V
139-
public synthetic fun <init> (Lorg/gradle/api/model/ObjectFactory;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
133+
public fun <init> ()V
134+
public fun <init> (Ljava/lang/String;)V
135+
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
136+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V
137+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V
138+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Z)V
139+
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
140140
public fun applyToSourceContent (Ljava/lang/String;)Ljava/lang/String;
141141
public fun canRelocateClass (Ljava/lang/String;)Z
142142
public fun canRelocatePath (Ljava/lang/String;)Z
143+
public fun equals (Ljava/lang/Object;)Z
143144
public fun exclude (Ljava/lang/String;)Lcom/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator;
144-
public final fun getExcludes ()Lorg/gradle/api/provider/SetProperty;
145-
public final fun getIncludes ()Lorg/gradle/api/provider/SetProperty;
145+
public final fun getExcludes ()Ljava/util/Set;
146+
public final fun getIncludes ()Ljava/util/Set;
147+
public fun hashCode ()I
146148
public fun include (Ljava/lang/String;)Lcom/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator;
147149
public fun relocateClass-XBGRxQs (Ljava/lang/String;)Ljava/lang/String;
148150
public fun relocatePath-bvWaKNU (Ljava/lang/String;)Ljava/lang/String;

src/docs/changes/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
**Changed**
1111

1212
- **BREAKING CHANGE:** Move tracking unused classes logic out of `ShadowCopyAction`. ([#1257](https://github.com/GradleUp/shadow/pull/1257))
13+
- Reduce duplicated `SimpleRelocator` to improve performance. ([#1271](https://github.com/GradleUp/shadow/pull/1271))
1314

1415
**Removed**
1516

src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.github.jengelman.gradle.plugins.shadow
22

33
import assertk.assertFailure
44
import assertk.assertThat
5+
import assertk.assertions.contains
56
import assertk.assertions.isEmpty
67
import assertk.assertions.isInstanceOf
78
import assertk.assertions.isNotEmpty
@@ -15,6 +16,7 @@ import kotlin.io.path.appendText
1516
import kotlin.io.path.writeText
1617
import org.junit.jupiter.api.Test
1718
import org.junit.jupiter.params.ParameterizedTest
19+
import org.junit.jupiter.params.provider.Arguments
1820
import org.junit.jupiter.params.provider.MethodSource
1921
import org.opentest4j.AssertionFailedError
2022

@@ -36,7 +38,7 @@ class RelocationTest : BasePluginTest() {
3638
)
3739
val entryPrefix = relocationPrefix.replace('.', '/')
3840

39-
run(shadowJarTask)
41+
val result = run(shadowJarTask, "--info")
4042

4143
assertThat(outputShadowJar).useAll {
4244
containsEntries(
@@ -48,6 +50,10 @@ class RelocationTest : BasePluginTest() {
4850
*junitEntries,
4951
)
5052
}
53+
// Make sure the relocator count is aligned with the number of unique packages in junit jar.
54+
assertThat(result.output).contains(
55+
"Relocator count: 6.",
56+
)
5157
}
5258

5359
@Issue(
@@ -345,9 +351,9 @@ class RelocationTest : BasePluginTest() {
345351
@JvmStatic
346352
fun prefixProvider() = listOf(
347353
// The default values.
348-
arrayOf(ShadowBasePlugin.SHADOW),
349-
arrayOf("new.pkg"),
350-
arrayOf("new/path"),
354+
Arguments.of(ShadowBasePlugin.SHADOW),
355+
Arguments.of("new.pkg"),
356+
Arguments.of("new/path"),
351357
)
352358
}
353359
}

src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package com.github.jengelman.gradle.plugins.shadow.relocation
22

3-
import com.github.jengelman.gradle.plugins.shadow.internal.setProperty
43
import java.util.regex.Pattern
54
import org.codehaus.plexus.util.SelectorUtils
6-
import org.gradle.api.model.ObjectFactory
7-
import org.gradle.api.provider.SetProperty
85
import org.gradle.api.tasks.Input
96

107
/**
@@ -16,7 +13,6 @@ import org.gradle.api.tasks.Input
1613
*/
1714
@CacheableRelocator
1815
public open class SimpleRelocator @JvmOverloads constructor(
19-
objectFactory: ObjectFactory,
2016
pattern: String? = null,
2117
shadedPattern: String? = null,
2218
includes: List<String>? = null,
@@ -31,10 +27,10 @@ public open class SimpleRelocator @JvmOverloads constructor(
3127
private val sourcePathExcludes = mutableSetOf<String>()
3228

3329
@get:Input
34-
public val includes: SetProperty<String> = objectFactory.setProperty()
30+
public val includes: MutableSet<String> = mutableSetOf()
3531

3632
@get:Input
37-
public val excludes: SetProperty<String> = objectFactory.setProperty()
33+
public val excludes: MutableSet<String> = mutableSetOf()
3834

3935
init {
4036
if (rawString) {
@@ -71,7 +67,7 @@ public open class SimpleRelocator @JvmOverloads constructor(
7167

7268
if (!rawString) {
7369
// Create exclude pattern sets for sources.
74-
for (exclude in this.excludes.get()) {
70+
for (exclude in this.excludes) {
7571
// Excludes should be subpackages of the global pattern.
7672
if (exclude.startsWith(this.pattern)) {
7773
sourcePackageExcludes.add(
@@ -136,12 +132,39 @@ public open class SimpleRelocator @JvmOverloads constructor(
136132
return shadeSourceWithExcludes(content, pathPattern, shadedPathPattern, sourcePathExcludes)
137133
}
138134

135+
override fun equals(other: Any?): Boolean {
136+
if (this === other) return true
137+
if (other !is SimpleRelocator) return false
138+
return rawString == other.rawString &&
139+
pattern == other.pattern &&
140+
pathPattern == other.pathPattern &&
141+
shadedPattern == other.shadedPattern &&
142+
shadedPathPattern == other.shadedPathPattern &&
143+
sourcePackageExcludes == other.sourcePackageExcludes &&
144+
sourcePathExcludes == other.sourcePathExcludes &&
145+
includes == other.includes &&
146+
excludes == other.excludes
147+
}
148+
149+
override fun hashCode(): Int {
150+
var result = rawString.hashCode()
151+
result = 31 * result + pattern.hashCode()
152+
result = 31 * result + pathPattern.hashCode()
153+
result = 31 * result + shadedPattern.hashCode()
154+
result = 31 * result + shadedPathPattern.hashCode()
155+
result = 31 * result + sourcePackageExcludes.hashCode()
156+
result = 31 * result + sourcePathExcludes.hashCode()
157+
result = 31 * result + includes.hashCode()
158+
result = 31 * result + excludes.hashCode()
159+
return result
160+
}
161+
139162
private fun isIncluded(path: String): Boolean {
140-
return includes.get().isEmpty() || includes.get().any { SelectorUtils.matchPath(it, path, "/", true) }
163+
return includes.isEmpty() || includes.any { SelectorUtils.matchPath(it, path, "/", true) }
141164
}
142165

143166
private fun isExcluded(path: String): Boolean {
144-
return excludes.get().any { SelectorUtils.matchPath(it, path, "/", true) }
167+
return excludes.any { SelectorUtils.matchPath(it, path, "/", true) }
145168
}
146169

147170
private companion object {

src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ public open class ShadowCopyAction(
172172
private val visitedFiles = mutableSetOf<String>()
173173

174174
init {
175+
logger.info("Relocator count: ${relocators.size}.")
175176
if (encoding != null) {
176177
this.zipOutStr.setEncoding(encoding)
177178
}

src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import org.gradle.api.Action
3030
import org.gradle.api.artifacts.Configuration
3131
import org.gradle.api.file.ConfigurableFileCollection
3232
import org.gradle.api.file.DuplicatesStrategy
33-
import org.gradle.api.file.FileCollection
3433
import org.gradle.api.internal.DocumentationRegistry
3534
import org.gradle.api.internal.file.FileResolver
3635
import org.gradle.api.internal.file.copy.CopyAction
@@ -242,7 +241,7 @@ public abstract class ShadowJar :
242241
destination: String,
243242
action: Action<SimpleRelocator>?,
244243
): ShadowJar = apply {
245-
val relocator = SimpleRelocator(objectFactory, pattern, destination)
244+
val relocator = SimpleRelocator(pattern, destination)
246245
addRelocator(relocator, action)
247246
}
248247

@@ -303,17 +302,14 @@ public abstract class ShadowJar :
303302
private val packageRelocators: List<SimpleRelocator>
304303
get() {
305304
if (!enableRelocation.get()) return emptyList()
306-
307305
val prefix = relocationPrefix.get()
308-
// Must cast configurations to Set<FileCollection> to fix type mismatch in runtime.
309-
return (configurations.get() as Set<FileCollection>).flatMap { configuration ->
310-
configuration.files.flatMap { file ->
311-
JarFile(file).use { jarFile ->
312-
jarFile.entries().toList()
313-
.filter { it.name.endsWith(".class") && it.name != "module-info.class" }
314-
.map { it.name.substringBeforeLast('/').replace('/', '.') }
315-
.map { SimpleRelocator(objectFactory, it, "$prefix.$it") }
316-
}
306+
return includedDependencies.files.flatMap { file ->
307+
JarFile(file).use { jarFile ->
308+
jarFile.entries().toList()
309+
.filter { it.name.endsWith(".class") && it.name != "module-info.class" }
310+
.map { it.name.substringBeforeLast('/').replace('/', '.') }
311+
.toSet()
312+
.map { SimpleRelocator(it, "$prefix.$it") }
317313
}
318314
}
319315
}

src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorTest.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import assertk.assertThat
44
import assertk.assertions.isEqualTo
55
import assertk.assertions.isFalse
66
import assertk.assertions.isTrue
7-
import com.github.jengelman.gradle.plugins.shadow.util.SimpleRelocator
87
import org.junit.jupiter.api.Test
98

109
/**

src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformerTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import assertk.assertions.startsWith
1010
import assertk.fail
1111
import com.github.jengelman.gradle.plugins.shadow.internal.requireResourceAsStream
1212
import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
13-
import com.github.jengelman.gradle.plugins.shadow.util.SimpleRelocator
13+
import com.github.jengelman.gradle.plugins.shadow.relocation.SimpleRelocator
1414
import com.github.jengelman.gradle.plugins.shadow.util.zipOutputStream
1515
import java.io.ByteArrayOutputStream
1616
import java.net.URI

src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import assertk.assertions.isEqualTo
55
import assertk.assertions.isFalse
66
import assertk.assertions.isTrue
77
import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
8-
import com.github.jengelman.gradle.plugins.shadow.util.SimpleRelocator
8+
import com.github.jengelman.gradle.plugins.shadow.relocation.SimpleRelocator
99
import com.github.jengelman.gradle.plugins.shadow.util.zipOutputStream
1010
import java.io.InputStream
1111
import java.nio.file.Path
Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,12 @@
11
package com.github.jengelman.gradle.plugins.shadow.util
22

3-
import com.github.jengelman.gradle.plugins.shadow.relocation.SimpleRelocator
43
import java.io.OutputStream
54
import org.apache.tools.zip.ZipOutputStream
65
import org.gradle.api.model.ObjectFactory
76
import org.gradle.testfixtures.ProjectBuilder
87

98
val testObjectFactory: ObjectFactory = ProjectBuilder.builder().build().objects
109

11-
@Suppress("TestFunctionName")
12-
fun SimpleRelocator(
13-
pattern: String? = null,
14-
shadedPattern: String? = null,
15-
includes: List<String> = emptyList(),
16-
excludes: List<String> = emptyList(),
17-
rawString: Boolean = false,
18-
): SimpleRelocator = SimpleRelocator(
19-
objectFactory = testObjectFactory,
20-
pattern = pattern,
21-
shadedPattern = shadedPattern,
22-
includes = includes,
23-
excludes = excludes,
24-
rawString = rawString,
25-
)
26-
2710
fun OutputStream.zipOutputStream(): ZipOutputStream {
28-
return if (this is ZipOutputStream) this else ZipOutputStream(this)
11+
return this as? ZipOutputStream ?: ZipOutputStream(this)
2912
}

0 commit comments

Comments
 (0)