Skip to content

Commit

Permalink
Cache mod path hashes once, rather than re-computing them when genera…
Browse files Browse the repository at this point in the history
…ting the crash report. #350
  • Loading branch information
AlexIIL committed Aug 20, 2023
1 parent 0852886 commit 740736d
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 20 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ group = org.quiltmc
description = The mod loading component of Quilt
url = https://github.com/quiltmc/quilt-loader
# Don't forget to change this in QuiltLoaderImpl as well
quilt_loader = 0.20.0-beta.15
quilt_loader = 0.20.0-beta.16

# Fabric & Quilt Libraries
asm = 9.5
Expand Down
56 changes: 47 additions & 9 deletions src/main/java/org/quiltmc/loader/impl/QuiltLoaderImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
Expand Down Expand Up @@ -130,7 +131,7 @@ public final class QuiltLoaderImpl {

public static final int ASM_VERSION = Opcodes.ASM9;

public static final String VERSION = "0.20.0-beta.15";
public static final String VERSION = "0.20.0-beta.16";
public static final String MOD_ID = "quilt_loader";
public static final String DEFAULT_MODS_DIR = "mods";
public static final String DEFAULT_CACHE_DIR = ".cache";
Expand All @@ -147,6 +148,9 @@ public final class QuiltLoaderImpl {

protected final Map<String, ModContainerExt> modMap = new HashMap<>();

protected final Map<String, String> modOriginHash = new HashMap<>();
protected final Map<Path, String> pathOriginHash = new HashMap<>();

protected List<ModContainerExt> mods = new ArrayList<>();

private final Map<String, LanguageAdapter> adapterMap = new HashMap<>();
Expand Down Expand Up @@ -343,8 +347,48 @@ private void setup() throws ModResolutionException {
long zipStart = System.nanoTime();
String suffix = System.getProperty(SystemProperties.CACHE_SUFFIX, getEnvironmentType().name().toLowerCase(Locale.ROOT));

Map<Path, byte[]> originPathCache = new HashMap<>();

for (ModLoadOption mod : modList) {
Path from = mod.from();
List<List<Path>> srcPaths = temporarySourcePaths.get(from);
boolean newArray = false;
byte[] hash = null;
for (List<Path> paths : srcPaths) {
Path first = paths.get(0);
if (first.getFileSystem() != FileSystems.getDefault()) {
throw new ModResolutionException(
"The first path as a source for " + from + " (first = " + first
+ ") is not on the default file system?"
);
}
byte[] firstHash = originPathCache.get(first);
if (firstHash == null) {
try {
firstHash = HashUtil.computeHash(first);
} catch (IOException e) {
throw new ModResolutionException("Failed to compute the hash for mod '" + mod.id() + "', path " + first);
}
originPathCache.put(first, firstHash);
pathOriginHash.put(first, HashUtil.hashToString(firstHash));
}
if (hash == null) {
hash = firstHash;
} else {
if (!newArray) {
newArray = true;
hash = Arrays.copyOf(hash, hash.length);
}
for (int i = 0; i < hash.length; i++) {
hash[i] ^= firstHash[i];
}
}
}
modOriginHash.put(mod.id(), HashUtil.hashToString(hash));
}

Path transformCacheFolder = getCacheDir().resolve(CACHE_DIR_NAME).resolve("transform-cache-" + suffix);
TransformCacheResult cacheResult = TransformCache.populateTransformBundle(transformCacheFolder, modList, result);
TransformCacheResult cacheResult = TransformCache.populateTransformBundle(transformCacheFolder, modList, modOriginHash, result);
QuiltZipPath transformedModBundle = cacheResult.transformCacheRoot;

long zipEnd = System.nanoTime();
Expand Down Expand Up @@ -814,13 +858,7 @@ public void appendModTable(Consumer<String> to) {

Path from = paths.get(0);
if (FasterFiles.isRegularFile(from)) {
String hashString;
try {
hashString = HashUtil.hashToString(HashUtil.computeHash(from));
} catch (IOException e) {
hashString = "<" + e.getMessage() + ">";
}
row.put(hash, hashString);
row.put(hash, pathOriginHash.get(from));
}

if (pathsIndex != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public class TransformCache {
private static final String FILE_TRANSFORM_COMPLETE = "__TRANSFORM_COMPLETE";

public static TransformCacheResult populateTransformBundle(Path transformCacheFolder, List<ModLoadOption> modList,
ModSolveResult result) throws ModResolutionException {
Map<String, String> modOriginHash, ModSolveResult result) throws ModResolutionException {
Map<String, String> map = new TreeMap<>();
// Mod order is important? For now, assume it is
int index = 0;
Expand All @@ -82,13 +82,8 @@ public static TransformCacheResult populateTransformBundle(Path transformCacheFo

for (Entry<String, ModLoadOption> mod : result.directMods().entrySet()) {
ModLoadOption modOption = mod.getValue();
try {
String name = modOption.from().getFileName().toString();
byte[] hash = modOption.computeOriginHash();
map.put("mod:" + mod.getKey(), name + " " + HashUtil.hashToString(hash));
} catch (IOException io) {
throw new ModResolutionException("Failed to compute the hash of " + modOption, io);
}
String name = modOption.from().getFileName().toString();
map.put("mod:" + mod.getKey(), name + " " + modOriginHash.get(modOption.id()));
}

boolean enableChasm = Boolean.getBoolean(SystemProperties.ENABLE_EXPERIMENTAL_CHASM);
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/quiltmc/loader/impl/util/HashUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.Arrays;

import org.quiltmc.loader.api.FasterFiles;

Expand Down Expand Up @@ -63,7 +64,7 @@ public static byte[] currentDateAndTimeHash() {

int nano = now.getNano();

return new byte[] { //
return Arrays.copyOf(new byte[] { //
(byte) (now.getYear() & 0xFF), //
(byte) ((now.getYear() >> 8) & 0xFF), //
(byte) (now.getMonthValue()), //
Expand All @@ -75,7 +76,7 @@ public static byte[] currentDateAndTimeHash() {
(byte) ((nano >> 8) & 0xFF), //
(byte) ((nano >> 16) & 0xFF), //
(byte) (nano >> 24)//
};
}, 20); // 20 bytes to match SHA-1
}

public static String hashToString(byte[] hash) {
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/changelog/0.20.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Features:
* Added an uncaught exception handler to every QuiltZipCustomCompressedWriter thread, and added it to the crash report.
* [#339] Added a new system property "loader.workaround.defer_all_filesystem_operations" which fixes "ClosedByInterruptException" on older versions of minecraft.
* [RFC#84] Removed the active user beacon.
* [#350] Cached mod path hashes once, rather than computing them when building a crash report.

Bug Fixes:

Expand Down

0 comments on commit 740736d

Please sign in to comment.