diff options
author | Nasser Grainawi <quic_nasserg@quicinc.com> | 2024-02-23 09:34:37 -0800 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2024-03-19 21:42:02 +0000 |
commit | 81d64c9135b99ce85bbf7ebdce4f7ea5b7b77d35 (patch) | |
tree | c940faf8844acdbfe314b8784b675c0ea140bf91 /org.eclipse.jgit/src | |
parent | 0acf07eb7a80f01ebfdb36bee9bfd566c8f9ce74 (diff) | |
download | jgit-81d64c9135b99ce85bbf7ebdce4f7ea5b7b77d35.tar.gz jgit-81d64c9135b99ce85bbf7ebdce4f7ea5b7b77d35.zip |
Cache refreshed loose ref dirs in SnapshottingRefDirectory
Update SnapshottingRefDirectory to have a cache of dirs refreshed for
loose refs. This should help improve performance when 'after_open'
setting is used for 'trustLooseRefStat' as duplicate refreshes are
avoided when a snapshot of the ref database is used in a request scope.
Change-Id: I8f66e7cee572e477d29abe2d9db69e97bca3ee4c
Signed-off-by: Nasser Grainawi <quic_nasserg@quicinc.com>
Co-authored-by: Martin Fick <quic_mfick@quicinc.com>
Co-authored-by: Kaushik Lingarkar <quic_kaushikl@quicinc.com>
Diffstat (limited to 'org.eclipse.jgit/src')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java index 46607f60d9..1dc5776e06 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java @@ -16,15 +16,21 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.revwalk.RevWalk; +import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; /** * Snapshotting write-through cache of a {@link RefDirectory}. * <p> * This is intended to be short-term write-through snapshot based cache used in - * a request scope to avoid re-reading packed-refs on each read. A future - * improvement could also snapshot loose refs. + * a request scope to avoid re-reading packed-refs on each read and to avoid + * refreshing paths to a loose ref that has already been refreshed. * <p> * Only use this class when concurrent writes from other requests (not using the * same instance of SnapshottingRefDirectory) generally need not be visible to @@ -34,6 +40,7 @@ import java.util.List; */ class SnapshottingRefDirectory extends RefDirectory { final RefDirectory refDb; + private final Set<File> refreshedLooseRefDirs = ConcurrentHashMap.newKeySet(); private volatile boolean isValid; @@ -67,6 +74,22 @@ class SnapshottingRefDirectory extends RefDirectory { } @Override + void refreshPathToLooseRef(Path refPath) { + for (int i = 1; i < refPath.getNameCount(); i++) { + File dir = fileFor(refPath.subpath(0, i).toString()); + if (!refreshedLooseRefDirs.contains(dir)) { + try (InputStream stream = Files.newInputStream(dir.toPath())) { + // open the dir to refresh attributes (on some NFS clients) + } catch (IOException e) { + break; // loose ref may not exist + } finally { + refreshedLooseRefDirs.add(dir); + } + } + } + } + + @Override void delete(RefDirectoryUpdate update) throws IOException { refreshSnapshot(); super.delete(update); @@ -107,6 +130,7 @@ class SnapshottingRefDirectory extends RefDirectory { } synchronized void invalidateSnapshot() { + refreshedLooseRefDirs.clear(); isValid = false; } |