Skip to content

Commit e30bff8

Browse files
pks-tgitster
authored andcommitted
object-name: move logic to iterate through packed prefixed objects
Similar to the preceding commit, move the logic to iterate through objects that have a given prefix into "packfile.c". Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 284b786 commit e30bff8

2 files changed

Lines changed: 181 additions & 87 deletions

File tree

object-name.c

Lines changed: 7 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ static void update_candidates(struct disambiguate_state *ds, const struct object
100100
/* otherwise, current can be discarded and candidate is still good */
101101
}
102102

103-
static int match_hash(unsigned, const unsigned char *, const unsigned char *);
104-
105103
static int match_prefix(const struct object_id *oid, struct object_info *oi UNUSED, void *arg)
106104
{
107105
struct disambiguate_state *ds = arg;
@@ -122,103 +120,25 @@ static void find_short_object_filename(struct disambiguate_state *ds)
122120
odb_source_loose_for_each_object(source, NULL, match_prefix, ds, &opts);
123121
}
124122

125-
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
126-
{
127-
do {
128-
if (*a != *b)
129-
return 0;
130-
a++;
131-
b++;
132-
len -= 2;
133-
} while (len > 1);
134-
if (len)
135-
if ((*a ^ *b) & 0xf0)
136-
return 0;
137-
return 1;
138-
}
139-
140-
static void unique_in_midx(struct multi_pack_index *m,
141-
struct disambiguate_state *ds)
142-
{
143-
for (; m; m = m->base_midx) {
144-
uint32_t num, i, first = 0;
145-
const struct object_id *current = NULL;
146-
int len = ds->len > ds->repo->hash_algo->hexsz ?
147-
ds->repo->hash_algo->hexsz : ds->len;
148-
149-
if (!m->num_objects)
150-
continue;
151-
152-
num = m->num_objects + m->num_objects_in_base;
153-
154-
bsearch_one_midx(&ds->bin_pfx, m, &first);
155-
156-
/*
157-
* At this point, "first" is the location of the lowest
158-
* object with an object name that could match
159-
* "bin_pfx". See if we have 0, 1 or more objects that
160-
* actually match(es).
161-
*/
162-
for (i = first; i < num && !ds->ambiguous; i++) {
163-
struct object_id oid;
164-
current = nth_midxed_object_oid(&oid, m, i);
165-
if (!match_hash(len, ds->bin_pfx.hash, current->hash))
166-
break;
167-
update_candidates(ds, current);
168-
}
169-
}
170-
}
171-
172-
static void unique_in_pack(struct packed_git *p,
173-
struct disambiguate_state *ds)
174-
{
175-
uint32_t num, i, first = 0;
176-
int len = ds->len > ds->repo->hash_algo->hexsz ?
177-
ds->repo->hash_algo->hexsz : ds->len;
178-
179-
if (p->multi_pack_index)
180-
return;
181-
182-
if (open_pack_index(p) || !p->num_objects)
183-
return;
184-
185-
num = p->num_objects;
186-
bsearch_pack(&ds->bin_pfx, p, &first);
187-
188-
/*
189-
* At this point, "first" is the location of the lowest object
190-
* with an object name that could match "bin_pfx". See if we have
191-
* 0, 1 or more objects that actually match(es).
192-
*/
193-
for (i = first; i < num && !ds->ambiguous; i++) {
194-
struct object_id oid;
195-
nth_packed_object_id(&oid, p, i);
196-
if (!match_hash(len, ds->bin_pfx.hash, oid.hash))
197-
break;
198-
update_candidates(ds, &oid);
199-
}
200-
}
201-
202123
static void find_short_packed_object(struct disambiguate_state *ds)
203124
{
125+
struct odb_for_each_object_options opts = {
126+
.prefix = &ds->bin_pfx,
127+
.prefix_hex_len = ds->len,
128+
};
204129
struct odb_source *source;
205-
struct packed_git *p;
206130

207131
/* Skip, unless oids from the storage hash algorithm are wanted */
208132
if (ds->bin_pfx.algo && (&hash_algos[ds->bin_pfx.algo] != ds->repo->hash_algo))
209133
return;
210134

211135
odb_prepare_alternates(ds->repo->objects);
212-
for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) {
213-
struct multi_pack_index *m = get_multi_pack_index(source);
214-
if (m)
215-
unique_in_midx(m, ds);
216-
}
136+
for (source = ds->repo->objects->sources; source; source = source->next) {
137+
struct odb_source_files *files = odb_source_files_downcast(source);
217138

218-
repo_for_each_pack(ds->repo, p) {
139+
packfile_store_for_each_object(files->packed, NULL, match_prefix, ds, &opts);
219140
if (ds->ambiguous)
220141
break;
221-
unique_in_pack(p, ds);
222142
}
223143
}
224144

packfile.c

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2371,6 +2371,177 @@ static int packfile_store_for_each_object_wrapper(const struct object_id *oid,
23712371
}
23722372
}
23732373

