diff options
author | Junio C Hamano <gitster@pobox.com> | 2017-07-05 13:32:56 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-07-05 13:32:56 -0700 |
commit | 5ab148dda0076a136b4afb385d96bd9cdc4d2590 (patch) | |
tree | 6e6876952e2e6a1154258c9a9e11428572d4dcf9 /sha1_name.c | |
parent | 85ce4a6828a418a22c69a870b3e059481b4263d6 (diff) | |
parent | 70c49050d4a16a7e2990e4d3c91d9d12f62e631e (diff) | |
download | git-5ab148dda0076a136b4afb385d96bd9cdc4d2590.tar.gz |
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.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/sha1_name.c b/sha1_name.c index d2d732c19b..e7f7b12ceb 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); } } |