aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src
diff options
context:
space:
mode:
authorNasser Grainawi <quic_nasserg@quicinc.com>2024-02-23 09:34:37 -0800
committerMatthias Sohn <matthias.sohn@sap.com>2024-03-19 21:42:02 +0000
commit81d64c9135b99ce85bbf7ebdce4f7ea5b7b77d35 (patch)
treec940faf8844acdbfe314b8784b675c0ea140bf91 /org.eclipse.jgit/src
parent0acf07eb7a80f01ebfdb36bee9bfd566c8f9ce74 (diff)
downloadjgit-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.java28
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;
}