From: Patrick Steinhardt Date: Wed, 17 Jun 2026 06:39:56 +0000 (+0200) Subject: odb/source-packed: wire up `find_abbrev_len()` callback X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c0f7b732e37b885009cdc64a13541591ebab00e;p=thirdparty%2Fgit.git odb/source-packed: wire up `find_abbrev_len()` callback Move `packfile_store_find_abbrev_len()` and its associated helpers from "packfile.c" into "odb/source-packed.c" and wire it up as the `find_abbrev_len()` callback of the "packed" source. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- diff --git a/odb/source-files.c b/odb/source-files.c index 274923e0ba..8ad782dc7b 100644 --- a/odb/source-files.c +++ b/odb/source-files.c @@ -133,7 +133,7 @@ static int odb_source_files_find_abbrev_len(struct odb_source *source, unsigned len = min_len; int ret; - ret = packfile_store_find_abbrev_len(files->packed, oid, len, &len); + ret = odb_source_find_abbrev_len(&files->packed->base, oid, len, &len); if (ret < 0) goto out; diff --git a/odb/source-packed.c b/odb/source-packed.c index 070a4e3958..b801b62023 100644 --- a/odb/source-packed.c +++ b/odb/source-packed.c @@ -370,6 +370,118 @@ out: return ret; } +static int extend_abbrev_len(const struct object_id *a, + const struct object_id *b, + unsigned *out) +{ + unsigned len = oid_common_prefix_hexlen(a, b); + if (len != hash_algos[a->algo].hexsz && len >= *out) + *out = len + 1; + return 0; +} + +static void find_abbrev_len_for_midx(struct multi_pack_index *m, + const struct object_id *oid, + unsigned min_len, + unsigned *out) +{ + unsigned len = min_len; + + for (; m; m = m->base_midx) { + int match = 0; + uint32_t num, first = 0; + struct object_id found_oid; + + if (!m->num_objects) + continue; + + num = m->num_objects + m->num_objects_in_base; + match = bsearch_one_midx(oid, m, &first); + + /* + * first is now the position in the packfile where we + * would insert the object ID if it does not exist (or the + * position of the object ID if it does exist). Hence, we + * consider a maximum of two objects nearby for the + * abbreviation length. + */ + + if (!match) { + if (nth_midxed_object_oid(&found_oid, m, first)) + extend_abbrev_len(&found_oid, oid, &len); + } else if (first < num - 1) { + if (nth_midxed_object_oid(&found_oid, m, first + 1)) + extend_abbrev_len(&found_oid, oid, &len); + } + if (first > 0) { + if (nth_midxed_object_oid(&found_oid, m, first - 1)) + extend_abbrev_len(&found_oid, oid, &len); + } + } + + *out = len; +} + +static void find_abbrev_len_for_pack(struct packed_git *p, + const struct object_id *oid, + unsigned min_len, + unsigned *out) +{ + int match; + uint32_t num, first = 0; + struct object_id found_oid; + unsigned len = min_len; + + num = p->num_objects; + match = bsearch_pack(oid, p, &first); + + /* + * first is now the position in the packfile where we would insert + * the object ID if it does not exist (or the position of mad->hash if + * it does exist). Hence, we consider a maximum of two objects + * nearby for the abbreviation length. + */ + if (!match) { + if (!nth_packed_object_id(&found_oid, p, first)) + extend_abbrev_len(&found_oid, oid, &len); + } else if (first < num - 1) { + if (!nth_packed_object_id(&found_oid, p, first + 1)) + extend_abbrev_len(&found_oid, oid, &len); + } + if (first > 0) { + if (!nth_packed_object_id(&found_oid, p, first - 1)) + extend_abbrev_len(&found_oid, oid, &len); + } + + *out = len; +} + +static int odb_source_packed_find_abbrev_len(struct odb_source *source, + const struct object_id *oid, + unsigned min_len, + unsigned *out) +{ + struct odb_source_packed *packed = odb_source_packed_downcast(source); + struct packfile_list_entry *e; + struct multi_pack_index *m; + + m = get_multi_pack_index(&packed->files->base); + if (m) + find_abbrev_len_for_midx(m, oid, min_len, &min_len); + + for (e = packfile_store_get_packs(packed); e; e = e->next) { + if (e->pack->multi_pack_index) + continue; + if (open_pack_index(e->pack) || !e->pack->num_objects) + continue; + + find_abbrev_len_for_pack(e->pack, oid, min_len, &min_len); + } + + *out = min_len; + return 0; +} + void (*report_garbage)(unsigned seen_bits, const char *path); static void report_helper(const struct string_list *list, @@ -582,6 +694,7 @@ struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent) packed->base.read_object_stream = odb_source_packed_read_object_stream; packed->base.for_each_object = odb_source_packed_for_each_object; packed->base.count_objects = odb_source_packed_count_objects; + packed->base.find_abbrev_len = odb_source_packed_find_abbrev_len; if (!is_absolute_path(parent->base.path)) chdir_notify_register(NULL, odb_source_packed_reparent, packed); diff --git a/packfile.c b/packfile.c index 2da6bbe2b5..7f84094e53 100644 --- a/packfile.c +++ b/packfile.c @@ -2037,117 +2037,6 @@ int for_each_object_in_pack(struct packed_git *p, return r; } -static int extend_abbrev_len(const struct object_id *a, - const struct object_id *b, - unsigned *out) -{ - unsigned len = oid_common_prefix_hexlen(a, b); - if (len != hash_algos[a->algo].hexsz && len >= *out) - *out = len + 1; - return 0; -} - -static void find_abbrev_len_for_midx(struct multi_pack_index *m, - const struct object_id *oid, - unsigned min_len, - unsigned *out) -{ - unsigned len = min_len; - - for (; m; m = m->base_midx) { - int match = 0; - uint32_t num, first = 0; - struct object_id found_oid; - - if (!m->num_objects) - continue; - - num = m->num_objects + m->num_objects_in_base; - match = bsearch_one_midx(oid, m, &first); - - /* - * first is now the position in the packfile where we - * would insert the object ID if it does not exist (or the - * position of the object ID if it does exist). Hence, we - * consider a maximum of two objects nearby for the - * abbreviation length. - */ - - if (!match) { - if (nth_midxed_object_oid(&found_oid, m, first)) - extend_abbrev_len(&found_oid, oid, &len); - } else if (first < num - 1) { - if (nth_midxed_object_oid(&found_oid, m, first + 1)) - extend_abbrev_len(&found_oid, oid, &len); - } - if (first > 0) { - if (nth_midxed_object_oid(&found_oid, m, first - 1)) - extend_abbrev_len(&found_oid, oid, &len); - } - } - - *out = len; -} - -static void find_abbrev_len_for_pack(struct packed_git *p, - const struct object_id *oid, - unsigned min_len, - unsigned *out) -{ - int match; - uint32_t num, first = 0; - struct object_id found_oid; - unsigned len = min_len; - - num = p->num_objects; - match = bsearch_pack(oid, p, &first); - - /* - * first is now the position in the packfile where we would insert - * the object ID if it does not exist (or the position of mad->hash if - * it does exist). Hence, we consider a maximum of two objects - * nearby for the abbreviation length. - */ - if (!match) { - if (!nth_packed_object_id(&found_oid, p, first)) - extend_abbrev_len(&found_oid, oid, &len); - } else if (first < num - 1) { - if (!nth_packed_object_id(&found_oid, p, first + 1)) - extend_abbrev_len(&found_oid, oid, &len); - } - if (first > 0) { - if (!nth_packed_object_id(&found_oid, p, first - 1)) - extend_abbrev_len(&found_oid, oid, &len); - } - - *out = len; -} - -int packfile_store_find_abbrev_len(struct odb_source_packed *store, - const struct object_id *oid, - unsigned min_len, - unsigned *out) -{ - struct packfile_list_entry *e; - struct multi_pack_index *m; - - m = get_multi_pack_index(&store->files->base); - if (m) - find_abbrev_len_for_midx(m, oid, min_len, &min_len); - - for (e = packfile_store_get_packs(store); e; e = e->next) { - if (e->pack->multi_pack_index) - continue; - if (open_pack_index(e->pack) || !e->pack->num_objects) - continue; - - find_abbrev_len_for_pack(e->pack, oid, min_len, &min_len); - } - - *out = min_len; - return 0; -} - struct add_promisor_object_data { struct repository *repo; struct oidset *set; diff --git a/packfile.h b/packfile.h index 0613fd3c63..79324e4010 100644 --- a/packfile.h +++ b/packfile.h @@ -217,11 +217,6 @@ int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn, void *data, enum odb_for_each_object_flags flags); -int packfile_store_find_abbrev_len(struct odb_source_packed *store, - const struct object_id *oid, - unsigned min_len, - unsigned *out); - /* A hook to report invalid files in pack directory */ #define PACKDIR_FILE_PACK 1 #define PACKDIR_FILE_IDX 2