Skip to content

Commit 6c2ede6

Browse files
pks-tgitster
authored andcommitted
object-file: move logic to compute packed abbreviation length
Same as the preceding commit, move the logic that computes the minimum required prefix length to make a given object ID unique for the packfile store into a new function `packfile_store_find_abbrev_len()` that is part of "packfile.c". This prepares for making the logic fully generic via pluggable object databases. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent ab3ab10 commit 6c2ede6

3 files changed

Lines changed: 128 additions & 123 deletions

File tree

object-name.c

Lines changed: 12 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -582,115 +582,6 @@ static unsigned msb(unsigned long val)
582582
return r;
583583
}
584584

585-
struct min_abbrev_data {
586-
unsigned int init_len;
587-
unsigned int cur_len;
588-
struct repository *repo;
589-
const struct object_id *oid;
590-
};
591-
592-
static int extend_abbrev_len(const struct object_id *oid,
593-
struct min_abbrev_data *mad)
594-
{
595-
unsigned len = oid_common_prefix_hexlen(oid, mad->oid);
596-
if (len != hash_algos[oid->algo].hexsz && len >= mad->cur_len)
597-
mad->cur_len = len + 1;
598-
return 0;
599-
}
600-
601-
static void find_abbrev_len_for_midx(struct multi_pack_index *m,
602-
struct min_abbrev_data *mad)
603-
{
604-
for (; m; m = m->base_midx) {
605-
int match = 0;
606-
uint32_t num, first = 0;
607-
struct object_id oid;
608-
const struct object_id *mad_oid;
609-
610-
if (!m->num_objects)
611-
continue;
612-
613-
num = m->num_objects + m->num_objects_in_base;
614-
mad_oid = mad->oid;
615-
match = bsearch_one_midx(mad_oid, m, &first);
616-
617-
/*
618-
* first is now the position in the packfile where we
619-
* would insert mad->hash if it does not exist (or the
620-
* position of mad->hash if it does exist). Hence, we
621-
* consider a maximum of two objects nearby for the
622-
* abbreviation length.
623-
*/
624-
mad->init_len = 0;
625-
if (!match) {
626-
if (nth_midxed_object_oid(&oid, m, first))
627-
extend_abbrev_len(&oid, mad);
628-
} else if (first < num - 1) {
629-
if (nth_midxed_object_oid(&oid, m, first + 1))
630-
extend_abbrev_len(&oid, mad);
631-
}
632-
if (first > 0) {
633-
if (nth_midxed_object_oid(&oid, m, first - 1))
634-
extend_abbrev_len(&oid, mad);
635-
}
636-
mad->init_len = mad->cur_len;
637-
}
638-
}
639-
640-
static void find_abbrev_len_for_pack(struct packed_git *p,
641-
struct min_abbrev_data *mad)
642-
{
643-
int match = 0;
644-
uint32_t num, first = 0;
645-
struct object_id oid;
646-
const struct object_id *mad_oid;
647-
648-
if (p->multi_pack_index)
649-
return;
650-
651-
if (open_pack_index(p) || !p->num_objects)
652-
return;
653-
654-
num = p->num_objects;
655-
mad_oid = mad->oid;
656-
match = bsearch_pack(mad_oid, p, &first);
657-
658-
/*
659-
* first is now the position in the packfile where we would insert
660-
* mad->hash if it does not exist (or the position of mad->hash if
661-
* it does exist). Hence, we consider a maximum of two objects
662-
* nearby for the abbreviation length.
663-
*/
664-
mad->init_len = 0;
665-
if (!match) {
666-
if (!nth_packed_object_id(&oid, p, first))
667-
extend_abbrev_len(&oid, mad);
668-
} else if (first < num - 1) {
669-
if (!nth_packed_object_id(&oid, p, first + 1))
670-
extend_abbrev_len(&oid, mad);
671-
}
672-
if (first > 0) {
673-
if (!nth_packed_object_id(&oid, p, first - 1))
674-
extend_abbrev_len(&oid, mad);
675-
}
676-
mad->init_len = mad->cur_len;
677-
}
678-
679-
static void find_abbrev_len_packed(struct min_abbrev_data *mad)
680-
{
681-
struct packed_git *p;
682-
683-
odb_prepare_alternates(mad->repo->objects);
684-
for (struct odb_source *source = mad->repo->objects->sources; source; source = source->next) {
685-
struct multi_pack_index *m = get_multi_pack_index(source);
686-
if (m)
687-
find_abbrev_len_for_midx(m, mad);
688-
}
689-
690-
repo_for_each_pack(mad->repo, p)
691-
find_abbrev_len_for_pack(p, mad);
692-
}
693-
694585
void strbuf_repo_add_unique_abbrev(struct strbuf *sb, struct repository *repo,
695586
const struct object_id *oid, int abbrev_len)
696587
{
@@ -707,14 +598,14 @@ void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
707598
}
708599