2374+
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
2375+
{
2376+
do {
2377+
if (*a != *b)
2378+
return 0;
2379+
a++;
2380+
b++;
2381+
len -= 2;
2382+
} while (len > 1);
2383+
if (len)
2384+
if ((*a ^ *b) & 0xf0)
2385+
return 0;
2386+
return 1;
2387+
}
2388+
2389+
static int for_each_prefixed_object_in_midx(
2390+
struct packfile_store *store,
2391+
struct multi_pack_index *m,
2392+
const struct odb_for_each_object_options *opts,
2393+
struct packfile_store_for_each_object_wrapper_data *data)
2394+
{
2395+
int ret;
2396+
2397+
for (; m; m = m->base_midx) {
2398+
uint32_t num, i, first = 0;
2399+
int len = opts->prefix_hex_len > m->source->odb->repo->hash_algo->hexsz ?
2400+
m->source->odb->repo->hash_algo->hexsz : opts->prefix_hex_len;
2401+
2402+
if (!m->num_objects)
2403+
continue;
2404+
2405+
num = m->num_objects + m->num_objects_in_base;
2406+
2407+
bsearch_one_midx(opts->prefix, m, &first);
2408+
2409+
/*
2410+
* At this point, "first" is the location of the lowest
2411+
* object with an object name that could match "opts->prefix".
2412+
* See if we have 0, 1 or more objects that actually match(es).
2413+
*/
2414+
for (i = first; i < num; i++) {
2415+
const struct object_id *current = NULL;
2416+
struct object_id oid;
2417+
2418+
current = nth_midxed_object_oid(&oid, m, i);
2419+
2420+
if (!match_hash(len, opts->prefix->hash, current->hash))
2421+
break;
2422+
2423+
if (data->request) {
2424+
struct object_info oi = *data->request;
2425+
2426+
ret = packfile_store_read_object_info(store, current,
2427+
&oi, 0);
2428+
if (ret)
2429+
goto out;
2430+
2431+
ret = data->cb(&oid, &oi, data->cb_data);
2432+
if (ret)
2433+
goto out;
2434+
} else {
2435+
ret = data->cb(&oid, NULL, data->cb_data);
2436+
if (ret)
2437+
goto out;
2438+
}
2439+
}
2440+
}
2441+
2442+
ret = 0;
2443+
2444+
out:
2445+
return ret;
2446+
}
2447+
2448+
static int for_each_prefixed_object_in_pack(
2449+
struct packfile_store *store,
2450+
struct packed_git *p,
2451+
const struct odb_for_each_object_options *opts,
2452+
struct packfile_store_for_each_object_wrapper_data *data)
2453+
{
2454+
uint32_t num, i, first = 0;
2455+
int len = opts->prefix_hex_len > p->repo->hash_algo->hexsz ?
2456+
p->repo->hash_algo->hexsz : opts->prefix_hex_len;
2457+
int ret;
2458+
2459+
num = p->num_objects;
2460+
bsearch_pack(opts->prefix, p, &first);
2461+
2462+
/*
2463+
* At this point, "first" is the location of the lowest object
2464+
* with an object name that could match "bin_pfx". See if we have
2465+
* 0, 1 or more objects that actually match(es).
2466+
*/
2467+
for (i = first; i < num; i++) {
2468+
struct object_id oid;
2469+
2470+
nth_packed_object_id(&oid, p, i);
2471+
if (!match_hash(len, opts->prefix->hash, oid.hash))
2472+
break;
2473+
2474+
if (data->request) {
2475+
struct object_info oi = *data->request;
2476+
2477+
ret = packfile_store_read_object_info(store, &oid, &oi, 0);
2478+
if (ret)
2479+
goto out;
2480+
2481+
ret = data->cb(&oid, &oi, data->cb_data);
2482+
if (ret)
2483+
goto out;
2484+
} else {
2485+
ret = data->cb(&oid, NULL, data->cb_data);
2486+
if (ret)
2487+
goto out;
2488+
}
2489+
}
2490+
2491+
ret = 0;
2492+
2493+
out:
2494+
return ret;
2495+
}
2496+
2497+
static int packfile_store_for_each_prefixed_object(
2498+
struct packfile_store *store,
2499+
const struct odb_for_each_object_options *opts,
2500+
struct packfile_store_for_each_object_wrapper_data *data)
2501+
{
2502+
struct packfile_list_entry *e;
2503+
struct multi_pack_index *m;
2504+
bool pack_errors = false;
2505+
int ret;
2506+
2507+
if (opts->flags)
2508+
BUG("flags unsupported");
2509+
2510+
store->skip_mru_updates = true;
2511+
2512+
m = get_multi_pack_index(store->source);
2513+
if (m) {
2514+
ret = for_each_prefixed_object_in_midx(store, m, opts, data);
2515+
if (ret)
2516+
goto out;
2517+
}
2518+
2519+
for (e = packfile_store_get_packs(store); e; e = e->next) {
2520+
if (e->pack->multi_pack_index)
2521+
continue;
2522+
2523+
if (open_pack_index(e->pack)) {
2524+
pack_errors = true;
2525+
continue;
2526+
}
2527+
2528+
if (!e->pack->num_objects)
2529+
continue;
2530+
2531+
ret = for_each_prefixed_object_in_pack(store, e->pack, opts, data);
2532+
if (ret)
2533+
goto out;
2534+
}
2535+
2536+
ret = 0;
2537+
2538+
out:
2539+
store->skip_mru_updates = false;
2540+
if (!ret && pack_errors)
2541+
ret = -1;
2542+
return ret;
2543+
}
2544+
23742545
int packfile_store_for_each_object(struct packfile_store *store,
23752546
const struct object_info *request,
23762547
odb_for_each_object_cb cb,
@@ -2386,6 +2557,9 @@ int packfile_store_for_each_object(struct packfile_store *store,
23862557
struct packfile_list_entry *e;
23872558
int pack_errors = 0, ret;
23882559

2560+
if (opts->prefix)
2561+
return packfile_store_for_each_prefixed_object(store, opts, &data);
2562+
23892563
store->skip_mru_updates = true;
23902564

23912565
for (e = packfile_store_get_packs(store); e; e = e->next) {

0 commit comments

Comments
 (0)