Merge branch 'en/ort-perf-batch-13'

Performance tweaks of "git merge -sort" around lazy fetching of objects.

* en/ort-perf-batch-13:
  merge-ort: add prefetching for content merges
  diffcore-rename: use a different prefetch for basename comparisons
  diffcore-rename: allow different missing_object_cb functions
  t6421: add tests checking for excessive object downloads during merge
  promisor-remote: output trace2 statistics for number of objects fetched
This commit is contained in:
Junio C Hamano
2021-07-16 17:42:45 -07:00
4 changed files with 612 additions and 34 deletions

View File

@ -29,6 +29,7 @@
#include "entry.h"
#include "ll-merge.h"
#include "object-store.h"
#include "promisor-remote.h"
#include "revision.h"
#include "strmap.h"
#include "submodule.h"
@ -3494,6 +3495,54 @@ static void process_entry(struct merge_options *opt,
record_entry_for_tree(dir_metadata, path, &ci->merged);
}
static void prefetch_for_content_merges(struct merge_options *opt,
struct string_list *plist)
{
struct string_list_item *e;
struct oid_array to_fetch = OID_ARRAY_INIT;
if (opt->repo != the_repository || !has_promisor_remote())
return;
for (e = &plist->items[plist->nr-1]; e >= plist->items; --e) {
/* char *path = e->string; */
struct conflict_info *ci = e->util;
int i;
/* Ignore clean entries */
if (ci->merged.clean)
continue;
/* Ignore entries that don't need a content merge */
if (ci->match_mask || ci->filemask < 6 ||
!S_ISREG(ci->stages[1].mode) ||
!S_ISREG(ci->stages[2].mode) ||
oideq(&ci->stages[1].oid, &ci->stages[2].oid))
continue;
/* Also don't need content merge if base matches either side */
if (ci->filemask == 7 &&
S_ISREG(ci->stages[0].mode) &&
(oideq(&ci->stages[0].oid, &ci->stages[1].oid) ||
oideq(&ci->stages[0].oid, &ci->stages[2].oid)))
continue;
for (i = 0; i < 3; i++) {
unsigned side_mask = (1 << i);
struct version_info *vi = &ci->stages[i];
if ((ci->filemask & side_mask) &&
S_ISREG(vi->mode) &&
oid_object_info_extended(opt->repo, &vi->oid, NULL,
OBJECT_INFO_FOR_PREFETCH))
oid_array_append(&to_fetch, &vi->oid);
}
}
promisor_remote_get_direct(opt->repo, to_fetch.oid, to_fetch.nr);
oid_array_clear(&to_fetch);
}
static void process_entries(struct merge_options *opt,
struct object_id *result_oid)
{
@ -3540,6 +3589,7 @@ static void process_entries(struct merge_options *opt,
* the way when it is time to process the file at the same path).
*/
trace2_region_enter("merge", "processing", opt->repo);
prefetch_for_content_merges(opt, &plist);
for (entry = &plist.items[plist.nr-1]; entry >= plist.items; --entry) {
char *path = entry->string;
/*