|
8 | 8 | #include "sha1-lookup.h"
|
9 | 9 | #include "midx.h"
|
10 | 10 | #include "progress.h"
|
| 11 | +#include "run-command.h" |
11 | 12 |
|
12 | 13 | #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */
|
13 | 14 | #define MIDX_VERSION 1
|
@@ -1111,7 +1112,113 @@ int expire_midx_packs(const char *object_dir)
|
1111 | 1112 | return result;
|
1112 | 1113 | }
|
1113 | 1114 |
|
1114 |
| -int midx_repack(const char *object_dir, size_t batch_size) |
| 1115 | +struct time_and_id { |
| 1116 | + timestamp_t mtime; |
| 1117 | + uint32_t pack_int_id; |
| 1118 | +}; |
| 1119 | + |
| 1120 | +static int compare_by_mtime(const void *a_, const void *b_) |
1115 | 1121 | {
|
| 1122 | + const struct time_and_id *a, *b; |
| 1123 | + |
| 1124 | + a = (const struct time_and_id *)a_; |
| 1125 | + b = (const struct time_and_id *)b_; |
| 1126 | + |
| 1127 | + if (a->mtime < b->mtime) |
| 1128 | + return -1; |
| 1129 | + if (a->mtime > b->mtime) |
| 1130 | + return 1; |
1116 | 1131 | return 0;
|
1117 | 1132 | }
|
| 1133 | + |
| 1134 | +int midx_repack(const char *object_dir, size_t batch_size) |
| 1135 | +{ |
| 1136 | + int result = 0; |
| 1137 | + uint32_t i, packs_to_repack; |
| 1138 | + size_t total_size; |
| 1139 | + struct time_and_id *pack_ti; |
| 1140 | + unsigned char *include_pack; |
| 1141 | + struct child_process cmd = CHILD_PROCESS_INIT; |
| 1142 | + struct strbuf base_name = STRBUF_INIT; |
| 1143 | + struct multi_pack_index *m = load_multi_pack_index(object_dir, 1); |
| 1144 | + |
| 1145 | + if (!m) |
| 1146 | + return 0; |
| 1147 | + |
| 1148 | + include_pack = xcalloc(m->num_packs, sizeof(unsigned char)); |
| 1149 | + pack_ti = xcalloc(m->num_packs, sizeof(struct time_and_id)); |
| 1150 | + |
| 1151 | + for (i = 0; i < m->num_packs; i++) { |
| 1152 | + pack_ti[i].pack_int_id = i; |
| 1153 | + |
| 1154 | + if (prepare_midx_pack(m, i)) |
| 1155 | + continue; |
| 1156 | + |
| 1157 | + pack_ti[i].mtime = m->packs[i]->mtime; |
| 1158 | + } |
| 1159 | + QSORT(pack_ti, m->num_packs, compare_by_mtime); |
| 1160 | + |
| 1161 | + total_size = 0; |
| 1162 | + packs_to_repack = 0; |
| 1163 | + for (i = 0; total_size < batch_size && i < m->num_packs; i++) { |
| 1164 | + int pack_int_id = pack_ti[i].pack_int_id; |
| 1165 | + struct packed_git *p = m->packs[pack_int_id]; |
| 1166 | + |
| 1167 | + if (!p) |
| 1168 | + continue; |
| 1169 | + if (p->pack_size >= batch_size) |
| 1170 | + continue; |
| 1171 | + |
| 1172 | + packs_to_repack++; |
| 1173 | + total_size += p->pack_size; |
| 1174 | + include_pack[pack_int_id] = 1; |
| 1175 | + } |
| 1176 | + |
| 1177 | + if (total_size < batch_size || packs_to_repack < 2) |
| 1178 | + goto cleanup; |
| 1179 | + |
| 1180 | + argv_array_push(&cmd.args, "pack-objects"); |
| 1181 | + |
| 1182 | + strbuf_addstr(&base_name, object_dir); |
| 1183 | + strbuf_addstr(&base_name, "/pack/pack"); |
| 1184 | + argv_array_push(&cmd.args, base_name.buf); |
| 1185 | + strbuf_release(&base_name); |
| 1186 | + |
| 1187 | + cmd.git_cmd = 1; |
| 1188 | + cmd.in = cmd.out = -1; |
| 1189 | + |
| 1190 | + if (start_command(&cmd)) { |
| 1191 | + error(_("could not start pack-objects")); |
| 1192 | + result = 1; |
| 1193 | + goto cleanup; |
| 1194 | + } |
| 1195 | + |
| 1196 | + for (i = 0; i < m->num_objects; i++) { |
| 1197 | + struct object_id oid; |
| 1198 | + uint32_t pack_int_id = nth_midxed_pack_int_id(m, i); |
| 1199 | + |
| 1200 | + if (!include_pack[pack_int_id]) |
| 1201 | + continue; |
| 1202 | + |
| 1203 | + nth_midxed_object_oid(&oid, m, i); |
| 1204 | + xwrite(cmd.in, oid_to_hex(&oid), the_hash_algo->hexsz); |
| 1205 | + xwrite(cmd.in, "\n", 1); |
| 1206 | + } |
| 1207 | + close(cmd.in); |
| 1208 | + |
| 1209 | + if (finish_command(&cmd)) { |
| 1210 | + error(_("could not finish pack-objects")); |
| 1211 | + result = 1; |
| 1212 | + goto cleanup; |
| 1213 | + } |
| 1214 | + |
| 1215 | + result = write_midx_internal(object_dir, m, NULL); |
| 1216 | + m = NULL; |
| 1217 | + |
| 1218 | +cleanup: |
| 1219 | + if (m) |
| 1220 | + close_midx(m); |
| 1221 | + free(include_pack); |
| 1222 | + free(pack_ti); |
| 1223 | + return result; |
| 1224 | +} |
0 commit comments