Skip to content

Commit b970b4e

Browse files
newrengitster
authored andcommitted
diffcore-rename: simplify and accelerate register_rename_src()
register_rename_src() took pains to create an array in rename_src which was sorted by pathname of the contained diff_filepair. The sorting was entirely unnecessary since callers pass filepairs to us in sorted order. We can simply append to the end of the rename_src array, speeding up diffcore_rename() setup time. Also, note that I dropped the return type on the function since it was unconditionally discarded anyway. This patch is being submitted in a different order than its original development, but in a large rebase of many commits with lots of renames and with several optimizations to inexact rename detection, diffcore_rename() setup time was a sizeable chunk of overall runtime. This patch dropped execution time of rebasing 35 commits with lots of renames by 2% overall. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ac14de1 commit b970b4e

File tree

1 file changed

+13
-26
lines changed

1 file changed

+13
-26
lines changed

diffcore-rename.c

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -76,36 +76,23 @@ static struct diff_rename_src {
7676
} *rename_src;
7777
static int rename_src_nr, rename_src_alloc;
7878

79-
static struct diff_rename_src *register_rename_src(struct diff_filepair *p)
79+
static void register_rename_src(struct diff_filepair *p)
8080
{
81-
int first, last;
82-
struct diff_filespec *one = p->one;
83-
unsigned short score = p->score;
84-
85-
first = 0;
86-
last = rename_src_nr;
87-
while (last > first) {
88-
int next = first + ((last - first) >> 1);
89-
struct diff_rename_src *src = &(rename_src[next]);
90-
int cmp = strcmp(one->path, src->p->one->path);
91-
if (!cmp)
92-
return src;
93-
if (cmp < 0) {
94-
last = next;
95-
continue;
96-
}
97-
first = next+1;
98-
}
81+
/*
82+
* If we have multiple entries at the same path in the source tree
83+
* (an invalid tree, to be sure), avoid using more more than one
84+
* such entry in rename detection. Once upon a time, doing so
85+
* caused segfaults; see commit 25d5ea410f ("[PATCH] Redo
86+
* rename/copy detection logic.", 2005-05-24).
87+
*/
88+
if (rename_src_nr > 0 &&
89+
!strcmp(rename_src[rename_src_nr-1].p->one->path, p->one->path))
90+
return;
9991

100-
/* insert to make it at "first" */
10192
ALLOC_GROW(rename_src, rename_src_nr + 1, rename_src_alloc);
93+
rename_src[rename_src_nr].p = p;
94+
rename_src[rename_src_nr].score = p->score;
10295
rename_src_nr++;
103-
if (first < rename_src_nr)
104-
MOVE_ARRAY(rename_src + first + 1, rename_src + first,
105-
rename_src_nr - first - 1);
106-
rename_src[first].p = p;
107-
rename_src[first].score = score;
108-
return &(rename_src[first]);
10996
}
11097

11198
static int basename_same(struct diff_filespec *src, struct diff_filespec *dst)

0 commit comments

Comments
 (0)