commit - b47897f387d8f7e9152f0b0e1b1d5548c7bab6f2
commit + a45330b1527e02e1627af02b55831f4cdf8794b4
blob - eb67565c358300506376e716dea9b9c42a2ed8a1
blob + 7a7f5de552270024ae0e6d69c930aa56b5e0a24e
--- lib/diff_myers.c
+++ lib/diff_myers.c
* For d == 0, kd_forward[0] is initialized, i.e. the first invocation should be for d == 0.
* meeting_snake: resulting meeting point, if any.
*/
-static void diff_divide_myers_forward(struct diff_data *left, struct diff_data *right,
+static bool diff_divide_myers_forward(struct diff_data *left, struct diff_data *right,
int *kd_forward, int *kd_backward, int d,
struct diff_box *meeting_snake)
{
meeting_snake->left_end,
meeting_snake->right_end);
debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d-1);
- return;
+ return true;
}
}
}
debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d-1);
+ return false;
}
/* Do one backwards step in the "divide and conquer" graph traversal.
* The first invocation will be for d == 1.
* meeting_snake: resulting meeting point, if any.
*/
-static void diff_divide_myers_backward(struct diff_data *left, struct diff_data *right,
+static bool diff_divide_myers_backward(struct diff_data *left, struct diff_data *right,
int *kd_forward, int *kd_backward, int d,
struct diff_box *meeting_snake)
{
meeting_snake->left_end,
meeting_snake->right_end);
debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d);
- return;
+ return true;
}
}
}
}
debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d);
+ return false;
}
/* Myers "Divide et Impera": tracing forwards from the start and backwards from the end to find a midpoint that divides
int d;
struct diff_box mid_snake = {};
+ bool found_midpoint = false;
for (d = 0; d <= (max/2); d++) {
debug("-- d=%d\n", d);
- diff_divide_myers_forward(left, right, kd_forward, kd_backward, d, &mid_snake);
- if (!diff_box_empty(&mid_snake))
+ found_midpoint = diff_divide_myers_forward(left, right, kd_forward, kd_backward, d, &mid_snake);
+ if (found_midpoint)
break;
- diff_divide_myers_backward(left, right, kd_forward, kd_backward, d, &mid_snake);
- if (!diff_box_empty(&mid_snake))
+ found_midpoint = diff_divide_myers_backward(left, right, kd_forward, kd_backward, d, &mid_snake);
+ if (found_midpoint)
break;
}
- if (diff_box_empty(&mid_snake)) {
+ if (!found_midpoint) {
/* Divide and conquer failed to find a meeting point. Use the fallback_algo defined in the algo_config
* (leave this to the caller). This is just paranoia/sanity, we normally should always find a midpoint.
*/
}
/* else: left_section_len == 0 and right_section_len == 0, i.e. nothing before the mid-snake. */
- /* the mid-snake, identical data on both sides: */
- debug("the mid-snake\n");
- if (!diff_state_add_chunk(state, true,
- &left->atoms.head[mid_snake.left_start],
- mid_snake.left_end - mid_snake.left_start,
- &right->atoms.head[mid_snake.right_start],
- mid_snake.right_end - mid_snake.right_start))
- goto return_rc;
+ if (!diff_box_empty(&mid_snake)) {
+ /* The midpoint is a "snake", i.e. on a section of identical data on both sides: that
+ * section immediately becomes a solved diff chunk. */
+ debug("the mid-snake\n");
+ if (!diff_state_add_chunk(state, true,
+ &left->atoms.head[mid_snake.left_start],
+ mid_snake.left_end - mid_snake.left_start,
+ &right->atoms.head[mid_snake.right_start],
+ mid_snake.right_end - mid_snake.right_start))
+ goto return_rc;
+ }
/* Section after the mid-snake. */
debug("Section after the mid-snake\n");