From 51d1e83f91a16363930023a5c39f79f270c04653 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 29 Jun 2006 14:04:01 -0700 Subject: Do not try futile object pairs when repacking. In the repacking window, if both objects we are looking at already came from the same (old) pack-file, don't bother delta'ing them against each other. That means that we'll still always check for better deltas for (and against!) _unpacked_ objects, but assuming incremental repacks, you'll avoid the delta creation 99% of the time. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- pack-objects.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'pack-objects.c') diff --git a/pack-objects.c b/pack-objects.c index bed2497b79..6e1767652c 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -987,6 +987,13 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, if (trg_entry->preferred_base) return -1; + /* + * We do not bother to try a delta that we discarded + * on an earlier try. + */ + if (trg_entry->in_pack && trg_entry->in_pack == src_entry->in_pack) + return 0; + /* * If the current object is at pack edge, take the depth the * objects that depend on the current object into account -- -- cgit 1.2.3-korg From 8dbbd14ea3ae1b4e825f1e7d314afddf26c67298 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 29 Jun 2006 23:44:52 -0400 Subject: consider previous pack undeltified object state only when reusing delta data Without this there would never be a chance to improve packing for previously undeltified objects. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- pack-objects.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'pack-objects.c') diff --git a/pack-objects.c b/pack-objects.c index 6e1767652c..47da33baa3 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -989,9 +989,10 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, /* * We do not bother to try a delta that we discarded - * on an earlier try. + * on an earlier try, but only when reusing delta data. */ - if (trg_entry->in_pack && trg_entry->in_pack == src_entry->in_pack) + if (!no_reuse_delta && trg_entry->in_pack && + trg_entry->in_pack == src_entry->in_pack) return 0; /* -- cgit 1.2.3-korg From 560b25a86f30ad81d2bc3a383da19c3b7e631b8b Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 30 Jun 2006 22:55:30 -0400 Subject: don't load objects needlessly when repacking If no delta is attempted on some objects then it is useless to load them in memory, neither create any delta index for them. The best thing to do is therefore to load and index them only when really needed. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- pack-objects.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'pack-objects.c') diff --git a/pack-objects.c b/pack-objects.c index 47da33baa3..b486ea528a 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -970,11 +970,12 @@ struct unpacked { * one. */ static int try_delta(struct unpacked *trg, struct unpacked *src, - struct delta_index *src_index, unsigned max_depth) + unsigned max_depth) { struct object_entry *trg_entry = trg->entry; struct object_entry *src_entry = src->entry; - unsigned long size, src_size, delta_size, sizediff, max_size; + unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; + char type[10]; void *delta_buf; /* Don't bother doing diffs between different types */ @@ -1009,19 +1010,38 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, return 0; /* Now some size filtering heuristics. */ - size = trg_entry->size; - max_size = size/2 - 20; + trg_size = trg_entry->size; + max_size = trg_size/2 - 20; max_size = max_size * (max_depth - src_entry->depth) / max_depth; if (max_size == 0) return 0; if (trg_entry->delta && trg_entry->delta_size <= max_size) max_size = trg_entry->delta_size-1; src_size = src_entry->size; - sizediff = src_size < size ? size - src_size : 0; + sizediff = src_size < trg_size ? trg_size - src_size : 0; if (sizediff >= max_size) return 0; - delta_buf = create_delta(src_index, trg->data, size, &delta_size, max_size); + /* Load data if not already done */ + if (!trg->data) { + trg->data = read_sha1_file(trg_entry->sha1, type, &sz); + if (sz != trg_size) + die("object %s inconsistent object length (%lu vs %lu)", + sha1_to_hex(trg_entry->sha1), sz, trg_size); + } + if (!src->data) { + src->data = read_sha1_file(src_entry->sha1, type, &sz); + if (sz != src_size) + die("object %s inconsistent object length (%lu vs %lu)", + sha1_to_hex(src_entry->sha1), sz, src_size); + } + if (!src->index) { + src->index = create_delta_index(src->data, src_size); + if (!src->index) + die("out of memory"); + } + + delta_buf = create_delta(src->index, trg->data, trg_size, &delta_size, max_size); if (!delta_buf) return 0; @@ -1054,8 +1074,6 @@ static void find_deltas(struct object_entry **list, int window, int depth) while (--i >= 0) { struct object_entry *entry = list[i]; struct unpacked *n = array + idx; - unsigned long size; - char type[10]; int j; if (!entry->preferred_base) @@ -1082,11 +1100,8 @@ static void find_deltas(struct object_entry **list, int window, int depth) free_delta_index(n->index); n->index = NULL; free(n->data); + n->data = NULL; n->entry = entry; - n->data = read_sha1_file(entry->sha1, type, &size); - if (size != entry->size) - die("object %s inconsistent object length (%lu vs %lu)", - sha1_to_hex(entry->sha1), size, entry->size); j = window; while (--j > 0) { @@ -1097,7 +1112,7 @@ static void find_deltas(struct object_entry **list, int window, int depth) m = array + other_idx; if (!m->entry) break; - if (try_delta(n, m, m->index, depth) < 0) + if (try_delta(n, m, depth) < 0) break; } /* if we made n a delta, and if n is already at max @@ -1107,10 +1122,6 @@ static void find_deltas(struct object_entry **list, int window, int depth) if (entry->delta && depth <= entry->depth) continue; - n->index = create_delta_index(n->data, size); - if (!n->index) - die("out of memory"); - idx++; if (idx >= window) idx = 0; -- cgit 1.2.3-korg