Commit 60ecdf59 by David Michael Barr

pack: iterate objects in offset order

Compute the ordering on demand and persist until the index is freed.
parent 687ec68b
...@@ -54,6 +54,10 @@ static int packfile_error(const char *message) ...@@ -54,6 +54,10 @@ static int packfile_error(const char *message)
static void pack_index_free(struct git_pack_file *p) static void pack_index_free(struct git_pack_file *p)
{ {
if (p->oids) {
git__free(p->oids);
p->oids = NULL;
}
if (p->index_map.data) { if (p->index_map.data) {
git_futils_mmap_free(&p->index_map); git_futils_mmap_free(&p->index_map);
p->index_map.data = NULL; p->index_map.data = NULL;
...@@ -686,13 +690,16 @@ static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_ ...@@ -686,13 +690,16 @@ static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_
} }
} }
static int git__memcmp4(const void *a, const void *b) {
return memcmp(a, b, 4);
}
int git_pack_foreach_entry( int git_pack_foreach_entry(
struct git_pack_file *p, struct git_pack_file *p,
int (*cb)(git_oid *oid, void *data), int (*cb)(git_oid *oid, void *data),
void *data) void *data)
{ {
const unsigned char *index = p->index_map.data, *current; const unsigned char *index = p->index_map.data, *current;
unsigned stride;
uint32_t i; uint32_t i;
if (index == NULL) { if (index == NULL) {
...@@ -712,21 +719,38 @@ int git_pack_foreach_entry( ...@@ -712,21 +719,38 @@ int git_pack_foreach_entry(
index += 4 * 256; index += 4 * 256;
if (p->oids == NULL) {
git_vector offsets, oids;
int error;
if ((error = git_vector_init(&oids, p->num_objects, NULL)))
return error;
if ((error = git_vector_init(&offsets, p->num_objects, git__memcmp4)))
return error;
if (p->index_version > 1) { if (p->index_version > 1) {
stride = 20; const unsigned char *off = index + 24 * p->num_objects;
for (i = 0; i < p->num_objects; i++)
git_vector_insert(&offsets, (void*)&off[4 * i]);
git_vector_sort(&offsets);
git_vector_foreach(&offsets, i, current)
git_vector_insert(&oids, (void*)&index[5 * (current - off)]);
} else { } else {
stride = 24; for (i = 0; i < p->num_objects; i++)
index += 4; git_vector_insert(&offsets, (void*)&index[24 * i]);
git_vector_sort(&offsets);
git_vector_foreach(&offsets, i, current)
git_vector_insert(&oids, (void*)&current[4]);
}
git_vector_free(&offsets);
p->oids = (git_oid **)oids.contents;
} }
current = index; for (i = 0; i < p->num_objects; i++)
for (i = 0; i < p->num_objects; i++) { if (cb(p->oids[i], data))
if (cb((git_oid *)current, data))
return GIT_EUSER; return GIT_EUSER;
current += stride;
}
return 0; return 0;
} }
......
...@@ -64,6 +64,7 @@ struct git_pack_file { ...@@ -64,6 +64,7 @@ struct git_pack_file {
unsigned pack_local:1, pack_keep:1, has_cache:1; unsigned pack_local:1, pack_keep:1, has_cache:1;
git_oid sha1; git_oid sha1;
git_vector cache; git_vector cache;
git_oid **oids;
/* something like ".git/objects/pack/xxxxx.pack" */ /* something like ".git/objects/pack/xxxxx.pack" */
char pack_name[GIT_FLEX_ARRAY]; /* more */ char pack_name[GIT_FLEX_ARRAY]; /* more */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment