Skip to content

Commit 84e7e05

Browse files
committed
improve fill missing speed
1 parent 48e7b99 commit 84e7e05

File tree

6 files changed

+138
-44
lines changed

6 files changed

+138
-44
lines changed

cli/src/main/kotlin/xyz/wagyourtail/unimined/mapping/cli/Main.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import xyz.wagyourtail.unimined.mapping.cli.Main.Companion.LOGGER
1818
import xyz.wagyourtail.unimined.mapping.formats.FormatRegistry
1919
import xyz.wagyourtail.unimined.mapping.propogator.Propagator
2020
import xyz.wagyourtail.unimined.mapping.tree.MemoryMappingTree
21-
import xyz.wagyourtail.unimined.mapping.visitor.delegate.copyTo
21+
import xyz.wagyourtail.unimined.mapping.visitor.delegate.copyNames
2222
import kotlin.time.measureTime
2323

2424
fun main(vararg args: String) {
@@ -72,7 +72,7 @@ class Main: CliktCommand(printHelpOnEmptyArgs = true) {
7272
for ((from, to) in copyMissingMap) {
7373
LOGGER.info { "Copying missing names from $from to ${to.joinToString(", ")}" }
7474
val t = measureTime {
75-
mappings.accept(mappings.copyTo(Namespace(from), to.map { Namespace(it) }.toSet()))
75+
mappings.accept(mappings.copyNames(Namespace(from), to.map { Namespace(it) }.toSet()))
7676
}
7777
LOGGER.info { "Copied missing names in ${t.inWholeMilliseconds}ms" }
7878
}

src/commonMain/kotlin/xyz/wagyourtail/unimined/mapping/resolver/MappingResolver.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package xyz.wagyourtail.unimined.mapping.resolver
22

33
import io.github.oshai.kotlinlogging.KotlinLogging
4-
import kotlinx.coroutines.async
5-
import kotlinx.coroutines.awaitAll
6-
import kotlinx.coroutines.coroutineScope
74
import kotlinx.coroutines.sync.Mutex
85
import kotlinx.coroutines.sync.withLock
96
import okio.Buffer
@@ -25,7 +22,8 @@ import xyz.wagyourtail.unimined.mapping.formats.zip.ZipFS
2522
import xyz.wagyourtail.unimined.mapping.tree.MemoryMappingTree
2623
import xyz.wagyourtail.unimined.mapping.util.*
2724
import xyz.wagyourtail.unimined.mapping.visitor.MappingVisitor
28-
import xyz.wagyourtail.unimined.mapping.visitor.delegate.copyTo
25+
import xyz.wagyourtail.unimined.mapping.visitor.delegate.DelegateClassVisitor
26+
import xyz.wagyourtail.unimined.mapping.visitor.delegate.NameCopyDelegate
2927
import xyz.wagyourtail.unimined.mapping.visitor.delegate.nsFiltered
3028
import kotlin.jvm.JvmOverloads
3129

@@ -229,13 +227,15 @@ abstract class MappingResolver<T : MappingResolver<T>>(val name: String) {
229227

230228
// fill in missing names from dependent namespaces
231229
val filled = unmappedNs.toMutableSet()
230+
val toFill = mutableListOf<Pair<Namespace, Set<Namespace>>>()
232231
for (entry in sorted) {
233-
val toFill = entry.provides.map { it.first }.toSet() - filled
234-
if (toFill.isNotEmpty()) {
235-
resolved.accept(resolved.copyTo(entry.requires, toFill))
236-
filled.addAll(toFill)
232+
val targets = entry.provides.map { it.first }.toSet() - filled
233+
if (targets.isNotEmpty()) {
234+
filled.addAll(targets)
235+
toFill.add(entry.requires to targets)
237236
}
238237
}
238+
resolved.fillMissingNames(*toFill.toTypedArray())
239239

240240
LOGGER.info { "Re-resolving fields and methods..." }
241241

src/commonMain/kotlin/xyz/wagyourtail/unimined/mapping/tree/MemoryMappingTree.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import xyz.wagyourtail.unimined.mapping.jvms.four.two.one.PackageName
1212
import xyz.wagyourtail.unimined.mapping.tree.node._class.ClassNode
1313
import xyz.wagyourtail.unimined.mapping.tree.node._constant.ConstantGroupNode
1414
import xyz.wagyourtail.unimined.mapping.tree.node._package.PackageNode
15+
import xyz.wagyourtail.unimined.mapping.visitor.ClassVisitor
1516
import xyz.wagyourtail.unimined.mapping.visitor.ConstantGroupVisitor
1617
import xyz.wagyourtail.unimined.mapping.visitor.MappingVisitor
1718
import xyz.wagyourtail.unimined.mapping.visitor.PackageVisitor
19+
import xyz.wagyourtail.unimined.mapping.visitor.delegate.*
1820

1921
class MemoryMappingTree : AbstractMappingTree() {
2022
private val _namespaces = mutableListOf<Namespace>()
@@ -157,4 +159,32 @@ class MemoryMappingTree : AbstractMappingTree() {
157159
}
158160
}
159161

162+
/**
163+
* function to fill missing names
164+
*/
165+
suspend fun fillMissingNames(vararg toFill: Pair<Namespace, Set<Namespace>>) {
166+
coroutineScope {
167+
listOf(
168+
async {
169+
packages.parallelMap {
170+
val nameMap = it.names.toMutableMap()
171+
NameCopyDelegate.fillNames(toFill, nameMap)
172+
it.setNames(nameMap)
173+
}
174+
},
175+
async {
176+
classes.parallelMap {
177+
val nameMap = it.names.toMutableMap()
178+
NameCopyDelegate.fillNames(toFill, nameMap)
179+
it.setNames(nameMap)
180+
it.acceptInner(
181+
DelegateClassVisitor(it, NameCopyDelegate(*toFill)),
182+
namespaces
183+
)
184+
}
185+
}
186+
).awaitAll()
187+
}
188+
}
189+
160190
}

src/commonMain/kotlin/xyz/wagyourtail/unimined/mapping/visitor/delegate/NameCopyVisitor.kt

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,41 @@ import xyz.wagyourtail.unimined.mapping.jvms.four.two.one.InternalName
77
import xyz.wagyourtail.unimined.mapping.jvms.four.two.one.PackageName
88
import xyz.wagyourtail.unimined.mapping.visitor.*
99

10-
fun MappingVisitor.copyTo(from: Namespace, to: Set<Namespace>, onlyMissing: Boolean = true): MappingVisitor {
11-
return DelegateMappingVisitor(this, NameCopyDelegate(from, to, onlyMissing))
10+
fun MappingVisitor.copyNames(from: Namespace, to: Set<Namespace>, onlyMissing: Boolean = true): MappingVisitor {
11+
return DelegateMappingVisitor(this, NameCopyDelegate(from to to, onlyMissing = onlyMissing))
1212
}
1313

14-
private class NameCopyDelegate(val from: Namespace, val to: Set<Namespace>, val onlyMissing: Boolean) : NullDelegator() {
14+
fun MappingVisitor.copyNames(vararg from: Pair<Namespace, Set<Namespace>>, onlyMissing: Boolean = true): MappingVisitor {
15+
return DelegateMappingVisitor(this, NameCopyDelegate(*from, onlyMissing = onlyMissing))
16+
}
17+
18+
class NameCopyDelegate(vararg val from: Pair<Namespace, Set<Namespace>>, val onlyMissing: Boolean = true) : NullDelegator() {
19+
20+
companion object {
1521

16-
fun Set<Namespace>.ifOnlyMissing(): Set<Namespace> {
17-
return if (onlyMissing) to - this else to
22+
fun Set<Namespace>.ifOnlyMissing(to: Set<Namespace>, onlyMissing: Boolean): Set<Namespace> {
23+
return if (onlyMissing) to - this else to
24+
}
25+
26+
fun <T> fillNames(toFill: Array<out Pair<Namespace, Set<Namespace>>>, names: MutableMap<Namespace, T>, onlyMissing: Boolean = true, fillWith: (T) -> T = { it }) {
27+
for ((from, to) in toFill) {
28+
val name = names[from] ?: continue
29+
for (namespace in names.keys.ifOnlyMissing(to, onlyMissing)) {
30+
names[namespace] = fillWith(name)
31+
}
32+
}
33+
}
1834
}
1935

2036
override fun visitClass(delegate: MappingVisitor, names: Map<Namespace, InternalName>): ClassVisitor? {
2137
val nameMap = names.toMutableMap()
22-
val name = nameMap[from] ?: return default.visitClass(delegate, nameMap)
23-
for (namespace in nameMap.keys.ifOnlyMissing()) {
24-
nameMap[namespace] = name
25-
}
38+
fillNames(from, nameMap, onlyMissing)
2639
return default.visitClass(delegate, nameMap)
2740
}
2841

2942
override fun visitPackage(delegate: MappingVisitor, names: Map<Namespace, PackageName>): PackageVisitor? {
3043
val nameMap = names.toMutableMap()
31-
val name = nameMap[from] ?: return default.visitPackage(delegate, nameMap)
32-
for (namespace in nameMap.keys.ifOnlyMissing()) {
33-
nameMap[namespace] = name
34-
}
44+
fillNames(from, nameMap, onlyMissing)
3545
return default.visitPackage(delegate, nameMap)
3646
}
3747

@@ -40,10 +50,7 @@ private class NameCopyDelegate(val from: Namespace, val to: Set<Namespace>, val
4050
names: Map<Namespace, Pair<String, FieldDescriptor?>>
4151
): FieldVisitor? {
4252
val nameMap = names.toMutableMap()
43-
val name = nameMap[from] ?: return default.visitField(delegate, nameMap)
44-
for (namespace in nameMap.keys.ifOnlyMissing()) {
45-
nameMap[namespace] = name.first to null
46-
}
53+
fillNames(from, nameMap, onlyMissing) { it.first to null }
4754
return default.visitField(delegate, nameMap)
4855
}
4956

@@ -52,10 +59,7 @@ private class NameCopyDelegate(val from: Namespace, val to: Set<Namespace>, val
5259
names: Map<Namespace, Pair<String, MethodDescriptor?>>
5360
): MethodVisitor? {
5461
val nameMap = names.toMutableMap()
55-
val name = nameMap[from] ?: return default.visitMethod(delegate, nameMap)
56-
for (namespace in nameMap.keys.ifOnlyMissing()) {
57-
nameMap[namespace] = name.first to null
58-
}
62+
fillNames(from, nameMap, onlyMissing) { it.first to null }
5963
return default.visitMethod(delegate, nameMap)
6064
}
6165

@@ -66,10 +70,7 @@ private class NameCopyDelegate(val from: Namespace, val to: Set<Namespace>, val
6670
names: Map<Namespace, String>
6771
): ParameterVisitor? {
6872
val nameMap = names.toMutableMap()
69-
val name = nameMap[from] ?: return default.visitParameter(delegate, index, lvOrd, nameMap)
70-
for (namespace in nameMap.keys.ifOnlyMissing()) {
71-
nameMap[namespace] = name
72-
}
73+
fillNames(from, nameMap, onlyMissing)
7374
return default.visitParameter(delegate, index, lvOrd, nameMap)
7475
}
7576

@@ -80,10 +81,7 @@ private class NameCopyDelegate(val from: Namespace, val to: Set<Namespace>, val
8081
names: Map<Namespace, String>
8182
): LocalVariableVisitor? {
8283
val nameMap = names.toMutableMap()
83-
val name = nameMap[from] ?: return default.visitLocalVariable(delegate, lvOrd, startOp, nameMap)
84-
for (namespace in nameMap.keys.ifOnlyMissing()) {
85-
nameMap[namespace] = name
86-
}
84+
fillNames(from, nameMap, onlyMissing)
8785
return default.visitLocalVariable(delegate, lvOrd, startOp, nameMap)
8886
}
8987

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package xyz.wagyourtail.unimined.mapping.test.delegate
2+
3+
import kotlinx.coroutines.test.runTest
4+
import okio.Buffer
5+
import okio.use
6+
import xyz.wagyourtail.unimined.mapping.Namespace
7+
import xyz.wagyourtail.unimined.mapping.formats.umf.UMFReader
8+
import xyz.wagyourtail.unimined.mapping.formats.umf.UMFWriter
9+
import xyz.wagyourtail.unimined.mapping.visitor.delegate.copyNames
10+
import kotlin.test.Test
11+
import kotlin.test.assertEquals
12+
13+
class NameCopyTest {
14+
15+
val ORIGINAL = """
16+
umf 1 0
17+
intermediary named extra
18+
c a b
19+
f a;Z b
20+
m a;()V b
21+
c d
22+
f d;Z
23+
""".trimIndent()
24+
25+
val FILLED_EXTRA = """
26+
umf 1 0
27+
intermediary named extra
28+
c a b b
29+
f a;Z b b
30+
m a;()V b b
31+
c d d d
32+
f d;Z d d
33+
""".trimIndent()
34+
35+
@Test
36+
fun testNameCopy() = runTest{
37+
val mappings = Buffer().use { input ->
38+
input.writeUtf8(ORIGINAL)
39+
UMFReader.read(input)
40+
}
41+
42+
val output = Buffer().use { output ->
43+
mappings.accept(UMFWriter.write(output, true).copyNames(Namespace("intermediary") to setOf(Namespace("named")), Namespace("named") to setOf(Namespace("extra"))))
44+
output.readUtf8()
45+
}
46+
47+
assertEquals(FILLED_EXTRA.trimEnd(), output.trimEnd().replace('\t', ' '))
48+
49+
}
50+
51+
@Test
52+
fun testParallelTreeVersion() = runTest {
53+
val mappings = Buffer().use { input ->
54+
input.writeUtf8(ORIGINAL)
55+
UMFReader.read(input)
56+
}
57+
58+
mappings.fillMissingNames(Namespace("intermediary") to setOf(Namespace("named")), Namespace("named") to setOf(Namespace("extra")))
59+
60+
val output = Buffer().use { output ->
61+
mappings.accept(UMFWriter.write(output, true))
62+
output.readUtf8()
63+
}
64+
65+
assertEquals(FILLED_EXTRA.trimEnd(), output.trimEnd().replace('\t', ' '))
66+
}
67+
68+
}

src/jvmMain/kotlin/xyz/wagyourtail/unimined/mapping/propogator/Propagator.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ import kotlin.streams.asStream
1919
class Propagator(tree: AbstractMappingTree, override val fns: Namespace, jars: Set<Path>): InheritanceTree(tree) {
2020

2121
override val classes: Map<InternalName, ClassInfo> by lazy {
22-
runBlocking {
23-
jars.parallelStream().flatMap {
24-
scanJar(it).asStream()
25-
}.asSequence().toMap()
26-
}
22+
jars.parallelStream().flatMap {
23+
scanJar(it).asStream()
24+
}.asSequence().toMap()
2725
}
2826

2927
private fun scanJar(jar: Path): Sequence<Pair<InternalName, ClassInfo>> {

0 commit comments

Comments
 (0)