3237
return 1;
3238
}
3239
3240
+static void find_deltas_for_region(struct object_entry *list,
3241
+ struct packing_region *region,
3242
+ unsigned int *processed)
3243
+{
3244
+ struct object_entry **delta_list;
3245
+ unsigned int delta_list_nr = 0;
3246
+
3247
+ ALLOC_ARRAY(delta_list, region->nr);
3248
+ for (size_t i = 0; i < region->nr; i++) {
3249
+ struct object_entry *entry = list + region->start + i;
3250
+ if (should_attempt_deltas(entry))
3251
+ delta_list[delta_list_nr++] = entry;
3252
+ }
3253
+
3254
+ QSORT(delta_list, delta_list_nr, type_size_sort);
3255
+ find_deltas(delta_list, &delta_list_nr, window, depth, processed);
3256
+ free(delta_list);
3257
+}
3258
+
3259
+static void find_deltas_by_region(struct object_entry *list,
3260
+ struct packing_region *regions,
3261
+ size_t start, size_t nr)
3262
+{
3263
+ unsigned int processed = 0;
3264
+ size_t progress_nr;
3265
+
3266
+ if (!nr)
3267
+ return;
3268
+
3269
+ progress_nr = regions[nr - 1].start + regions[nr - 1].nr;
3270
+
3271
+ if (progress)
3272
+ progress_state = start_progress(the_repository,
3273
+ _("Compressing objects by path"),
3274
+ progress_nr);
3275
+
3276
+ while (nr--)
3277
+ find_deltas_for_region(list,
3278
+ ®ions[start++],
3279
+ &processed);
3280
+
3281
+ display_progress(progress_state, progress_nr);
3282
+ stop_progress(&progress_state);
3283
+}
3284
+
3285
static void prepare_pack(int window, int depth)
3286
{
3287
struct object_entry **delta_list;
3306
if (!to_pack.nr_objects || !window || !depth)
3307
return;
3308
3309
+ if (path_walk)
3310
+ find_deltas_by_region(to_pack.objects, to_pack.regions,
3311
+ 0, to_pack.nr_regions);
3312
+
3313
ALLOC_ARRAY(delta_list, to_pack.nr_objects);
3314
nr_deltas = n = 0;
3315
4263
enum object_type type,
4264
void *data)
4265
{
4217
- struct object_entry **delta_list = NULL;
4266
size_t oe_start = to_pack.nr_objects;
4267
size_t oe_end;
4220
- unsigned int sub_list_nr;
4268
unsigned int *processed = data;
4269
4270
/*
4297
if (oe_end == oe_start || !window)
4298
return 0;
4299
4253
- sub_list_nr = 0;
4254
- if (oe_end > oe_start)
4255
- ALLOC_ARRAY(delta_list, oe_end - oe_start);
4300
+ ALLOC_GROW(to_pack.regions,
4301
+ to_pack.nr_regions + 1,
4302
+ to_pack.nr_regions_alloc);
4303
4257
- for (size_t i = 0; i < oe_end - oe_start; i++) {
4258
- struct object_entry *entry = to_pack.objects + oe_start + i;
4304
+ to_pack.regions[to_pack.nr_regions].start = oe_start;
4305
+ to_pack.regions[to_pack.nr_regions].nr = oe_end - oe_start;
4306
+ to_pack.nr_regions++;
4307
4260
- if (!should_attempt_deltas(entry))
4261
- continue;
4308
+ *processed += oids->nr;
4309
+ display_progress(progress_state, *processed);
4310
4263
- delta_list[sub_list_nr++] = entry;
4264
- }
4265
-
4266
- /*
4267
- * Find delta bases among this list of objects that all match the same
4268
- * path. This causes the delta compression to be interleaved in the
4269
- * object walk, which can lead to confusing progress indicators. This is
4270
- * also incompatible with threaded delta calculations. In the future,
4271
- * consider creating a list of regions in the full to_pack.objects array
4272
- * that could be picked up by the threaded delta computation.
4273
- */
4274
- if (sub_list_nr && window) {
4275
- QSORT(delta_list, sub_list_nr, type_size_sort);
4276
- find_deltas(delta_list, &sub_list_nr, window, depth, processed);
4277
- }
4278
-
4279
- free(delta_list);
4311
return 0;
4312
}
4313