* 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;
enum object_type in_pack_type; /* could be delta */
sha1_to_hex(entry->sha1));
}
-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)
{
uint32_t i;
prepare_pack_ix();
for (i = 0, entry = objects; i < nr_objects; i++, entry++)
check_object(entry);
-
- if (nr_objects == nr_result) {
- /*
- * Depth of objects that depend on the entry -- this
- * is subtracted from depth-max to break too deep
- * delta chain because of delta data reusing.
- * However, we loosen this restriction when we know we
- * are creating a thin pack -- it will have to be
- * expanded on the other end anyway, so do not
- * artificially cut the delta chain and let it go as
- * deep as it wants.
- */
- 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 *);
trg_entry->in_pack_type != OBJ_OFS_DELTA)
return 0;
- /*
- * If the current object is at pack edge, take the depth the
- * objects that depend on the current object into account --
- * otherwise they would become too deep.
- */
- if (trg_entry->delta_child) {
- if (max_depth <= trg_entry->delta_limit)
- return 0;
- max_depth -= trg_entry->delta_limit;
- }
+ /* Let's not bust the allowed depth. */
if (src_entry->depth >= max_depth)
return 0;
return 1;
}
-static void progress_interval(int signum)
+static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
{
- progress_update = 1;
+ 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 find_deltas(struct object_entry **list, int window, int depth)
unsigned int array_size = window * sizeof(struct unpacked);
struct unpacked *array;
unsigned last_percent = 999;
+ int max_depth;
if (!nr_objects)
return;
n->data = NULL;
n->entry = entry;
+ /*
+ * If the current object is at pack edge, take the depth the
+ * objects that depend on the current object into account
+ * otherwise they would become too deep.
+ */
+ max_depth = depth;
+ if (entry->delta_child) {
+ max_depth -= check_delta_limit(entry, 0);
+ if (max_depth <= 0)
+ goto next;
+ }
+
j = window;
while (--j > 0) {
uint32_t other_idx = idx + j;
m = array + other_idx;
if (!m->entry)
break;
- if (try_delta(n, m, depth) < 0)
+ if (try_delta(n, m, max_depth) < 0)
break;
}
+
/* if we made n a delta, and if n is already at max
* depth, leaving it in the window is pointless. we
* should evict it first.
if (entry->delta && depth <= entry->depth)
continue;
+ next:
idx++;
if (idx >= window)
idx = 0;
return 1;
}
+static void progress_interval(int signum)
+{
+ progress_update = 1;
+}
+
static void setup_progress_signal(void)
{
struct sigaction sa;