aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorKaushik Lingarkar <quic_kaushikl@quicinc.com>2022-12-02 13:21:02 -0800
committerMatthias Sohn <matthias.sohn@sap.com>2023-01-05 15:52:36 +0100
commit82b5aaf7e3e3f881056dd2d4486e02537b0493da (patch)
tree91ff2e5dd3d8bfe5ad054c1ddcf7ab58edf6822b /org.eclipse.jgit
parent52aa9c81fcc72961d2ecb4ecadea6d869a6f878a (diff)
downloadjgit-82b5aaf7e3e3f881056dd2d4486e02537b0493da.tar.gz
jgit-82b5aaf7e3e3f881056dd2d4486e02537b0493da.zip
Introduce core.trustPackedRefsStat config
Currently, we always read packed-refs file when 'trustFolderStat' is false. Introduce a new config 'trustPackedRefsStat' which takes precedence over 'trustFolderStat' when reading packed refs. Possible values for this new config are: * always: Trust packed-refs file attributes * after_open: Same as 'always', but refresh the file attributes of packed-refs before trusting it * never: Always read the packed-refs file * unset: Fallback to 'trustFolderStat' to determine if the file attributes of packed-refs can be trusted Folks whose repositories are on NFS and have traditionally been setting 'trustFolderStat=false' can now get some performance improvement with 'trustPackedRefsStat=after_open' as it refreshes the file attributes of packed-refs (at least on some NFS clients) before considering it. For example, consider a repository on NFS with ~500k packed-refs. Here are some stats which illustrate the improvement with this new config when reading packed refs on NFS: trustFolderStat=true trustPackedRefsStat=unset: 0.2ms trustFolderStat=false trustPackedRefsStat=unset: 155ms trustFolderStat=false trustPackedRefsStat=after_open: 1.5ms Change-Id: I00da88e4cceebbcf3475be0fc0011ff65767c111 Signed-off-by: Kaushik Lingarkar <quic_kaushikl@quicinc.com>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/.settings/.api_filters14
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java33
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java21
4 files changed, 72 insertions, 2 deletions
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index a6f18310d6..0f84330082 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -15,6 +15,20 @@
<message_argument value="SHA1_IMPLEMENTATION"/>
</message_arguments>
</filter>
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="6.1.1"/>
+ <message_argument value="CONFIG_KEY_TRUST_PACKED_REFS_STAT"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/lib/CoreConfig.java" type="org.eclipse.jgit.lib.CoreConfig$TrustPackedRefsStat">
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="6.1.1"/>
+ <message_argument value="TrustPackedRefsStat"/>
+ </message_arguments>
+ </filter>
</resource>
<resource path="src/org/eclipse/jgit/lib/ObjectDatabase.java" type="org.eclipse.jgit.lib.ObjectDatabase">
<filter id="336695337">
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
index b46ffe3670..43ebce3918 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -30,6 +30,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.nio.file.DirectoryNotEmptyException;
@@ -60,6 +61,7 @@ import org.eclipse.jgit.events.RefsChangedEvent;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig.TrustPackedRefsStat;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.Ref;
@@ -892,10 +894,37 @@ public class RefDirectory extends RefDatabase {
boolean trustFolderStat = getRepository().getConfig().getBoolean(
ConfigConstants.CONFIG_CORE_SECTION,
ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
+ TrustPackedRefsStat trustPackedRefsStat =
+ getRepository().getConfig().getEnum(
+ ConfigConstants.CONFIG_CORE_SECTION,
+ null,
+ ConfigConstants.CONFIG_KEY_TRUST_PACKED_REFS_STAT,
+ TrustPackedRefsStat.UNSET);
final PackedRefList curList = packedRefs.get();
- if (trustFolderStat && !curList.snapshot.isModified(packedRefsFile)) {
- return curList;
+
+ switch (trustPackedRefsStat) {
+ case NEVER:
+ break;
+ case AFTER_OPEN:
+ try (InputStream stream = Files
+ .newInputStream(packedRefsFile.toPath())) {
+ // open the file to refresh attributes (on some NFS clients)
+ } catch (FileNotFoundException e) {
+ // Ignore as packed-refs may not exist
+ }
+ //$FALL-THROUGH$
+ case ALWAYS:
+ if (!curList.snapshot.isModified(packedRefsFile)) {
+ return curList;
+ }
+ break;
+ case UNSET:
+ if (trustFolderStat
+ && !curList.snapshot.isModified(packedRefsFile)) {
+ return curList;
+ }
+ break;
}
final PackedRefList newList = readPackedRefs();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index 649bcde25a..9398419af9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -850,4 +850,10 @@ public final class ConfigConstants {
*/
public static final String CONFIG_KEY_ABBREV = "abbrev";
+ /**
+ * The "trustPackedRefsStat" key
+ *
+ * @since 6.1.1
+ */
+ public static final String CONFIG_KEY_TRUST_PACKED_REFS_STAT = "trustPackedRefsStat";
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
index f23c6e08d1..fc82a5fead 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
@@ -116,6 +116,27 @@ public class CoreConfig {
ALWAYS
}
+ /**
+ * Permissible values for {@code core.trustPackedRefsStat}.
+ *
+ * @since 6.1.1
+ */
+ public enum TrustPackedRefsStat {
+ /** Do not trust file attributes of the packed-refs file. */
+ NEVER,
+
+ /** Trust file attributes of the packed-refs file. */
+ ALWAYS,
+
+ /** Open and close the packed-refs file to refresh its file attributes
+ * and then trust it. */
+ AFTER_OPEN,
+
+ /** {@code core.trustPackedRefsStat} defaults to this when it is
+ * not set */
+ UNSET
+ }
+
private final int compression;
private final int packIndexVersion;