Skip to content

Commit

Permalink
Merge branch 'jc/pack-reuse'
Browse files Browse the repository at this point in the history
* jc/pack-reuse:
  pack-objects: avoid delta chains that are too long.
  • Loading branch information
Junio C Hamano committed Feb 18, 2006
2 parents 9b1320a + e4c9327 commit 416b3cb
Showing 1 changed file with 35 additions and 8 deletions.
43 changes: 35 additions & 8 deletions pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@ static const char pack_usage[] = "git-pack-objects [-q] [--no-reuse-delta] [--no
struct object_entry {
unsigned char sha1[20];
unsigned long size; /* uncompressed size */
unsigned long offset; /* offset into the final pack file (nonzero if already written) */
unsigned long offset; /* offset into the final pack file;
* nonzero if already written.
*/
unsigned int depth; /* delta depth */
unsigned int delta_limit; /* base adjustment for in-pack delta */
unsigned int hash; /* name hint hash */
enum object_type type;
unsigned char edge; /* reused delta chain points at this entry. */
enum object_type in_pack_type; /* could be delta */
unsigned long delta_size; /* delta data size (uncompressed) */
struct object_entry *delta; /* delta base object */
struct packed_git *in_pack; /* already in pack */
unsigned int in_pack_offset;
struct object_entry *delta_child; /* delitified objects who bases me */
struct object_entry *delta_sibling; /* other deltified objects who
* uses the same base as me
*/
};

/*
Expand Down Expand Up @@ -470,7 +476,8 @@ static void check_object(struct object_entry *entry)
entry->delta = base_entry;
entry->type = OBJ_DELTA;

base_entry->edge = 1;
entry->delta_sibling = base_entry->delta_child;
base_entry->delta_child = entry;

return;
}
Expand Down Expand Up @@ -513,15 +520,32 @@ static void hash_objects(void)
}
}

static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
{
struct object_entry *child = me->delta_child;
unsigned int m = n;
while (child) {
unsigned int c = check_delta_limit(child, n + 1);
if (m < c)
m = c;
child = child->delta_sibling;
}
return m;
}

static void get_object_details(void)
{
int i;
struct object_entry *entry = objects;
struct object_entry *entry;

hash_objects();
prepare_pack_ix();
for (i = 0; i < nr_objects; i++)
check_object(entry++);
for (i = 0, entry = objects; i < nr_objects; i++, entry++)
check_object(entry);
for (i = 0, entry = objects; i < nr_objects; i++, entry++)
if (!entry->delta && entry->delta_child)
entry->delta_limit =
check_delta_limit(entry, 1);
}

typedef int (*entry_sort_t)(const struct object_entry *, const struct object_entry *);
Expand Down Expand Up @@ -598,8 +622,11 @@ static int try_delta(struct unpacked *cur, struct unpacked *old, unsigned max_de
* that depend on the current object into account -- otherwise
* they would become too deep.
*/
if (cur_entry->edge)
max_depth /= 4;
if (cur_entry->delta_child) {
if (max_depth <= cur_entry->delta_limit)
return 0;
max_depth -= cur_entry->delta_limit;
}

size = cur_entry->size;
if (size < 50)
Expand Down

0 comments on commit 416b3cb

Please sign in to comment.