aboutsummaryrefslogtreecommitdiff
path: root/xdiff/xpatience.c
diff options
context:
space:
mode:
Diffstat (limited to 'xdiff/xpatience.c')
-rw-r--r--xdiff/xpatience.c35
1 files changed, 16 insertions, 19 deletions
diff --git a/xdiff/xpatience.c b/xdiff/xpatience.c
index 669b653580..7953490ed0 100644
--- a/xdiff/xpatience.c
+++ b/xdiff/xpatience.c
@@ -48,7 +48,7 @@
struct hashmap {
int nr, alloc;
struct entry {
- unsigned long hash;
+ size_t minimal_perfect_hash;
/*
* 0 = unused entry, 1 = first line, 2 = second, etc.
* line2 is NON_UNIQUE if the line is not unique
@@ -61,12 +61,6 @@ struct hashmap {
* initially, "next" reflects only the order in file1.
*/
struct entry *next, *previous;
-
- /*
- * If 1, this entry can serve as an anchor. See
- * Documentation/diff-options.adoc for more information.
- */
- unsigned anchor : 1;
} *entries, *first, *last;
/* were common records found? */
unsigned long has_matches;
@@ -85,8 +79,7 @@ static int is_anchor(xpparam_t const *xpp, const char *line)
}
/* The argument "pass" is 1 for the first file, 2 for the second. */
-static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
- int pass)
+static void insert_record(int line, struct hashmap *map, int pass)
{
xrecord_t *records = pass == 1 ?
map->env->xdf1.recs : map->env->xdf2.recs;
@@ -101,10 +94,10 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
* So we multiply ha by 2 in the hope that the hashing was
* "unique enough".
*/
- int index = (int)((record->ha << 1) % map->alloc);
+ int index = (int)((record->minimal_perfect_hash << 1) % map->alloc);
while (map->entries[index].line1) {
- if (map->entries[index].hash != record->ha) {
+ if (map->entries[index].minimal_perfect_hash != record->minimal_perfect_hash) {
if (++index >= map->alloc)
index = 0;
continue;
@@ -120,8 +113,7 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
if (pass == 2)
return;
map->entries[index].line1 = line;
- map->entries[index].hash = record->ha;
- map->entries[index].anchor = is_anchor(xpp, map->env->xdf1.recs[line - 1].ptr);
+ map->entries[index].minimal_perfect_hash = record->minimal_perfect_hash;
if (!map->first)
map->first = map->entries + index;
if (map->last) {
@@ -153,11 +145,11 @@ static int fill_hashmap(xpparam_t const *xpp, xdfenv_t *env,
/* First, fill with entries from the first file */
while (count1--)
- insert_record(xpp, line1++, result, 1);
+ insert_record(line1++, result, 1);
/* Then search for matches in the second file */
while (count2--)
- insert_record(xpp, line2++, result, 2);
+ insert_record(line2++, result, 2);
return 0;
}
@@ -194,6 +186,8 @@ static int binary_search(struct entry **sequence, int longest,
*/
static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
{
+ xpparam_t const *xpp = map->xpp;
+ xrecord_t const *recs = map->env->xdf2.recs;
struct entry **sequence;
int longest = 0, i;
struct entry *entry;
@@ -211,13 +205,16 @@ static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
for (entry = map->first; entry; entry = entry->next) {
if (!entry->line2 || entry->line2 == NON_UNIQUE)
continue;
- i = binary_search(sequence, longest, entry);
+ if (longest == 0 || entry->line2 > sequence[longest - 1]->line2)
+ i = longest - 1;
+ else
+ i = binary_search(sequence, longest, entry);
entry->previous = i < 0 ? NULL : sequence[i];
++i;
if (i <= anchor_i)
continue;
sequence[i] = entry;
- if (entry->anchor) {
+ if (is_anchor(xpp, (const char*)recs[entry->line2 - 1].ptr)) {
anchor_i = i;
longest = anchor_i + 1;
} else if (i == longest) {
@@ -248,7 +245,7 @@ static int match(struct hashmap *map, int line1, int line2)
{
xrecord_t *record1 = &map->env->xdf1.recs[line1 - 1];
xrecord_t *record2 = &map->env->xdf2.recs[line2 - 1];
- return record1->ha == record2->ha;
+ return record1->minimal_perfect_hash == record2->minimal_perfect_hash;
}
static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
@@ -370,5 +367,5 @@ static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env)
{
- return patience_diff(xpp, env, 1, env->xdf1.nrec, 1, env->xdf2.nrec);
+ return patience_diff(xpp, env, 1, (int)env->xdf1.nrec, 1, (int)env->xdf2.nrec);
}