709600
int repo_find_unique_abbrev_r(struct repository *r, char *hex,
710-
const struct object_id *oid, int len)
601+
const struct object_id *oid, int min_len)
711602
{
712603
const struct git_hash_algo *algo =
713604
oid->algo ? &hash_algos[oid->algo] : r->hash_algo;
714-
struct min_abbrev_data mad;
715605
const unsigned hexsz = algo->hexsz;
606+
unsigned len;
716607

717-
if (len < 0) {
608+
if (min_len < 0) {
718609
unsigned long count;
719610

720611
if (odb_count_objects(r->objects, ODB_COUNT_OBJECTS_APPROXIMATE, &count) < 0)
@@ -738,25 +629,23 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
738629
*/
739630
if (len < FALLBACK_DEFAULT_ABBREV)
740631
len = FALLBACK_DEFAULT_ABBREV;
632+
} else {
633+
len = min_len;
741634
}
742635

743636
oid_to_hex_r(hex, oid);
744637
if (len >= hexsz || !len)
745638
return hexsz;
746639

747-
mad.repo = r;
748-
mad.init_len = len;
749-
mad.cur_len = len;
750-
mad.oid = oid;
751-
752-
find_abbrev_len_packed(&mad);
753-
754640
odb_prepare_alternates(r->objects);
755-
for (struct odb_source *s = r->objects->sources; s; s = s->next)
756-
odb_source_loose_find_abbrev_len(s, mad.oid, mad.cur_len, &mad.cur_len);
641+
for (struct odb_source *s = r->objects->sources; s; s = s->next) {
642+
struct odb_source_files *files = odb_source_files_downcast(s);
643+
packfile_store_find_abbrev_len(files->packed, oid, len, &len);
644+
odb_source_loose_find_abbrev_len(s, oid, len, &len);
645+
}
757646

758-
hex[mad.cur_len] = 0;
759-
return mad.cur_len;
647+
hex[len] = 0;
648+
return len;
760649
}
761650

762651
const char *repo_find_unique_abbrev(struct repository *r,

packfile.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,6 +2597,117 @@ int packfile_store_for_each_object(struct packfile_store *store,
25972597
return ret;
25982598
}
25992599

2600+
static int extend_abbrev_len(const struct object_id *a,
2601+
const struct object_id *b,
2602+
unsigned *out)
2603+
{
2604+
unsigned len = oid_common_prefix_hexlen(a, b);
2605+
if (len != hash_algos[a->algo].hexsz && len >= *out)
2606+
*out = len + 1;
2607+
return 0;
2608+
}
2609+
2610+
static void find_abbrev_len_for_midx(struct multi_pack_index *m,
2611+
const struct object_id *oid,
2612+
unsigned min_len,
2613+
unsigned *out)
2614+
{
2615+
unsigned len = min_len;
2616+
2617+
for (; m; m = m->base_midx) {
2618+
int match = 0;
2619+
uint32_t num, first = 0;
2620+
struct object_id found_oid;
2621+
2622+
if (!m->num_objects)
2623+
continue;
2624+
2625+
num = m->num_objects + m->num_objects_in_base;
2626+
match = bsearch_one_midx(oid, m, &first);
2627+
2628+
/*
2629+
* first is now the position in the packfile where we
2630+
* would insert the object ID if it does not exist (or the
2631+
* position of the object ID if it does exist). Hence, we
2632+
* consider a maximum of two objects nearby for the
2633+
* abbreviation length.
2634+
*/
2635+
2636+
if (!match) {
2637+
if (nth_midxed_object_oid(&found_oid, m, first))
2638+
extend_abbrev_len(&found_oid, oid, &len);
2639+
} else if (first < num - 1) {
2640+
if (nth_midxed_object_oid(&found_oid, m, first + 1))
2641+
extend_abbrev_len(&found_oid, oid, &len);
2642+
}
2643+
if (first > 0) {
2644+
if (nth_midxed_object_oid(&found_oid, m, first - 1))
2645+
extend_abbrev_len(&found_oid, oid, &len);
2646+
}
2647+
}
2648+
2649+
*out = len;
2650+
}
2651+
2652+
static void find_abbrev_len_for_pack(struct packed_git *p,
2653+
const struct object_id *oid,
2654+
unsigned min_len,
2655+
unsigned *out)
2656+
{
2657+
int match;
2658+
uint32_t num, first = 0;
2659+
struct object_id found_oid;
2660+
unsigned len = min_len;
2661+
2662+
num = p->num_objects;
2663+
match = bsearch_pack(oid, p, &first);
2664+
2665+
/*
2666+
* first is now the position in the packfile where we would insert
2667+
* the object ID if it does not exist (or the position of mad->hash if
2668+
* it does exist). Hence, we consider a maximum of two objects
2669+
* nearby for the abbreviation length.
2670+
*/
2671+
if (!match) {
2672+
if (!nth_packed_object_id(&found_oid, p, first))
2673+
extend_abbrev_len(&found_oid, oid, &len);
2674+
} else if (first < num - 1) {
2675+
if (!nth_packed_object_id(&found_oid, p, first + 1))
2676+
extend_abbrev_len(&found_oid, oid, &len);
2677+
}
2678+
if (first > 0) {
2679+
if (!nth_packed_object_id(&found_oid, p, first - 1))
2680+
extend_abbrev_len(&found_oid, oid, &len);
2681+
}
2682+
2683+
*out = len;
2684+
}
2685+
2686+
int packfile_store_find_abbrev_len(struct packfile_store *store,
2687+
const struct object_id *oid,
2688+
unsigned min_len,
2689+
unsigned *out)
2690+
{
2691+
struct packfile_list_entry *e;
2692+
struct multi_pack_index *m;
2693+
2694+
m = get_multi_pack_index(store->source);
2695+
if (m)
2696+
find_abbrev_len_for_midx(m, oid, min_len, &min_len);
2697+
2698+
for (e = packfile_store_get_packs(store); e; e = e->next) {
2699+
if (e->pack->multi_pack_index)
2700+
continue;
2701+
if (open_pack_index(e->pack) || !e->pack->num_objects)
2702+
continue;
2703+
2704+
find_abbrev_len_for_pack(e->pack, oid, min_len, &min_len);
2705+
}
2706+
2707+
*out = min_len;
2708+
return 0;
2709+
}
2710+
26002711
struct add_promisor_object_data {
26012712
struct repository *repo;
26022713
struct oidset *set;

packfile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ int packfile_store_for_each_object(struct packfile_store *store,
369369
void *cb_data,
370370
const struct odb_for_each_object_options *opts);
371371

372+
int packfile_store_find_abbrev_len(struct packfile_store *store,
373+
const struct object_id *oid,
374+
unsigned min_len,
375+
unsigned *out);
376+
372377
/* A hook to report invalid files in pack directory */
373378
#define PACKDIR_FILE_PACK 1
374379
#define PACKDIR_FILE_IDX 2

0 commit comments

Comments
 (0)