diff options
author | Kaushik Lingarkar <quic_kaushikl@quicinc.com> | 2021-11-18 13:12:17 -0800 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2021-12-02 10:45:37 +0100 |
commit | 5606a53151e8b9b4785e5c01513eb331998b8278 (patch) | |
tree | b67d3fa7da441694f92a56fe401198335dada343 | |
parent | 09c923073a652236aa7c91eb2c7951c2a0ebab6f (diff) | |
download | jgit-5606a53151e8b9b4785e5c01513eb331998b8278.tar.gz jgit-5606a53151e8b9b4785e5c01513eb331998b8278.zip |
FileSnapshot: Lazy load file store attributes cache
Doing a getFileStoreAttributes call even when the file doesn't
exist is unnecessary. This call is particularly slow on some
filesystems. Instead, do it only when the file exists and load
the appropriate cache.
This update can help speed up RefDirectory.exactRef when the ref
is packed, but has a corresponding empty dir for it under 'refs/'.
This scenario can happen when an atomic 'BatchRefUpdate' creates
new sharded refs.
For example, consider the case where we create 50k sharded refs in
a new namespace called 'new-refs' using an atomic 'BatchRefUpdate'.
The refs are named like 'refs/new-refs/01/1/1', 'refs/new-refs/01/1/2',
'refs/new-refs/01/1/3' and so on. After the refs are created, the
'new-refs' namespace looks like below:
$ find refs/new-refs -type f | wc -l
0
$ find refs/new-refs -type d | wc -l
5101
At this point, an 'exactRef' call on each of the 50k refs without
this change takes ~30s, where as with this change it takes ~2.5s.
Change-Id: I4a5d4c6a652dbeed1f4bc3b4f2b2f1416f7ca0e7
Signed-off-by: Kaushik Lingarkar <quic_kaushikl@quicinc.com>
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java index 976f946e5d..487ae06014 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java @@ -218,6 +218,12 @@ public class FileSnapshot { private FileStoreAttributes fileStoreAttributeCache; /** + * if {@code true} read filesystem time resolution from configuration file + * otherwise use fallback resolution + */ + private boolean useConfig; + + /** * Object that uniquely identifies the given file, or {@code * null} if a file key is not available */ @@ -253,9 +259,7 @@ public class FileSnapshot { protected FileSnapshot(File file, boolean useConfig) { this.file = file; this.lastRead = Instant.now(); - this.fileStoreAttributeCache = useConfig - ? FS.getFileStoreAttributes(file.toPath().getParent()) - : FALLBACK_FILESTORE_ATTRIBUTES; + this.useConfig = useConfig; BasicFileAttributes fileAttributes = null; try { fileAttributes = FS.DETECTED.fileAttributes(file); @@ -399,7 +403,7 @@ public class FileSnapshot { * if sleep was interrupted */ public void waitUntilNotRacy() throws InterruptedException { - long timestampResolution = fileStoreAttributeCache + long timestampResolution = fileStoreAttributeCache() .getFsTimestampResolution().toNanos(); while (isRacyClean(Instant.now())) { TimeUnit.NANOSECONDS.sleep(timestampResolution); @@ -519,10 +523,10 @@ public class FileSnapshot { } private long getEffectiveRacyThreshold() { - long timestampResolution = fileStoreAttributeCache + long timestampResolution = fileStoreAttributeCache() .getFsTimestampResolution().toNanos(); - long minRacyInterval = fileStoreAttributeCache.getMinimalRacyInterval() - .toNanos(); + long minRacyInterval = fileStoreAttributeCache() + .getMinimalRacyInterval().toNanos(); long max = Math.max(timestampResolution, minRacyInterval); // safety margin: factor 2.5 below 100ms otherwise 1.25 return max < 100_000_000L ? max * 5 / 2 : max * 5 / 4; @@ -582,4 +586,13 @@ public class FileSnapshot { } return changed; } + + private FileStoreAttributes fileStoreAttributeCache() { + if (fileStoreAttributeCache == null) { + fileStoreAttributeCache = useConfig + ? FS.getFileStoreAttributes(file.toPath().getParent()) + : FALLBACK_FILESTORE_ATTRIBUTES; + } + return fileStoreAttributeCache; + } } |