Skip to content

Commit 8aac67a

Browse files
derrickstoleegitster
authored andcommitted
midx: use midx in abbreviation calculations
Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3715a63 commit 8aac67a

File tree

5 files changed

+91
-0
lines changed

5 files changed

+91
-0
lines changed

midx.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,17 @@ int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32
203203
MIDX_HASH_LEN, result);
204204
}
205205

206+
struct object_id *nth_midxed_object_oid(struct object_id *oid,
207+
struct multi_pack_index *m,
208+
uint32_t n)
209+
{
210+
if (n >= m->num_objects)
211+
return NULL;
212+
213+
hashcpy(oid->hash, m->chunk_oid_lookup + m->hash_len * n);
214+
return oid;
215+
}
216+
206217
static off_t nth_midxed_offset(struct multi_pack_index *m, uint32_t pos)
207218
{
208219
const unsigned char *offset_data;

midx.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ struct multi_pack_index {
3131

3232
struct multi_pack_index *load_multi_pack_index(const char *object_dir);
3333
int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result);
34+
struct object_id *nth_midxed_object_oid(struct object_id *oid,
35+
struct multi_pack_index *m,
36+
uint32_t n);
3437
int fill_midx_entry(const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m);
3538
int prepare_multi_pack_index_one(struct repository *r, const char *object_dir);
3639

packfile.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,12 @@ struct packed_git *get_packed_git(struct repository *r)
961961
return r->objects->packed_git;
962962
}
963963

964+
struct multi_pack_index *get_multi_pack_index(struct repository *r)
965+
{
966+
prepare_packed_git(r);
967+
return r->objects->multi_pack_index;
968+
}
969+
964970
struct list_head *get_packed_git_mru(struct repository *r)
965971
{
966972
prepare_packed_git(r);

packfile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ extern void install_packed_git(struct repository *r, struct packed_git *pack);
4545

4646
struct packed_git *get_packed_git(struct repository *r);
4747
struct list_head *get_packed_git_mru(struct repository *r);
48+
struct multi_pack_index *get_multi_pack_index(struct repository *r);
4849

4950
/*
5051
* Give a rough count of objects in the repository. This sacrifices accuracy

sha1-name.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "packfile.h"
1313
#include "object-store.h"
1414
#include "repository.h"
15+
#include "midx.h"
1516

1617
static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);
1718

@@ -149,6 +150,32 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
149150
return 1;
150151
}
151152

153+
static void unique_in_midx(struct multi_pack_index *m,
154+
struct disambiguate_state *ds)
155+
{
156+
uint32_t num, i, first = 0;
157+
const struct object_id *current = NULL;
158+
num = m->num_objects;
159+
160+
if (!num)
161+
return;
162+
163+
bsearch_midx(&ds->bin_pfx, m, &first);
164+
165+
/*
166+
* At this point, "first" is the location of the lowest object
167+
* with an object name that could match "bin_pfx". See if we have
168+
* 0, 1 or more objects that actually match(es).
169+
*/
170+
for (i = first; i < num && !ds->ambiguous; i++) {
171+
struct object_id oid;
172+
current = nth_midxed_object_oid(&oid, m, i);
173+
if (!match_sha(ds->len, ds->bin_pfx.hash, current->hash))
174+
break;
175+
update_candidates(ds, current);
176+
}
177+
}
178+
152179
static void unique_in_pack(struct packed_git *p,
153180
struct disambiguate_state *ds)
154181
{
@@ -177,8 +204,12 @@ static void unique_in_pack(struct packed_git *p,
177204

178205
static void find_short_packed_object(struct disambiguate_state *ds)
179206
{
207+
struct multi_pack_index *m;
180208
struct packed_git *p;
181209

210+
for (m = get_multi_pack_index(the_repository); m && !ds->ambiguous;
211+
m = m->next)
212+
unique_in_midx(m, ds);
182213
for (p = get_packed_git(the_repository); p && !ds->ambiguous;
183214
p = p->next)
184215
unique_in_pack(p, ds);
@@ -527,6 +558,42 @@ static int extend_abbrev_len(const struct object_id *oid, void *cb_data)
527558
return 0;
528559
}
529560

561+
static void find_abbrev_len_for_midx(struct multi_pack_index *m,
562+
struct min_abbrev_data *mad)
563+
{
564+
int match = 0;
565+
uint32_t num, first = 0;
566+
struct object_id oid;
567+
const struct object_id *mad_oid;
568+
569+
if (!m->num_objects)
570+
return;
571+
572+
num = m->num_objects;
573+
mad_oid = mad->oid;
574+
match = bsearch_midx(mad_oid, m, &first);
575+
576+
/*
577+
* first is now the position in the packfile where we would insert
578+
* mad->hash if it does not exist (or the position of mad->hash if
579+
* it does exist). Hence, we consider a maximum of two objects
580+
* nearby for the abbreviation length.
581+
*/
582+
mad->init_len = 0;
583+
if (!match) {
584+
if (nth_midxed_object_oid(&oid, m, first))
585+
extend_abbrev_len(&oid, mad);
586+
} else if (first < num - 1) {
587+
if (nth_midxed_object_oid(&oid, m, first + 1))
588+
extend_abbrev_len(&oid, mad);
589+
}
590+
if (first > 0) {
591+
if (nth_midxed_object_oid(&oid, m, first - 1))
592+
extend_abbrev_len(&oid, mad);
593+
}
594+
mad->init_len = mad->cur_len;
595+
}
596+
530597
static void find_abbrev_len_for_pack(struct packed_git *p,
531598
struct min_abbrev_data *mad)
532599
{
@@ -565,8 +632,11 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
565632

566633
static void find_abbrev_len_packed(struct min_abbrev_data *mad)
567634
{
635+
struct multi_pack_index *m;
568636
struct packed_git *p;
569637

638+
for (m = get_multi_pack_index(the_repository); m; m = m->next)
639+
find_abbrev_len_for_midx(m, mad);
570640
for (p = get_packed_git(the_repository); p; p = p->next)
571641
find_abbrev_len_for_pack(p, mad);
572642
}

0 commit comments

Comments
 (0)