Skip to content

Commit 09ef661

Browse files
rscharfegitster
authored andcommitted
packfile: use oidset for bad objects
Store the object ID of broken pack entries in an oidset instead of keeping only their hashes in an unsorted array. The resulting code is shorter and easier to read. It also handles the (hopefully) very rare case of having a high number of bad objects better. Helped-by: Jeff King <[email protected]> Signed-off-by: René Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7407d73 commit 09ef661

File tree

3 files changed

+11
-31
lines changed

3 files changed

+11
-31
lines changed

midx.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,9 @@ int fill_midx_entry(struct repository * r,
307307
if (!is_pack_valid(p))
308308
return 0;
309309

310-
if (p->num_bad_objects) {
311-
uint32_t i;
312-
for (i = 0; i < p->num_bad_objects; i++)
313-
if (hasheq(oid->hash,
314-
p->bad_object_sha1 + the_hash_algo->rawsz * i))
315-
return 0;
316-
}
310+
if (oidset_size(&p->bad_objects) &&
311+
oidset_contains(&p->bad_objects, oid))
312+
return 0;
317313

318314
e->offset = nth_midxed_offset(m, pos);
319315
e->p = p;

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;
@@ -75,9 +76,8 @@ struct packed_git {
7576
const void *index_data;
7677
size_t index_size;
7778
uint32_t num_objects;
78-
uint32_t num_bad_objects;
7979
uint32_t crc_offset;
80-
unsigned char *bad_object_sha1;
80+
struct oidset bad_objects;
8181
int index_version;
8282
time_t mtime;
8383
int pack_fd;

packfile.c

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,29 +1163,17 @@ int unpack_object_header(struct packed_git *p,
11631163

11641164
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(oid->hash, 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, oid->hash);
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,
11791170
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(oid->hash,
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

@@ -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)

0 commit comments

Comments
 (0)