pack-objects: rework check_delta_limit usage
[gitweb.git] / builtin-pack-objects.c
index 869ca1ab269859c6e23676f329e8c59e4f6aeb20..d44b8f4c01ff74d4726276f8ccc81b9db21ccd0c 100644 (file)
@@ -27,7 +27,6 @@ struct object_entry {
                                 * 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 */
@@ -1172,19 +1171,6 @@ static void check_object(struct object_entry *entry)
                    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;
@@ -1193,23 +1179,6 @@ static void get_object_details(void)
        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 *);
@@ -1322,16 +1291,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
            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;
 
@@ -1378,9 +1338,17 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        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)
@@ -1389,6 +1357,7 @@ 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;
@@ -1429,6 +1398,18 @@ static void find_deltas(struct object_entry **list, int window, int depth)
                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;
@@ -1438,9 +1419,10 @@ 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, 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.
@@ -1448,6 +1430,7 @@ static void find_deltas(struct object_entry **list, int window, int depth)
                if (entry->delta && depth <= entry->depth)
                        continue;
 
+               next:
                idx++;
                if (idx >= window)
                        idx = 0;
@@ -1525,6 +1508,11 @@ static int reuse_cached_pack(unsigned char *sha1)
        return 1;
 }
 
+static void progress_interval(int signum)
+{
+       progress_update = 1;
+}
+
 static void setup_progress_signal(void)
 {
        struct sigaction sa;