From: "Shawn O. Pearce" <spearce@spearce.org>
To: Robin Rosenberg <robin.rosenberg@dewire.com>
Cc: git@vger.kernel.org
Subject: [JGIT PATCH (RESEND) 1/4] Avoid unnecessary stat when scanning packs in the objects directory
Date: Wed, 12 Aug 2009 12:45:20 -0700 [thread overview]
Message-ID: <1250106323-19408-2-git-send-email-spearce@spearce.org> (raw)
In-Reply-To: <1250106323-19408-1-git-send-email-spearce@spearce.org>
We only care that the pack name exists in the directory at this stage
of processing. Performing a isFile() test against the pack file name
is likely to be slower than checking an in-memory HashSet, since the
OS call has to actually check the inode to determine whether or not
the name is a file, or some other node type. Since we already have
forced the OS to give us a complete listing of the paths, its just
faster to consult that existing list.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../src/org/spearce/jgit/lib/ObjectDirectory.java | 49 +++++++++++--------
1 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectDirectory.java b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectDirectory.java
index 7cc459c..4419f9c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectDirectory.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/ObjectDirectory.java
@@ -41,14 +41,16 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.spearce.jgit.errors.PackMismatchException;
@@ -339,11 +341,23 @@ private static boolean inList(final PackFile[] list, final PackFile pack) {
private PackFile[] scanPacksImpl(final PackFile[] old) {
final Map<String, PackFile> forReuse = reuseMap(old);
- final String[] idxList = listPackIdx();
- final List<PackFile> list = new ArrayList<PackFile>(idxList.length);
- for (final String indexName : idxList) {
+ final Set<String> names = listPackDirectory();
+ final List<PackFile> list = new ArrayList<PackFile>(names.size() >> 2);
+ for (final String indexName : names) {
+ // Must match "pack-[0-9a-f]{40}.idx" to be an index.
+ //
+ if (indexName.length() != 49 || !indexName.endsWith(".idx"))
+ continue;
+
final String base = indexName.substring(0, indexName.length() - 4);
final String packName = base + ".pack";
+ if (!names.contains(packName)) {
+ // Sometimes C Git's HTTP fetch transport leaves a
+ // .idx file behind and does not download the .pack.
+ // We have to skip over such useless indexes.
+ //
+ continue;
+ }
final PackFile oldPack = forReuse.remove(packName);
if (oldPack != null) {
@@ -352,14 +366,6 @@ private static boolean inList(final PackFile[] list, final PackFile pack) {
}
final File packFile = new File(packDirectory, packName);
- if (!packFile.isFile()) {
- // Sometimes C Git's HTTP fetch transport leaves a
- // .idx file behind and does not download the .pack.
- // We have to skip over such useless indexes.
- //
- continue;
- }
-
final File idxFile = new File(packDirectory, indexName);
list.add(new PackFile(idxFile, packFile));
}
@@ -401,16 +407,17 @@ private static boolean inList(final PackFile[] list, final PackFile pack) {
return forReuse;
}
- private String[] listPackIdx() {
+ private Set<String> listPackDirectory() {
packDirectoryLastModified = packDirectory.lastModified();
- final String[] idxList = packDirectory.list(new FilenameFilter() {
- public boolean accept(final File baseDir, final String n) {
- // Must match "pack-[0-9a-f]{40}.idx" to be an index.
- return n.length() == 49 && n.endsWith(".idx")
- && n.startsWith("pack-");
- }
- });
- return idxList != null ? idxList : new String[0];
+ final String[] nameList = packDirectory.list();
+ if (nameList == null)
+ return Collections.emptySet();
+ final Set<String> nameSet = new HashSet<String>(nameList.length << 1);
+ for (final String name : nameList) {
+ if (name.startsWith("pack-"))
+ nameSet.add(name);
+ }
+ return nameSet;
}
@Override
--
1.6.4.225.gb589e
next prev parent reply other threads:[~2009-08-12 19:46 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-12 19:45 [JGIT PATCH (RESEND) 0/4] Fix race condition on loading pack files Shawn O. Pearce
2009-08-12 19:45 ` Shawn O. Pearce [this message]
2009-08-12 19:45 ` [JGIT PATCH (RESEND) 2/4] Make ObjectDirectory last modified time atomically updated with list Shawn O. Pearce
2009-08-12 19:45 ` [JGIT PATCH (RESEND) 3/4] Don't create new pack lists if the directory hasn't changed Shawn O. Pearce
2009-08-12 19:45 ` [JGIT PATCH (RESEND) 4/4] Fix racy condition when a repository is repacked Shawn O. Pearce
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1250106323-19408-2-git-send-email-spearce@spearce.org \
--to=spearce@spearce.org \
--cc=git@vger.kernel.org \
--cc=robin.rosenberg@dewire.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox