Skip to content

Commit 28caad6

Browse files
committed
Merge branch 'rs/packfile-bad-object-list-in-oidset'
Replace a handcrafted data structure used to keep track of bad objects in the packfile API by an oidset. * rs/packfile-bad-object-list-in-oidset: packfile: use oidset for bad objects packfile: convert has_packed_and_bad() to object_id packfile: convert mark_bad_packed_object() to object_id midx: inline nth_midxed_pack_entry() oidset: make oidset_size() an inline function
2 parents 6c84b00 + 09ef661 commit 28caad6

File tree

7 files changed

+32
-65
lines changed

7 files changed

+32
-65
lines changed

midx.c

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -283,14 +283,18 @@ uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos)
283283
(off_t)pos * MIDX_CHUNK_OFFSET_WIDTH);
284284
}
285285

286-
static int nth_midxed_pack_entry(struct repository *r,
287-
struct multi_pack_index *m,
288-
struct pack_entry *e,
289-
uint32_t pos)
286+
int fill_midx_entry(struct repository * r,
287+
const struct object_id *oid,
288+
struct pack_entry *e,
289+
struct multi_pack_index *m)
290290
{
291+
uint32_t pos;
291292
uint32_t pack_int_id;
292293
struct packed_git *p;
293294

295+
if (!bsearch_midx(oid, m, &pos))
296+
return 0;
297+
294298
if (pos >= m->num_objects)
295299
return 0;
296300

@@ -310,35 +314,16 @@ static int nth_midxed_pack_entry(struct repository *r,
310314
if (!is_pack_valid(p))
311315
return 0;
312316

313-
if (p->num_bad_objects) {
314-
uint32_t i;
315-
struct object_id oid;
316-
nth_midxed_object_oid(&oid, m, pos);
317-
for (i = 0; i < p->num_bad_objects; i++)
318-
if (hasheq(oid.hash,
319-
p->bad_object_sha1 + the_hash_algo->rawsz * i))
320-
return 0;
321-
}
317+
if (oidset_size(&p->bad_objects) &&
318+
oidset_contains(&p->bad_objects, oid))
319+
return 0;
322320

323321
e->offset = nth_midxed_offset(m, pos);
324322
e->p = p;
325323

326324
return 1;
327325
}
328326

329-
int fill_midx_entry(struct repository * r,
330-
const struct object_id *oid,
331-
struct pack_entry *e,
332-
struct multi_pack_index *m)
333-
{
334-
uint32_t pos;
335-
336-
if (!bsearch_midx(oid, m, &pos))
337-
return 0;
338-
339-
return nth_midxed_pack_entry(r, m, e, pos);
340-
}
341-
342327
/* Match "foo.idx" against either "foo.pack" _or_ "foo.idx". */
343328
static int cmp_idx_or_pack_name(const char *idx_or_pack_name,
344329
const char *idx_name)

object-file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,7 +1642,7 @@ static int do_oid_object_info_extended(struct repository *r,
16421642
return 0;
16431643
rtype = packed_object_info(r, e.p, e.offset, oi);
16441644
if (rtype < 0) {
1645-
mark_bad_packed_object(e.p, real->hash);
1645+
mark_bad_packed_object(e.p, real);
16461646
return do_oid_object_info_extended(r, real, oi, 0);
16471647
} else if (oi->whence == OI_PACKED) {
16481648
oi->u.packed.offset = e.offset;
@@ -1751,7 +1751,7 @@ void *read_object_file_extended(struct repository *r,
17511751
die(_("loose object %s (stored in %s) is corrupt"),
17521752
oid_to_hex(repl), path);
17531753

1754-
if ((p = has_packed_and_bad(r, repl->hash)) != NULL)
1754+
if ((p = has_packed_and_bad(r, repl)) != NULL)
17551755
die(_("packed object %s (stored in %s) is corrupt"),
17561756
oid_to_hex(repl), p->pack_name);
17571757
obj_read_unlock();

object-store.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "khash.h"
1111
#include "dir.h"
1212
#include "oidtree.h"
13+
#include "oidset.h"
1314

1415
struct object_directory {
1516
struct object_directory *next;
@@ -76,9 +77,8 @@ struct packed_git {
7677
const void *index_data;
7778
size_t index_size;
7879
uint32_t num_objects;
79-
uint32_t num_bad_objects;
8080
uint32_t crc_offset;
81-
unsigned char *bad_object_sha1;
81+
struct oidset bad_objects;
8282
int index_version;
8383
time_t mtime;
8484
int pack_fd;

oidset.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ void oidset_clear(struct oidset *set)
3636
oidset_init(set, 0);
3737
}
3838

39-
int oidset_size(struct oidset *set)
40-
{
41-
return kh_size(&set->set);
42-
}
43-
4439
void oidset_parse_file(struct oidset *set, const char *path)
4540
{
4641
oidset_parse_file_carefully(set, path, NULL, NULL);

oidset.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ int oidset_remove(struct oidset *set, const struct object_id *oid);
5757
/**
5858
* Returns the number of oids in the set.
5959
*/
60-
int oidset_size(struct oidset *set);
60+
static inline int oidset_size(const struct oidset *set)
61+
{
62+
return kh_size(&set->set);
63+
}
6164

6265
/**
6366
* Remove all entries from the oidset, freeing any resources associated with

packfile.c

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,31 +1161,19 @@ int unpack_object_header(struct packed_git *p,
11611161
return type;
11621162
}
11631163

1164-
void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1)
1164+
void mark_bad_packed_object(struct packed_git *p, const struct object_id *oid)
11651165
{
1166-
unsigned i;
1167-
const unsigned hashsz = the_hash_algo->rawsz;
1168-
for (i = 0; i < p->num_bad_objects; i++)
1169-
if (hasheq(sha1, p->bad_object_sha1 + hashsz * i))
1170-
return;
1171-
p->bad_object_sha1 = xrealloc(p->bad_object_sha1,
1172-
st_mult(GIT_MAX_RAWSZ,
1173-
st_add(p->num_bad_objects, 1)));
1174-
hashcpy(p->bad_object_sha1 + hashsz * p->num_bad_objects, sha1);
1175-
p->num_bad_objects++;
1166+
oidset_insert(&p->bad_objects, oid);
11761167
}
11771168

11781169
const struct packed_git *has_packed_and_bad(struct repository *r,
1179-
const unsigned char *sha1)
1170+
const struct object_id *oid)
11801171
{
11811172
struct packed_git *p;
1182-
unsigned i;
11831173

11841174
for (p = r->objects->packed_git; p; p = p->next)
1185-
for (i = 0; i < p->num_bad_objects; i++)
1186-
if (hasheq(sha1,
1187-
p->bad_object_sha1 + the_hash_algo->rawsz * i))
1188-
return p;
1175+
if (oidset_contains(&p->bad_objects, oid))
1176+
return p;
11891177
return NULL;
11901178
}
11911179

@@ -1272,7 +1260,7 @@ static int retry_bad_packed_offset(struct repository *r,
12721260
if (offset_to_pack_pos(p, obj_offset, &pos) < 0)
12731261
return OBJ_BAD;
12741262
nth_packed_object_id(&oid, p, pack_pos_to_index(p, pos));
1275-
mark_bad_packed_object(p, oid.hash);
1263+
mark_bad_packed_object(p, &oid);
12761264
type = oid_object_info(r, &oid, NULL);
12771265
if (type <= OBJ_NONE)
12781266
return OBJ_BAD;
@@ -1722,7 +1710,7 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
17221710
nth_packed_object_id(&oid, p, index_pos);
17231711
error("bad packed object CRC for %s",
17241712
oid_to_hex(&oid));
1725-
mark_bad_packed_object(p, oid.hash);
1713+
mark_bad_packed_object(p, &oid);
17261714
data = NULL;
17271715
goto out;
17281716
}
@@ -1811,7 +1799,7 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
18111799
" at offset %"PRIuMAX" from %s",
18121800
oid_to_hex(&base_oid), (uintmax_t)obj_offset,
18131801
p->pack_name);
1814-
mark_bad_packed_object(p, base_oid.hash);
1802+
mark_bad_packed_object(p, &base_oid);
18151803
base = read_object(r, &base_oid, &type, &base_size);
18161804
external_base = base;
18171805
}
@@ -2016,13 +2004,9 @@ static int fill_pack_entry(const struct object_id *oid,
20162004
{
20172005
off_t offset;
20182006

2019-
if (p->num_bad_objects) {
2020-
unsigned i;
2021-
for (i = 0; i < p->num_bad_objects; i++)
2022-
if (hasheq(oid->hash,
2023-
p->bad_object_sha1 + the_hash_algo->rawsz * i))
2024-
return 0;
2025-
}
2007+
if (oidset_size(&p->bad_objects) &&
2008+
oidset_contains(&p->bad_objects, oid))
2009+
return 0;
20262010

20272011
offset = find_pack_entry_one(oid->hash, p);
20282012
if (!offset)

packfile.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ int packed_object_info(struct repository *r,
159159
struct packed_git *pack,
160160
off_t offset, struct object_info *);
161161

162-
void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);
163-
const struct packed_git *has_packed_and_bad(struct repository *r, const unsigned char *sha1);
162+
void mark_bad_packed_object(struct packed_git *, const struct object_id *);
163+
const struct packed_git *has_packed_and_bad(struct repository *, const struct object_id *);
164164

165165
#define ON_DISK_KEEP_PACKS 1
166166
#define IN_CORE_KEEP_PACKS 2

0 commit comments

Comments
 (0)