diffcore-rename: add a mapping of destination names to their indices

Compute a mapping of full filename to the index within rename_dst where that filename is found, and store it in idx_map. idx_possible_rename() needs this to quickly finding an array entry in rename_dst given the pathname. While at it, add placeholder initializations for dir_rename_count and dir_rename_guess; these will be more fully populated in subsequent commits. Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Feb 27, 2021 at 00:30 UTC ae8cf74d3f9e76332138ee8bb911b3fa53f17bbf
1 file changed +45
diffcore-rename.c
+45
@@ -380,6 +380,45 @@ static char *get_dirname(const char *filename)
380 return slash ? xstrndup(filename, slash - filename) : xstrdup("");
381 }
382
383 +static void initialize_dir_rename_info(struct dir_rename_info *info)
384 +{
385 + int i;
386 +
387 + info->setup = 1;
388 +
389 + strintmap_init_with_options(&info->idx_map, -1, NULL, 0);
390 + strmap_init_with_options(&info->dir_rename_guess, NULL, 0);
391 + info->dir_rename_count = NULL;
392 +
393 + /*
394 + * Loop setting up both info->idx_map.
395 + */
396 + for (i = 0; i < rename_dst_nr; ++i) {
397 + /*
398 + * For non-renamed files, make idx_map contain mapping of
399 + * filename -> index (index within rename_dst, that is)
400 + */
401 + if (!rename_dst[i].is_rename) {
402 + char *filename = rename_dst[i].p->two->path;
403 + strintmap_set(&info->idx_map, filename, i);
404 + }
405 + }
406 +}
407 +
408 +static void cleanup_dir_rename_info(struct dir_rename_info *info)
409 +{
410 + if (!info->setup)
411 + return;
412 +
413 + /* idx_map */
414 + strintmap_clear(&info->idx_map);
415 +
416 + /* dir_rename_guess */
417 + strmap_clear(&info->dir_rename_guess, 1);
418 +
419 + /* Nothing to do for dir_rename_count, yet */
420 +}
421 +
422 static const char *get_basename(const char *filename)
423 {
424 /*
@@ -858,6 +897,11 @@ void diffcore_rename(struct diff_options *options)
897 remove_unneeded_paths_from_src(want_copies);
898 trace2_region_leave("diff", "cull after exact", options->repo);
899
900 + /* Preparation for basename-driven matching. */
901 + trace2_region_enter("diff", "dir rename setup", options->repo);
902 + initialize_dir_rename_info(&info);
903 + trace2_region_leave("diff", "dir rename setup", options->repo);
904 +
905 /* Utilize file basenames to quickly find renames. */
906 trace2_region_enter("diff", "basename matches", options->repo);
907 rename_count += find_basename_matches(options,
@@ -1026,6 +1070,7 @@ void diffcore_rename(struct diff_options *options)
1070 if (rename_dst[i].filespec_to_free)
1071 free_filespec(rename_dst[i].filespec_to_free);
1072
1073 + cleanup_dir_rename_info(&info);
1074 FREE_AND_NULL(rename_dst);
1075 rename_dst_nr = rename_dst_alloc = 0;
1076 FREE_AND_NULL(rename_src);