summaryrefslogtreecommitdiff
path: root/sha1_name.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-07-05 20:32:56 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-07-05 20:32:56 (GMT)
commit5ab148dda0076a136b4afb385d96bd9cdc4d2590 (patch)
tree6e6876952e2e6a1154258c9a9e11428572d4dcf9 /sha1_name.c
parent85ce4a6828a418a22c69a870b3e059481b4263d6 (diff)
parent70c49050d4a16a7e2990e4d3c91d9d12f62e631e (diff)
downloadgit-5ab148dda0076a136b4afb385d96bd9cdc4d2590.zip
git-5ab148dda0076a136b4afb385d96bd9cdc4d2590.tar.gz
git-5ab148dda0076a136b4afb385d96bd9cdc4d2590.tar.bz2
Merge branch 'rs/sha1-name-readdir-optim'
Optimize "what are the object names already taken in an alternate object database?" query that is used to derive the length of prefix an object name is uniquely abbreviated to. * rs/sha1-name-readdir-optim: sha1_file: guard against invalid loose subdirectory numbers sha1_file: let for_each_file_in_obj_subdir() handle subdir names p4205: add perf test script for pretty log formats sha1_name: cache readdir(3) results in find_short_object_filename()
Diffstat (limited to 'sha1_name.c')
-rw-r--r--sha1_name.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/sha1_name.c b/sha1_name.c
index d2d732c..e7f7b12 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -78,10 +78,19 @@ static void update_candidates(struct disambiguate_state *ds, const struct object
/* otherwise, current can be discarded and candidate is still good */
}
+static int append_loose_object(const struct object_id *oid, const char *path,
+ void *data)
+{
+ oid_array_append(data, oid);
+ return 0;
+}
+
+static int match_sha(unsigned, const unsigned char *, const unsigned char *);
+
static void find_short_object_filename(struct disambiguate_state *ds)
{
+ int subdir_nr = ds->bin_pfx.hash[0];
struct alternate_object_database *alt;
- char hex[GIT_MAX_HEXSZ];
static struct alternate_object_database *fakeent;
if (!fakeent) {
@@ -96,29 +105,29 @@ static void find_short_object_filename(struct disambiguate_state *ds)
}
fakeent->next = alt_odb_list;
- xsnprintf(hex, sizeof(hex), "%.2s", ds->hex_pfx);
for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
- struct strbuf *buf = alt_scratch_buf(alt);
- struct dirent *de;
- DIR *dir;
-
- strbuf_addf(buf, "%.2s/", ds->hex_pfx);
- dir = opendir(buf->buf);
- if (!dir)
- continue;
+ int pos;
- while (!ds->ambiguous && (de = readdir(dir)) != NULL) {
- struct object_id oid;
+ if (!alt->loose_objects_subdir_seen[subdir_nr]) {
+ struct strbuf *buf = alt_scratch_buf(alt);
+ for_each_file_in_obj_subdir(subdir_nr, buf,
+ append_loose_object,
+ NULL, NULL,
+ &alt->loose_objects_cache);
+ alt->loose_objects_subdir_seen[subdir_nr] = 1;
+ }
- if (strlen(de->d_name) != GIT_SHA1_HEXSZ - 2)
- continue;
- if (memcmp(de->d_name, ds->hex_pfx + 2, ds->len - 2))
- continue;
- memcpy(hex + 2, de->d_name, GIT_SHA1_HEXSZ - 2);
- if (!get_oid_hex(hex, &oid))
- update_candidates(ds, &oid);
+ pos = oid_array_lookup(&alt->loose_objects_cache, &ds->bin_pfx);
+ if (pos < 0)
+ pos = -1 - pos;
+ while (!ds->ambiguous && pos < alt->loose_objects_cache.nr) {
+ const struct object_id *oid;
+ oid = alt->loose_objects_cache.oid + pos;
+ if (!match_sha(ds->len, ds->bin_pfx.hash, oid->hash))
+ break;
+ update_candidates(ds, oid);
+ pos++;
}
- closedir(dir);
}
}