pack-objects: clarify the use of object_entry::size
[gitweb.git] / builtin / pack-objects.c
index ec02641d2e773841ed85541d696a711cd34fee11..779f14a45ede8179bffa00c16075db95460ffb90 100644 (file)
@@ -1418,6 +1418,7 @@ static void check_object(struct object_entry *entry)
                off_t ofs;
                unsigned char *buf, c;
                enum object_type type;
+               unsigned long in_pack_size;
 
                buf = use_pack(p, &w_curs, entry->in_pack_offset, &avail);
 
@@ -1427,7 +1428,7 @@ static void check_object(struct object_entry *entry)
                 */
                used = unpack_object_header_buffer(buf, avail,
                                                   &type,
-                                                  &entry->size);
+                                                  &in_pack_size);
                if (used == 0)
                        goto give_up;
 
@@ -1444,6 +1445,7 @@ static void check_object(struct object_entry *entry)
                default:
                        /* Not a delta hence we've already got all we need. */
                        oe_set_type(entry, entry->in_pack_type);
+                       entry->size = in_pack_size;
                        entry->in_pack_header_size = used;
                        if (oe_type(entry) < OBJ_COMMIT || oe_type(entry) > OBJ_BLOB)
                                goto give_up;
@@ -1500,6 +1502,7 @@ static void check_object(struct object_entry *entry)
                         * circular deltas.
                         */
                        oe_set_type(entry, entry->in_pack_type);
+                       entry->size = in_pack_size; /* delta size */
                        SET_DELTA(entry, base_entry);
                        entry->delta_size = entry->size;
                        entry->delta_sibling_idx = base_entry->delta_child_idx;
@@ -1509,13 +1512,15 @@ static void check_object(struct object_entry *entry)
                }
 
                if (oe_type(entry)) {
+                       off_t delta_pos;
+
                        /*
                         * This must be a delta and we already know what the
                         * final object type is.  Let's extract the actual
                         * object size from the delta header.
                         */
-                       entry->size = get_size_from_delta(p, &w_curs,
-                                       entry->in_pack_offset + entry->in_pack_header_size);
+                       delta_pos = entry->in_pack_offset + entry->in_pack_header_size;
+                       entry->size = get_size_from_delta(p, &w_curs, delta_pos);
                        if (entry->size == 0)
                                goto give_up;
                        unuse_pack(&w_curs);
@@ -1742,7 +1747,7 @@ static void get_object_details(void)
        for (i = 0; i < to_pack.nr_objects; i++) {
                struct object_entry *entry = sorted_by_offset[i];
                check_object(entry);
-               if (big_file_threshold < entry->size)
+               if (entry->type_valid && big_file_threshold < entry->size)
                        entry->no_try_delta = 1;
        }
 
@@ -2099,12 +2104,19 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                 * between writes at that moment.
                 */
                if (entry->delta_data && !pack_to_stdout) {
-                       entry->z_delta_size = do_compress(&entry->delta_data,
-                                                         entry->delta_size);
-                       cache_lock();
-                       delta_cache_size -= entry->delta_size;
-                       delta_cache_size += entry->z_delta_size;
-                       cache_unlock();
+                       unsigned long size;
+
+                       size = do_compress(&entry->delta_data, entry->delta_size);
+                       if (size < (1U << OE_Z_DELTA_BITS)) {
+                               entry->z_delta_size = size;
+                               cache_lock();
+                               delta_cache_size -= entry->delta_size;
+                               delta_cache_size += entry->z_delta_size;
+                               cache_unlock();
+                       } else {
+                               FREE_AND_NULL(entry->delta_data);
+                               entry->z_delta_size = 0;
+                       }
                }
 
                /* if we made n a delta, and if n is already at max
@@ -2446,7 +2458,7 @@ static void prepare_pack(int window, int depth)
                         */
                        continue;
 
-               if (entry->size < 50)
+               if (!entry->type_valid || entry->size < 50)
                        continue;
 
                if (entry->no_try_delta)
@@ -3087,6 +3099,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                        depth, (1 << OE_DEPTH_BITS) - 1);
                depth = (1 << OE_DEPTH_BITS) - 1;
        }
+       if (cache_max_small_delta_size >= (1U << OE_Z_DELTA_BITS)) {
+               warning(_("pack.deltaCacheLimit is too high, forcing %d"),
+                       (1U << OE_Z_DELTA_BITS) - 1);
+               cache_max_small_delta_size = (1U << OE_Z_DELTA_BITS) - 1;
+       }
 
        argv_array_push(&rp, "pack-objects");
        if (thin) {