ObjectDirectory: avoid using File.getCanonicalPath()

On java 17 + Windows OS java.io.File.getCanonicalPath is a very slow
system call which uses most time during clone.

That is since JDK 12 the result of File.getCanonicalPath is not cached
anymore by default:
https://bugs.openjdk.java.net/browse/JDK-8207005

* Use toRealPath() to follow symbolic links also on windows.
* Cache the result.

Bug: 580568
Change-Id: I95f4f5b2babefd7210ee4740646230225ebf3788
This commit is contained in:
Jörg Kubitz 2022-08-15 11:05:04 +02:00 committed by Matthias Sohn
parent eb5124c74f
commit 2021ce3423
1 changed files with 15 additions and 7 deletions

View File

@ -724,14 +724,17 @@ public File fileFor(AnyObjectId objectId) {
static class AlternateHandle {
static class Id {
String alternateId;
private final String alternateId;
public Id(File object) {
String id = null;
try {
this.alternateId = object.getCanonicalPath();
} catch (Exception e) {
alternateId = null;
// resolve symbolic links to their final target:
id = object.toPath().toRealPath().normalize().toString();
} catch (Exception ignored) {
// id == null
}
this.alternateId = id;
}
@Override
@ -757,6 +760,8 @@ public int hashCode() {
final ObjectDirectory db;
private AlternateHandle.Id id;
AlternateHandle(ObjectDirectory db) {
this.db = db;
}
@ -765,8 +770,11 @@ void close() {
db.close();
}
public Id getId(){
return db.getAlternateId();
public synchronized Id getId() {
if (id == null) {
id = new AlternateHandle.Id(db.objects);
}
return id;
}
}
@ -795,6 +803,6 @@ CachedObjectDirectory newCachedFileObjectDatabase() {
}
AlternateHandle.Id getAlternateId() {
return new AlternateHandle.Id(objects);
return handle.getId();
}
}