| 110 | } |
| 111 | |
| 112 | static uint32_t compute_pack_geometry_split(struct packed_git **pack, size_t pack_nr, |
| 113 | int split_factor) |
| 114 | { |
| 115 | uint32_t i; |
| 116 | uint32_t split; |
| 117 | off_t total_size = 0; |
| 118 | |
| 119 | if (!pack_nr) |
| 120 | return 0; |
| 121 | |
| 122 | /* |
| 123 | * First, count the number of packs (in descending order of size) which |
| 124 | * already form a geometric progression. |
| 125 | */ |
| 126 | for (i = pack_nr - 1; i > 0; i--) { |
| 127 | struct packed_git *ours = pack[i]; |
| 128 | struct packed_git *prev = pack[i - 1]; |
| 129 | |
| 130 | if (unsigned_mult_overflows(split_factor, |
| 131 | pack_geometry_weight(prev))) |
| 132 | die(_("pack %s too large to consider in geometric " |
| 133 | "progression"), |
| 134 | prev->pack_name); |
| 135 | |
| 136 | if (pack_geometry_weight(ours) < |
| 137 | split_factor * pack_geometry_weight(prev)) |
| 138 | break; |
| 139 | } |
| 140 | |
| 141 | split = i; |
| 142 | |
| 143 | if (split) { |
| 144 | /* |
| 145 | * Move the split one to the right, since the top element in the |
| 146 | * last-compared pair can't be in the progression. Only do this |
| 147 | * when we split in the middle of the array (otherwise if we got |
| 148 | * to the end, then the split is in the right place). |
| 149 | */ |
| 150 | split++; |
| 151 | } |
| 152 | |
| 153 | /* |
| 154 | * Then, anything to the left of 'split' must be in a new pack. But, |
| 155 | * creating that new pack may cause packs in the heavy half to no longer |
| 156 | * form a geometric progression. |
| 157 | * |
| 158 | * Compute an expected size of the new pack, and then determine how many |
| 159 | * packs in the heavy half need to be joined into it (if any) to restore |
| 160 | * the geometric progression. |
| 161 | */ |
| 162 | for (i = 0; i < split; i++) { |
| 163 | struct packed_git *p = pack[i]; |
| 164 | |
| 165 | if (unsigned_add_overflows(total_size, pack_geometry_weight(p))) |
| 166 | die(_("pack %s too large to roll up"), p->pack_name); |
| 167 | total_size += pack_geometry_weight(p); |
| 168 | } |
| 169 | for (i = split; i < pack_nr; i++) { |
no test coverage detected