| 2787 | } |
| 2788 | |
| 2789 | static int try_delta(struct unpacked *trg, struct unpacked *src, |
| 2790 | unsigned max_depth, unsigned long *mem_usage) |
| 2791 | { |
| 2792 | struct object_entry *trg_entry = trg->entry; |
| 2793 | struct object_entry *src_entry = src->entry; |
| 2794 | unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; |
| 2795 | unsigned ref_depth; |
| 2796 | enum object_type type; |
| 2797 | void *delta_buf; |
| 2798 | |
| 2799 | /* Don't bother doing diffs between different types */ |
| 2800 | if (oe_type(trg_entry) != oe_type(src_entry)) |
| 2801 | return -1; |
| 2802 | |
| 2803 | /* |
| 2804 | * We do not bother to try a delta that we discarded on an |
| 2805 | * earlier try, but only when reusing delta data. Note that |
| 2806 | * src_entry that is marked as the preferred_base should always |
| 2807 | * be considered, as even if we produce a suboptimal delta against |
| 2808 | * it, we will still save the transfer cost, as we already know |
| 2809 | * the other side has it and we won't send src_entry at all. |
| 2810 | */ |
| 2811 | if (reuse_delta && IN_PACK(trg_entry) && |
| 2812 | IN_PACK(trg_entry) == IN_PACK(src_entry) && |
| 2813 | !src_entry->preferred_base && |
| 2814 | trg_entry->in_pack_type != OBJ_REF_DELTA && |
| 2815 | trg_entry->in_pack_type != OBJ_OFS_DELTA) |
| 2816 | return 0; |
| 2817 | |
| 2818 | /* Let's not bust the allowed depth. */ |
| 2819 | if (src->depth >= max_depth) |
| 2820 | return 0; |
| 2821 | |
| 2822 | /* Now some size filtering heuristics. */ |
| 2823 | trg_size = SIZE(trg_entry); |
| 2824 | if (!DELTA(trg_entry)) { |
| 2825 | max_size = trg_size/2 - the_hash_algo->rawsz; |
| 2826 | ref_depth = 1; |
| 2827 | } else { |
| 2828 | max_size = DELTA_SIZE(trg_entry); |
| 2829 | ref_depth = trg->depth; |
| 2830 | } |
| 2831 | max_size = (uint64_t)max_size * (max_depth - src->depth) / |
| 2832 | (max_depth - ref_depth + 1); |
| 2833 | if (max_size == 0) |
| 2834 | return 0; |
| 2835 | src_size = SIZE(src_entry); |
| 2836 | sizediff = src_size < trg_size ? trg_size - src_size : 0; |
| 2837 | if (sizediff >= max_size) |
| 2838 | return 0; |
| 2839 | if (trg_size < src_size / 32) |
| 2840 | return 0; |
| 2841 | |
| 2842 | if (!in_same_island(&trg->entry->idx.oid, &src->entry->idx.oid)) |
| 2843 | return 0; |
| 2844 | |
| 2845 | /* Load data if not already done */ |
| 2846 | if (!trg->data) { |
no test coverage detected