commit - 0ea9501aa02aa4bbaed4bd7e2818bf946b01cfa6
commit + 223979a920a4be072343306ca1c3a34efb036f31
blob - ec47f65416456d6fa54228e53e8ccea1fd888fba
blob + d3a560ca65443972ce10f241d3345d036bf04e7f
--- lib/debug.h
+++ lib/debug.h
dump_atoms(d, d->atoms.head, d->atoms.len);
}
+/* kd is a quadratic space myers matrix from the original Myers algorithm.
+ * kd_forward and kd_backward are linear slices of a myers matrix from the Myers Divide algorithm.
+ */
static inline void dump_myers_graph(const struct diff_data *l, const struct diff_data *r,
- int *kd)
+ int *kd, int *kd_forward, int kd_forward_d, int *kd_backward, int kd_backward_d)
{
+ #define COLOR_YELLOW "\033[1;33m"
+ #define COLOR_GREEN "\033[1;32m"
+ #define COLOR_BLUE "\033[1;34m"
+ #define COLOR_RED "\033[1;31m"
+ #define COLOR_END "\033[0;m"
int x;
int y;
- print(" ");
+ print(" ");
for (x = 0; x <= l->atoms.len; x++)
- print("%2d", x);
+ print("%2d", x % 100);
print("\n");
for (y = 0; y <= r->atoms.len; y++) {
- print("%2d ", y);
+ print("%3d ", y);
for (x = 0; x <= l->atoms.len; x++) {
/* print d advancements from kd, if any. */
- int d = -1;
+ char label = 'o';
+ char *color = NULL;
if (kd) {
int max = l->atoms.len + r->atoms.len;
size_t kd_len = max + 1 + max;
for (di = 0; di < max; di++) {
int ki;
for (ki = di; ki >= -di; ki -= 2) {
- if (x == kd_pos[ki]
- && y == xk_to_y(x, ki)) {
- d = di;
- break;
- }
+ if (x != kd_pos[ki]
+ || y != xk_to_y(x, ki))
+ continue;
+ label = '0' + (di % 10);
+ color = COLOR_YELLOW;
+ break;
}
- if (d >= 0)
+ if (label != 'o')
break;
kd_pos += kd_len;
}
}
- if (d >= 0)
- print("%d", d);
- else
- print("o");
- if (x < l->atoms.len && d < 10)
+ if (kd_forward && kd_forward_d >= 0) {
+ int max = l->atoms.len + r->atoms.len;
+ size_t kd_len = max + 1 + max;
+ int di;
+#define xc_to_y(X, C, DELTA) ((X) - (C) + (DELTA))
+ int delta = (int)r->atoms.len - (int)l->atoms.len;
+ int ki;
+ for (ki = kd_forward_d; ki >= -kd_forward_d; ki -= 2) {
+ if (x != kd_forward[ki])
+ continue;
+ if (y != xk_to_y(x, ki))
+ continue;
+ label = 'F';
+ color = COLOR_GREEN;
+ break;
+ }
+ }
+ if (kd_backward && kd_backward_d >= 0) {
+ int max = l->atoms.len + r->atoms.len;
+ size_t kd_len = max + 1 + max;
+ int di;
+ int delta = (int)r->atoms.len - (int)l->atoms.len;
+ int ki;
+ for (ki = kd_backward_d; ki >= -kd_backward_d; ki -= 2) {
+ if (x != kd_backward[ki])
+ continue;
+ if (y != xc_to_y(x, ki, delta))
+ continue;
+ if (label == 'o') {
+ label = 'B';
+ color = COLOR_BLUE;
+ } else {
+ label = 'X';
+ color = COLOR_RED;
+ }
+ break;
+ }
+ }
+ if (color)
+ print("%s", color);
+ print("%c", label);
+ if (color)
+ print("%s", COLOR_END);
+ if (x < l->atoms.len)
print("-");
}
print("\n");
if (y == r->atoms.len)
break;
- print(" ");
+ print(" ");
for (x = 0; x < l->atoms.len; x++) {
if (diff_atom_same(&l->atoms.head[x], &r->atoms.head[y]))
print("|\\");
}
static inline void debug_dump_myers_graph(const struct diff_data *l, const struct diff_data *r,
- int *kd)
+ int *kd, int *kd_forward, int kd_forward_d, int *kd_backward, int kd_backward_d)
{
if (l->atoms.len > 99 || r->atoms.len > 99)
return;
- dump_myers_graph(l, r, kd);
+ dump_myers_graph(l, r, kd, kd_forward, kd_forward_d, kd_backward, kd_backward_d);
}
#else
blob - 285bd40d5941fe84c5d9a9bd437a4a9f981ead13
blob + 46c7fc63654f51755c1bde729244e679a0fa7c6c
--- lib/diff_main.c
+++ lib/diff_main.c
debug_dump(&state->left);
debug("right:\n");
debug_dump(&state->right);
- debug_dump_myers_graph(&state->left, &state->right, NULL);
+ debug_dump_myers_graph(&state->left, &state->right, NULL, NULL, 0, NULL, 0);
/* Add a chunk of equal lines, if any */
unsigned int equal_atoms = 0;
blob - a77e578fed2a1e759424a3853d595bb888a4ecc8
blob + 111366765d59948fc0ea91555be00ef59b425b15
--- lib/diff_myers.c
+++ lib/diff_myers.c
int x;
debug("-- %s d=%d\n", __func__, d);
- debug_dump_myers_graph(left, right, NULL);
for (k = d; k >= -d; k -= 2) {
if (k < -(int)right->atoms.len || k > (int)left->atoms.len) {
*/
int backward_x = kd_backward[c];
int backward_y = xc_to_y(backward_x, c, delta);
- debug(" prev_x,y = (%d,%d) c%d:backward_x,y = (%d,%d) k%d:x,y = (%d,%d)\n",
- prev_x, prev_y, c, backward_x, backward_y, k, x, xk_to_y(x, k));
+ debug("Compare: k=%d c=%d is (%d,%d) >= (%d,%d)?\n",
+ k, c, x, xk_to_y(x, k), backward_x, xc_to_y(backward_x, c, delta));
if (prev_x <= backward_x && prev_y <= backward_y
&& x >= backward_x) {
*meeting_snake = (struct diff_box){
meeting_snake->right_start,
meeting_snake->left_end,
meeting_snake->right_end);
+ debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d-1);
return;
}
}
}
+
+ debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d-1);
}
/* Do one backwards step in the "divide and conquer" graph traversal.
int x;
debug("-- %s d=%d\n", __func__, d);
- debug_dump_myers_graph(left, right, NULL);
for (c = d; c >= -d; c -= 2) {
if (c < -(int)left->atoms.len || c > (int)right->atoms.len) {
debug(" l="); debug_dump_atom(left, right, &left->atoms.head[x-1]);
}
if (xc_to_y(x, c, delta) > 0) {
- debug(" r="); debug_dump_atom(right, left, &right->atoms.head[xc_to_y(x, c, delta)-1]);
+ debug(" r="); debug_dump_atom(right, left, &right->atoms.head[xc_to_y(x, c, delta)-1]);
}
while (x > 0 && xc_to_y(x, c, delta) > 0
&& diff_atom_same(&left->atoms.head[x-1], &right->atoms.head[xc_to_y(x, c, delta)-1]))
- x--;
+ x--;
kd_backward[c] = x;
if (DEBUG) {
* mid-box. */
int forward_x = kd_forward[k];
int forward_y = xk_to_y(forward_x, k);
- debug("Compare %d to %d k=%d (x=%d,y=%d) to (x=%d,y=%d)\n",
- forward_x, x, k,
- forward_x, xk_to_y(forward_x, k), x, xc_to_y(x, c, delta));
+ debug("Compare: k=%d c=%d is (%d,%d) >= (%d,%d)?\n",
+ k, c, forward_x, xk_to_y(forward_x, k), x, xc_to_y(x, c, delta));
if (forward_x <= prev_x && forward_y <= prev_y
&& forward_x >= x) {
*meeting_snake = (struct diff_box){
meeting_snake->right_start,
meeting_snake->left_end,
meeting_snake->right_end);
+ debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d);
return;
}
}
}
}
+ debug_dump_myers_graph(left, right, NULL, kd_forward, d, kd_backward, d);
}
/* Myers "Divide et Impera": tracing forwards from the start and backwards from the end to find a midpoint that divides
debug_dump(left);
debug("right:\n");
debug_dump(right);
- debug_dump_myers_graph(left, right, NULL);
+ debug_dump_myers_graph(left, right, NULL, NULL, 0, NULL, 0);
/* Allocate two columns of a Myers graph, one for the forward and one for the backward traversal. */
unsigned int max = left->atoms.len + right->atoms.len;
debug_dump(left);
debug("right:\n");
debug_dump(right);
- debug_dump_myers_graph(left, right, NULL);
+ debug_dump_myers_graph(left, right, NULL, NULL, 0, NULL, 0);
/* Allocate two columns of a Myers graph, one for the forward and one for the backward traversal. */
unsigned int max = left->atoms.len + right->atoms.len;
size_t kd_len = max + 1 + max;
size_t kd_buf_size = kd_len * kd_len;
+ size_t kd_state_size = kd_buf_size * sizeof(int);
debug("state size: %zu\n", kd_buf_size);
if (kd_buf_size < kd_len /* overflow? */
- || kd_buf_size * sizeof(int) > algo_config->permitted_state_size) {
+ || kd_state_size > algo_config->permitted_state_size) {
debug("state size %zu > permitted_state_size %zu, use fallback_algo\n",
- kd_buf_size, algo_config->permitted_state_size);
+ kd_state_size, algo_config->permitted_state_size);
return DIFF_RC_USE_DIFF_ALGO_FALLBACK;
}
break;
}
- debug_dump_myers_graph(left, right, kd_origin);
+ debug_dump_myers_graph(left, right, kd_origin, NULL, 0, NULL, 0);
/* backtrack. A matrix spanning from start to end of the file is ready:
*