git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Tweak diffcore-rename heuristics.

From
Junio C Hamano <junkio@cox.net>
Date
May 21, 2005, 22:55 UTC
Message-ID
<7v7jhsfauh.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<7vfywgkj90.fsf_-_@assigned-by-dhcp.cox.net>

The heuristics so far was to compare file size change and xdelta size against the average of file size before and after the change. This patch uses the smaller of pre- and post- change file size instead.

It also makes a very small performance fix. I didn't measure it; I do not expect it to make any practical difference, but while scanning an already sorted list, breaking out in the middle is the right thing.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

diffcore-rename.c | 38 ++++++++++++++++++++------------------ 1 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -68,37 +68,39 @@ static int estimate_similarity(struct di
 	 * else.
 	 */
 	void *delta;
-	unsigned long delta_size;
+	unsigned long delta_size, base_size;
 	int score;
 
 	delta_size = ((src->size < dst->size) ?
 		      (dst->size - src->size) : (src->size - dst->size));
+	base_size = ((src->size < dst->size) ? src->size : dst->size);
 
-	/* We would not consider rename followed by more than
-	 * minimum_score/MAX_SCORE edits; that is, delta_size must be smaller
-	 * than (src->size + dst->size)/2 * minimum_score/MAX_SCORE,
-	 * which means...
+	/* We would not consider edits that change the file size so
+	 * drastically.  delta_size must be smaller than
+	 * minimum_score/MAX_SCORE * min(src->size, dst->size).
+	 * Note that base_size == 0 case is handled here already
+	 * and the final score computation below would not have a
+	 * divide-by-zero issue.
 	 */
-
-	if ((src->size+dst->size)*minimum_score < delta_size*MAX_SCORE*2)
+	if (base_size * minimum_score < delta_size * MAX_SCORE)
 		return 0;
 
 	delta = diff_delta(src->data, src->size,
 			   dst->data, dst->size,
 			   &delta_size);
+	/*
+	 * We currently punt here, but we may later end up parsing the
+	 * delta to really assess the extent of damage.  A big consecutive
+	 * remove would produce small delta_size that affects quite a
+	 * big portion of the file.
+	 */
 	free(delta);
 
-	/* This "delta" is really xdiff with adler32 and all the
-	 * overheads but it is a quick and dirty approximation.
-	 *
-	 * Now we will give some score to it.  100% edit gets
-	 * 0 points and 0% edit gets MAX_SCORE points.  That is, every
-	 * 1/MAX_SCORE edit gets 1 point penalty.  The amount of penalty is:
-	 *
-	 * (delta_size * 2 / (src->size + dst->size)) * MAX_SCORE
-	 *
+	/*
+	 * Now we will give some score to it.  100% edit gets 0 points
+	 * and 0% edit gets MAX_SCORE points.
 	 */
-	score = MAX_SCORE-(MAX_SCORE*2*delta_size/(src->size+dst->size));
+	score = MAX_SCORE - (MAX_SCORE * delta_size / base_size); 
 	if (score < 0) return 0;
 	if (MAX_SCORE < score) return MAX_SCORE;
 	return score;
@@ -314,7 +316,7 @@ void diff_detect_rename(struct diff_queu
 		if (mx[i].dst->xfrm_flags & RENAME_DST_MATCHED)
 			continue; /* alreayd done, either exact or fuzzy. */
 		if (mx[i].score < minimum_score)
-			continue;
+			break; /* there is not any more diffs applicable. */
 		record_rename_pair(&outq,
 				  mx[i].src, mx[i].dst, mx[i].rank,
 				  mx[i].score);
------------------------------------------------
Previous: Junio C HamanoNext: Junio C Hamano
Message 42 of 43 in “Detect renames in diff family.”
  1. Detect renames in diff family.Junio C Hamano, May 19, 2005
  2. Linus TorvaldsMay 19, 2005
  3. Junio C HamanoMay 19, 2005
  4. Linus TorvaldsMay 19, 2005
  5. Nicolas PitreMay 19, 2005
  6. Junio C HamanoMay 19, 2005
  7. Nicolas PitreMay 19, 2005
  8. Junio C HamanoMay 19, 2005
  9. Nicolas PitreMay 19, 2005
  10. Junio C HamanoMay 19, 2005
  11. Linus TorvaldsMay 19, 2005
  12. Junio C HamanoMay 19, 2005
  13. Linus TorvaldsMay 20, 2005
  14. Junio C HamanoMay 20, 2005
  15. Junio C HamanoMay 19, 2005
  16. Junio C HamanoMay 19, 2005
  17. Linus TorvaldsMay 19, 2005
  18. Junio C HamanoMay 19, 2005
  19. H. Peter AnvinMay 19, 2005
  20. Joel BeckerMay 19, 2005
  21. Junio C HamanoMay 21, 2005
  22. 1/3 Diff overhaul, adding half of copy detection.Junio C Hamano, May 21, 2005
  23. 2/3 Introducing software archaeologist's tool "pickaxe".Junio C Hamano, May 21, 2005
  24. Constness fix for pickaxe option.Junio C Hamano, May 21, 2005
  25. Linus TorvaldsMay 21, 2005
  26. 3/3 Diff overhaul, adding the other half of copy detection.Junio C Hamano, May 21, 2005
  27. Teach diff-tree to report unmodified paths for -C option.Junio C Hamano, May 21, 2005
  28. Junio C HamanoMay 21, 2005
  29. Linus TorvaldsMay 21, 2005
  30. Junio C HamanoMay 21, 2005
  31. Linus TorvaldsMay 21, 2005
  32. Linus TorvaldsMay 21, 2005
  33. Linus TorvaldsMay 21, 2005
  34. Junio C HamanoMay 21, 2005
  35. Junio C HamanoMay 24, 2005
  36. Linus TorvaldsMay 24, 2005
  37. Junio C HamanoMay 24, 2005
  38. Linus TorvaldsMay 24, 2005
  39. Junio C HamanoMay 24, 2005
  40. Detect copies harder in diff-tree.Junio C Hamano, May 26, 2005
  41. Junio C HamanoMay 21, 2005
  42. Tweak diffcore-rename heuristics.Junio C Hamano, May 21, 2005
  43. Now I think I am done with diff...Junio C Hamano, May 23, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.