Skip to content

Commit

Permalink
Cache FMJs and ArtifactMetadata when reading during configuration time (
Browse files Browse the repository at this point in the history
#1018)

We have to read every jar on remapped configs to see if they are a mod or should otherwise be remapped. By caching we can avoid re-reading jars that are java-runtime & java-api or are on multiple remapped configs. The cache scope could probably be widened to help more with multi-project builds, but I am leaving that for future work as I think it would also require some sort of invalidation.
  • Loading branch information
jpenilla authored Jan 5, 2024
1 parent c52f868 commit 8df2293
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public static void supplyModConfigurations(Project project, SharedServiceManager
// the installer data. The installer data has to be added before
// any mods are remapped since remapping needs the dependencies provided by that data.
final Map<Configuration, List<ModDependency>> dependenciesBySourceConfig = new HashMap<>();
final Map<ArtifactRef, ArtifactMetadata> metaCache = new HashMap<>();
configsToRemap.forEach((sourceConfig, remappedConfig) -> {
/*
sourceConfig - The source configuration where the intermediary named artifacts come from. i.e "modApi"
Expand All @@ -148,11 +149,13 @@ public static void supplyModConfigurations(Project project, SharedServiceManager
for (ArtifactRef artifact : resolveArtifacts(project, sourceConfig)) {
final ArtifactMetadata artifactMetadata;

try {
artifactMetadata = ArtifactMetadata.create(artifact, LoomGradlePlugin.LOOM_VERSION);
} catch (IOException e) {
throw ExceptionUtil.createDescriptiveWrapper(UncheckedIOException::new, "Failed to read metadata from " + artifact.path(), e);
}
artifactMetadata = metaCache.computeIfAbsent(artifact, a -> {
try {
return ArtifactMetadata.create(a, LoomGradlePlugin.LOOM_VERSION);
} catch (IOException e) {
throw ExceptionUtil.createDescriptiveWrapper(UncheckedIOException::new, "Failed to read metadata from " + a.path(), e);
}
});

if (artifactMetadata.installerData() != null) {
if (extension.getInstallerData() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
Expand All @@ -57,30 +59,37 @@
*/
public record SpecContextImpl(List<FabricModJson> modDependencies, List<FabricModJson> localMods, List<FabricModJson> compileRuntimeMods) implements SpecContext {
public static SpecContextImpl create(Project project) {
return new SpecContextImpl(getDependentMods(project), FabricModJsonHelpers.getModsInProject(project), getCompileRuntimeMods(project));
final Map<String, List<FabricModJson>> fmjCache = new HashMap<>();
return new SpecContextImpl(getDependentMods(project, fmjCache), FabricModJsonHelpers.getModsInProject(project), getCompileRuntimeMods(project, fmjCache));
}

// Reruns a list of mods found on both the compile and/or runtime classpaths
private static List<FabricModJson> getDependentMods(Project project) {
private static List<FabricModJson> getDependentMods(Project project, Map<String, List<FabricModJson>> fmjCache) {
final LoomGradleExtension extension = LoomGradleExtension.get(project);
var mods = new ArrayList<FabricModJson>();

for (RemapConfigurationSettings entry : extension.getRemapConfigurations()) {
final Set<File> artifacts = entry.getSourceConfiguration().get().resolve();

for (File artifact : artifacts) {
final FabricModJson fabricModJson = FabricModJsonFactory.createFromZipNullable(artifact.toPath());

if (fabricModJson != null) {
mods.add(fabricModJson);
final List<FabricModJson> fabricModJson = fmjCache.computeIfAbsent(artifact.toPath().toAbsolutePath().toString(), $ -> {
return FabricModJsonFactory.createFromZipOptional(artifact.toPath())
.map(List::of)
.orElseGet(List::of);
});

if (!fabricModJson.isEmpty()) {
mods.add(fabricModJson.get(0));
}
}
}

if (!GradleUtils.getBooleanProperty(project, Constants.Properties.DISABLE_PROJECT_DEPENDENT_MODS)) {
// Add all the dependent projects
for (Project dependentProject : getDependentProjects(project).toList()) {
mods.addAll(FabricModJsonHelpers.getModsInProject(dependentProject));
mods.addAll(fmjCache.computeIfAbsent(dependentProject.getPath(), $ -> {
return FabricModJsonHelpers.getModsInProject(dependentProject);
}));
}
}

Expand All @@ -96,18 +105,20 @@ private static Stream<Project> getDependentProjects(Project project) {
}

// Returns a list of mods that are on both to compile and runtime classpath
private static List<FabricModJson> getCompileRuntimeMods(Project project) {
var mods = new ArrayList<>(getCompileRuntimeModsFromRemapConfigs(project).toList());
private static List<FabricModJson> getCompileRuntimeMods(Project project, Map<String, List<FabricModJson>> fmjCache) {
var mods = new ArrayList<>(getCompileRuntimeModsFromRemapConfigs(project, fmjCache).toList());

for (Project dependentProject : getCompileRuntimeProjectDependencies(project).toList()) {
mods.addAll(FabricModJsonHelpers.getModsInProject(dependentProject));
mods.addAll(fmjCache.computeIfAbsent(dependentProject.getPath(), $ -> {
return FabricModJsonHelpers.getModsInProject(dependentProject);
}));
}

return Collections.unmodifiableList(mods);
}

// Returns a list of jar mods that are found on the compile and runtime remapping configurations
private static Stream<FabricModJson> getCompileRuntimeModsFromRemapConfigs(Project project) {
private static Stream<FabricModJson> getCompileRuntimeModsFromRemapConfigs(Project project, Map<String, List<FabricModJson>> fmjCache) {
final LoomGradleExtension extension = LoomGradleExtension.get(project);
final List<Path> runtimeEntries = extension.getRuntimeRemapConfigurations().stream()
.filter(settings -> settings.getApplyDependencyTransforms().get())
Expand All @@ -118,9 +129,15 @@ private static Stream<FabricModJson> getCompileRuntimeModsFromRemapConfigs(Proje
.filter(settings -> settings.getApplyDependencyTransforms().get())
.flatMap(resolveArtifacts(project, false))
.filter(runtimeEntries::contains) // Use the intersection of the two configurations.
.map(FabricModJsonFactory::createFromZipOptional)
.filter(Optional::isPresent)
.map(Optional::get)
.map(zipPath -> {
final List<FabricModJson> list = fmjCache.computeIfAbsent(zipPath.toAbsolutePath().toString(), $ -> {
return FabricModJsonFactory.createFromZipOptional(zipPath)
.map(List::of)
.orElseGet(List::of);
});
return list.isEmpty() ? null : list.get(0);
})
.filter(Objects::nonNull)
.sorted(Comparator.comparing(FabricModJson::getId));
}

Expand Down

0 comments on commit 8df2293

Please sign in to comment.