LoaderUtil 路径缓存
基本信息
| 属性 | 值 |
|---|---|
| 类 | com.mitchej123.jarjar.fml.common.LoaderUtil |
| 静态缓存 | ConcurrentMap<Path, Path> pathNormalizationCache |
LoaderUtil 提供 Path 归一化(realpath)缓存。path.toRealPath() 是 fs syscall(FOLLOW_LINK + resolve symlink + normalize),同一 Path 在 Mod 发现阶段会被多次访问,缓存避免重复 IO。
方法
public static String getClassFileName(String className) {
return className.replace('.', '/').concat(".class.class");
}
public static Path normalizePath(Path path) {
if (Files.exists(path)) return normalizeExistingPath(path);
else return path.toAbsolutePath().normalize();
}
public static Path normalizeExistingPath(Path path) {
return pathNormalizationCache.computeIfAbsent(path, LoaderUtil::normalizeExistingPath0);
}
private static Path normalizeExistingPath0(Path path) {
try {
return path.toRealPath();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
使用点
DirectoryModCandidateFinder构造函数:LoaderUtil.normalizePath(path)ParallellModDiscoverer.discoverMods内的processedPaths.add(path)前:path.equals(LoaderUtil.normalizeExistingPath(path))—— assert 保证入队 path 已经 realpathDirectoryModCandidateFinder.findCandidates额外 mod:LoaderUtil.normalizePath(additionalMod.toPath())
缓存命中
Path p1 = Paths.get("/home/evlos/mods/gregtech.jar");
Path p2 = Paths.get("/home/evlos/mods/gregtech.jar"); // 实际可能是符号链接解析后
normalizeExistingPath(p1); // 触发 syscall + 缓存
normalizeExistingPath(p2); // 缓存命中
ConcurrentHashMap.computeIfAbsent 线程安全,多 finder 并发时无锁竞争。
相关条目
- DirectoryModCandidateFinder - 主使用方
- 并行 mod 发现 - ModScanTask 入队前归一化