You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by jc...@apache.org on 2011/02/11 22:38:55 UTC
svn commit: r1069961 - in /subversion/trunk/subversion: include/svn_diff.h
libsvn_diff/diff.c libsvn_diff/diff.h libsvn_diff/diff3.c
libsvn_diff/diff4.c libsvn_diff/diff_file.c libsvn_diff/diff_memory.c
libsvn_diff/lcs.c
Author: jcorvel
Date: Fri Feb 11 21:38:55 2011
New Revision: 1069961
URL: http://svn.apache.org/viewvc?rev=1069961&view=rev
Log:
Re-enable elimination of the identical suffix for diff (and diff3 (merge) and
diff4), which was disabled in r1068613 because of truncation of suffix lines
during merge.
This time, count the number of suffix lines so we can create an entirely
correct LCS, also containing the common suffix, so diff3 (merge) can do its
work properly.
* subversion/include/svn_diff.h
(svn_diff_fns2_t): Add a new output parameter SUFFIX_LINES to the
datasources_open prototype. The svn_diff_fns2_t struct is new in 1.7 (was
already revved), so we can still do this.
* subversion/libsvn_diff/diff_file.c
(SUFFIX_LINES_TO_KEEP): Add extensive comment to explain its purpose.
(find_identical_suffix): Count the number of suffix lines, and return it in
the new out-parameter SUFFIX_LINES.
(datasources_open): Add new out-parameter SUFFIX_LINES, passing the number
of suffix lines to callers.
* subversion/libsvn_diff/diff_memory.c
(datasources_open): Add new out-parameter SUFFIX_LINES, and set it to 0
just like the PREFIX_LINES (i.e. dummy implementation of prefix/suffix
scanning).
* subversion/libsvn_diff/diff.h
(svn_diff__lcs): Add parameter SUFFIX_LINES.
* subversion/libsvn_diff/lcs.c
(prepend_prefix_lcs): Rename to ...
(prepend_lcs): ... this, and add parameters POS0_OFFSET and POS1_OFFSET, so
it can be used for prepending both the prefix lcs and the suffix lcs.
(svn_diff__lcs): Take the new parameter SUFFIX_LINES, and use it to add
a chunk of suffix lcs to the lcs chain.
* subversion/libsvn_diff/diff.c
(svn_diff_diff_2): Get the SUFFIX_LINES from the call to datasources_open,
and pass it to svn_diff__lcs.
* subversion/libsvn_diff/diff3.c
(svn_diff__resolve_conflict): Pass 0 for SUFFIX_LINES in the call to
svn_diff__lcs, because it's not used here (just like for PREFIX_LINES).
(svn_diff_diff3_2): Get the SUFFIX_LINES from the call to datasources_open,
and pass it to svn_diff__lcs.
* subversion/libsvn_diff/diff4.c
(svn_diff_diff4_2): Get the SUFFIX_LINES from the call to datasources_open,
and pass it to svn_diff__lcs.
Modified:
subversion/trunk/subversion/include/svn_diff.h
subversion/trunk/subversion/libsvn_diff/diff.c
subversion/trunk/subversion/libsvn_diff/diff.h
subversion/trunk/subversion/libsvn_diff/diff3.c
subversion/trunk/subversion/libsvn_diff/diff4.c
subversion/trunk/subversion/libsvn_diff/diff_file.c
subversion/trunk/subversion/libsvn_diff/diff_memory.c
subversion/trunk/subversion/libsvn_diff/lcs.c
Modified: subversion/trunk/subversion/include/svn_diff.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_diff.h?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_diff.h (original)
+++ subversion/trunk/subversion/include/svn_diff.h Fri Feb 11 21:38:55 2011
@@ -109,7 +109,9 @@ typedef enum svn_diff_datasource_e
typedef struct svn_diff_fns2_t
{
/** Open the datasources of type @a datasources. */
- svn_error_t *(*datasources_open)(void *diff_baton, apr_off_t *prefix_lines,
+ svn_error_t *(*datasources_open)(void *diff_baton,
+ apr_off_t *prefix_lines,
+ apr_off_t *suffix_lines,
const svn_diff_datasource_e *datasources,
apr_size_t datasources_len);
Modified: subversion/trunk/subversion/libsvn_diff/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff.c?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff.c (original)
+++ subversion/trunk/subversion/libsvn_diff/diff.c Fri Feb 11 21:38:55 2011
@@ -111,6 +111,7 @@ svn_diff_diff_2(svn_diff_t **diff,
apr_pool_t *subpool;
apr_pool_t *treepool;
apr_off_t prefix_lines = 0;
+ apr_off_t suffix_lines = 0;
*diff = NULL;
@@ -119,7 +120,8 @@ svn_diff_diff_2(svn_diff_t **diff,
svn_diff__tree_create(&tree, treepool);
- SVN_ERR(vtable->datasources_open(diff_baton, &prefix_lines, datasource, 2));
+ SVN_ERR(vtable->datasources_open(diff_baton, &prefix_lines, &suffix_lines,
+ datasource, 2));
/* Insert the data into the tree */
SVN_ERR(svn_diff__get_tokens(&position_list[0],
@@ -146,7 +148,8 @@ svn_diff_diff_2(svn_diff_t **diff,
svn_pool_destroy(treepool);
/* Get the lcs */
- lcs = svn_diff__lcs(position_list[0], position_list[1], prefix_lines, subpool);
+ lcs = svn_diff__lcs(position_list[0], position_list[1], prefix_lines,
+ suffix_lines, subpool);
/* Produce the diff */
*diff = svn_diff__diff(lcs, 1, 1, TRUE, pool);
Modified: subversion/trunk/subversion/libsvn_diff/diff.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff.h?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff.h (original)
+++ subversion/trunk/subversion/libsvn_diff/diff.h Fri Feb 11 21:38:55 2011
@@ -92,6 +92,7 @@ svn_diff__lcs_t *
svn_diff__lcs(svn_diff__position_t *position_list1, /* pointer to tail (ring) */
svn_diff__position_t *position_list2, /* pointer to tail (ring) */
apr_off_t prefix_lines,
+ apr_off_t suffix_lines,
apr_pool_t *pool);
Modified: subversion/trunk/subversion/libsvn_diff/diff3.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff3.c?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff3.c (original)
+++ subversion/trunk/subversion/libsvn_diff/diff3.c Fri Feb 11 21:38:55 2011
@@ -173,7 +173,7 @@ svn_diff__resolve_conflict(svn_diff_t *h
position[1]->next = start_position[1];
}
- *lcs_ref = svn_diff__lcs(position[0], position[1], 0,
+ *lcs_ref = svn_diff__lcs(position[0], position[1], 0, 0,
subpool);
/* Fix up the EOF lcs element in case one of
@@ -259,6 +259,7 @@ svn_diff_diff3_2(svn_diff_t **diff,
apr_pool_t *subpool;
apr_pool_t *treepool;
apr_off_t prefix_lines = 0;
+ apr_off_t suffix_lines = 0;
*diff = NULL;
@@ -267,7 +268,8 @@ svn_diff_diff3_2(svn_diff_t **diff,
svn_diff__tree_create(&tree, treepool);
- SVN_ERR(vtable->datasources_open(diff_baton, &prefix_lines, datasource, 3));
+ SVN_ERR(vtable->datasources_open(diff_baton, &prefix_lines, &suffix_lines,
+ datasource, 3));
SVN_ERR(svn_diff__get_tokens(&position_list[0],
tree,
@@ -299,9 +301,9 @@ svn_diff_diff3_2(svn_diff_t **diff,
/* Get the lcs for original-modified and original-latest */
lcs_om = svn_diff__lcs(position_list[0], position_list[1], prefix_lines,
- subpool);
+ suffix_lines, subpool);
lcs_ol = svn_diff__lcs(position_list[0], position_list[2], prefix_lines,
- subpool);
+ suffix_lines, subpool);
/* Produce a merged diff */
{
Modified: subversion/trunk/subversion/libsvn_diff/diff4.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff4.c?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff4.c (original)
+++ subversion/trunk/subversion/libsvn_diff/diff4.c Fri Feb 11 21:38:55 2011
@@ -186,6 +186,7 @@ svn_diff_diff4_2(svn_diff_t **diff,
apr_pool_t *subpool2;
apr_pool_t *subpool3;
apr_off_t prefix_lines = 0;
+ apr_off_t suffix_lines = 0;
*diff = NULL;
@@ -195,7 +196,8 @@ svn_diff_diff4_2(svn_diff_t **diff,
svn_diff__tree_create(&tree, subpool3);
- SVN_ERR(vtable->datasources_open(diff_baton, &prefix_lines, datasource, 4));
+ SVN_ERR(vtable->datasources_open(diff_baton, &prefix_lines, &suffix_lines,
+ datasource, 4));
SVN_ERR(svn_diff__get_tokens(&position_list[0],
tree,
@@ -234,7 +236,7 @@ svn_diff_diff4_2(svn_diff_t **diff,
/* Get the lcs for original - latest */
lcs_ol = svn_diff__lcs(position_list[0], position_list[2], prefix_lines,
- subpool3);
+ suffix_lines, subpool3);
diff_ol = svn_diff__diff(lcs_ol, 1, 1, TRUE, pool);
svn_pool_clear(subpool3);
@@ -256,7 +258,7 @@ svn_diff_diff4_2(svn_diff_t **diff,
* Do reverse adjustements
*/
lcs_adjust = svn_diff__lcs(position_list[3], position_list[2], prefix_lines,
- subpool3);
+ suffix_lines, subpool3);
diff_adjust = svn_diff__diff(lcs_adjust, 1, 1, FALSE, subpool3);
adjust_diff(diff_ol, diff_adjust);
@@ -266,7 +268,7 @@ svn_diff_diff4_2(svn_diff_t **diff,
* Do forward adjustments
*/
lcs_adjust = svn_diff__lcs(position_list[1], position_list[3], prefix_lines,
- subpool3);
+ suffix_lines, subpool3);
diff_adjust = svn_diff__diff(lcs_adjust, 1, 1, FALSE, subpool3);
adjust_diff(diff_ol, diff_adjust);
Modified: subversion/trunk/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff_file.c?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/trunk/subversion/libsvn_diff/diff_file.c Fri Feb 11 21:38:55 2011
@@ -492,17 +492,29 @@ find_identical_prefix(svn_boolean_t *rea
}
+/* The number of identical suffix lines to keep with the middle section. These
+ * lines are not eliminated as suffix, and can be picked up by the token
+ * parsing and lcs steps. This is mainly for backward compatibility with
+ * the previous diff (and blame) output (if there are multiple diff solutions,
+ * our lcs algorithm prefers taking common lines from the start, rather than
+ * from the end. By giving it back some suffix lines, we give it some wiggle
+ * room to find the exact same diff as before).
+ *
+ * The number 50 is more or less arbitrary, based on some real-world tests
+ * with big files (and then doubling the required number to be on the safe
+ * side). This has a negligible effect on the power of the optimization. */
#define SUFFIX_LINES_TO_KEEP 50
/* Find the suffix which is identical between all elements of the FILE array.
+ * Return the number of suffix lines in SUFFIX_LINES.
*
* Before this function is called the FILEs' pointers and chunks should be
* positioned right after the identical prefix (which is the case after
* find_identical_prefix), so we can determine where suffix scanning should
* ultimately stop. */
static svn_error_t *
-find_identical_suffix(struct file_info file[], apr_size_t file_len,
- apr_pool_t *pool)
+find_identical_suffix(apr_off_t *suffix_lines, struct file_info file[],
+ apr_size_t file_len, apr_pool_t *pool)
{
struct file_info file_for_suffix[4];
apr_off_t length[4];
@@ -510,7 +522,9 @@ find_identical_suffix(struct file_info f
apr_off_t suffix_min_offset0;
apr_off_t min_file_size;
int suffix_lines_to_keep = SUFFIX_LINES_TO_KEEP;
- svn_boolean_t is_match, can_read, reached_prefix;
+ svn_boolean_t is_match, reached_prefix;
+ apr_off_t lines = 0;
+ svn_boolean_t had_cr, had_nl;
apr_size_t i;
memset(file_for_suffix, 0, sizeof(file_for_suffix));
@@ -560,7 +574,15 @@ find_identical_suffix(struct file_info f
}
/* Scan backwards until mismatch or until we reach the prefix. */
- while (1)
+ for (i = 1, is_match = TRUE; i < file_len; i++)
+ is_match = is_match
+ && *file_for_suffix[0].curp == *file_for_suffix[i].curp;
+ if (is_match && *file_for_suffix[0].curp != '\r'
+ && *file_for_suffix[0].curp != '\n')
+ /* Count an extra line for the last line not ending in an eol. */
+ lines++;
+
+ while (is_match)
{
/* Initialize the minimum pointer positions. */
const char *min_curp[4];
@@ -568,6 +590,26 @@ find_identical_suffix(struct file_info f
svn_boolean_t can_read_word;
#endif /* SVN_UNALIGNED_ACCESS_IS_OK */
+ /* ### TODO: see if we can take advantage of
+ diff options like ignore_eol_style or ignore_space. */
+ /* check for eol, and count */
+ if (*file_for_suffix[0].curp == '\n')
+ {
+ lines++;
+ had_nl = TRUE;
+ }
+ else if (*file_for_suffix[0].curp == '\r' && !had_nl)
+ {
+ lines++;
+ }
+ else
+ {
+ had_nl = FALSE;
+ }
+
+ DECREMENT_POINTERS(file_for_suffix, file_len, pool);
+
+
min_curp[0] = file_for_suffix[0].chunk == suffix_min_chunk0
? file_for_suffix[0].buffer + suffix_min_offset0 + 1
: file_for_suffix[0].buffer + 1;
@@ -585,16 +627,21 @@ find_identical_suffix(struct file_info f
{
do
{
+ apr_size_t chunk;
for (i = 0; i < file_len; i++)
file_for_suffix[i].curp -= sizeof(apr_size_t);
+ chunk = *(const apr_size_t *)(file_for_suffix[0].curp + 1);
+ if (contains_eol(chunk))
+ break;
+
for (i = 0, can_read_word = TRUE; i < file_len; i++)
can_read_word = can_read_word
&& ( file_for_suffix[i].curp - sizeof(apr_size_t)
>= min_curp[i]);
for (i = 1, is_match = TRUE; i < file_len; i++)
is_match = is_match
- && ( *(const apr_size_t *)(file_for_suffix[0].curp + 1)
+ && ( chunk
== *(const apr_size_t *)(file_for_suffix[i].curp + 1));
} while (can_read_word && is_match);
@@ -604,33 +651,15 @@ find_identical_suffix(struct file_info f
#endif
- for (i = 1, is_match = TRUE; i < file_len; i++)
- is_match =
- is_match && *file_for_suffix[0].curp == *file_for_suffix[i].curp;
- for (i = 0, can_read = TRUE; i < file_len; i++)
- can_read = can_read && (file_for_suffix[i].curp > min_curp[i]);
- while (is_match && can_read)
- {
- for (i = 0; i < file_len; i++)
- file_for_suffix[i].curp--;
- for (i = 1, is_match = TRUE; i < file_len; i++)
- is_match =
- is_match && *file_for_suffix[0].curp == *file_for_suffix[i].curp;
- for (i = 0, can_read = TRUE; i < file_len; i++)
- can_read = can_read && (file_for_suffix[i].curp > min_curp[i]);
- }
-
- if (!is_match)
- break;
-
- DECREMENT_POINTERS(file_for_suffix, file_len, pool);
-
reached_prefix = file_for_suffix[0].chunk == suffix_min_chunk0
&& (file_for_suffix[0].curp - file_for_suffix[0].buffer)
== suffix_min_offset0;
-
if (reached_prefix || is_one_at_bof(file_for_suffix, file_len))
break;
+
+ for (i = 1, is_match = TRUE; i < file_len; i++)
+ is_match = is_match
+ && *file_for_suffix[0].curp == *file_for_suffix[i].curp;
}
/* Slide one byte forward, to point at the first byte of identical suffix */
@@ -641,6 +670,7 @@ find_identical_suffix(struct file_info f
one file reaches its end. */
do
{
+ had_cr = FALSE;
while (!is_one_at_eof(file_for_suffix, file_len)
&& *file_for_suffix[0].curp != '\n'
&& *file_for_suffix[0].curp != '\r')
@@ -649,14 +679,25 @@ find_identical_suffix(struct file_info f
/* Slide one or two more bytes, to point past the eol. */
if (!is_one_at_eof(file_for_suffix, file_len)
&& *file_for_suffix[0].curp == '\r')
- INCREMENT_POINTERS(file_for_suffix, file_len, pool);
+ {
+ lines--;
+ had_cr = TRUE;
+ INCREMENT_POINTERS(file_for_suffix, file_len, pool);
+ }
if (!is_one_at_eof(file_for_suffix, file_len)
&& *file_for_suffix[0].curp == '\n')
- INCREMENT_POINTERS(file_for_suffix, file_len, pool);
+ {
+ if (!had_cr)
+ lines--;
+ INCREMENT_POINTERS(file_for_suffix, file_len, pool);
+ }
}
while (!is_one_at_eof(file_for_suffix, file_len)
&& suffix_lines_to_keep--);
+ if (is_one_at_eof(file_for_suffix, file_len))
+ lines = 0;
+
/* Save the final suffix information in the original file_info */
for (i = 0; i < file_len; i++)
{
@@ -665,6 +706,8 @@ find_identical_suffix(struct file_info f
file_for_suffix[i].curp - file_for_suffix[i].buffer;
}
+ *suffix_lines = lines;
+
return SVN_NO_ERROR;
}
@@ -677,7 +720,8 @@ find_identical_suffix(struct file_info f
* FILE.file, FILE.size, FILE.buffer, FILE.curp and FILE.endp; allocate a
* buffer and read the first chunk. Then find the prefix and suffix lines
* which are identical between all the files. Return the number of identical
- * prefix lines in PREFIX_LINES.
+ * prefix lines in PREFIX_LINES, and the number of identical suffix lines in
+ * SUFFIX_LINES.
*
* Finding the identical prefix and suffix allows us to exclude those from the
* rest of the diff algorithm, which increases performance by reducing the
@@ -685,7 +729,9 @@ find_identical_suffix(struct file_info f
*
* Implements svn_diff_fns2_t::datasources_open. */
static svn_error_t *
-datasources_open(void *baton, apr_off_t *prefix_lines,
+datasources_open(void *baton,
+ apr_off_t *prefix_lines,
+ apr_off_t *suffix_lines,
const svn_diff_datasource_e *datasources,
apr_size_t datasources_len)
{
@@ -696,9 +742,10 @@ datasources_open(void *baton, apr_off_t
svn_boolean_t reached_one_eof;
apr_size_t i;
- /* Make sure prefix_lines is set correctly, even if we exit early because
- * one of the files is empty. */
+ /* Make sure prefix_lines and suffix_lines are set correctly, even if we
+ * exit early because one of the files is empty. */
*prefix_lines = 0;
+ *suffix_lines = 0;
/* Open datasources and read first chunk */
for (i = 0; i < datasources_len; i++)
@@ -736,11 +783,8 @@ datasources_open(void *baton, apr_off_t
if (!reached_one_eof)
/* No file consisted totally of identical prefix,
* so there may be some identical suffix. */
- /* ### jcorve0: disable for now, because this causes wc corruption
- * when merging files with more than 50 lines of identical suffix
- * (identical suffix is truncated after the 50th common line). */
- if (FALSE)
- SVN_ERR(find_identical_suffix(files, datasources_len, file_baton->pool));
+ SVN_ERR(find_identical_suffix(suffix_lines, files, datasources_len,
+ file_baton->pool));
/* Copy local results back to baton. */
for (i = 0; i < datasources_len; i++)
Modified: subversion/trunk/subversion/libsvn_diff/diff_memory.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff_memory.c?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff_memory.c (original)
+++ subversion/trunk/subversion/libsvn_diff/diff_memory.c Fri Feb 11 21:38:55 2011
@@ -90,12 +90,15 @@ datasource_to_index(svn_diff_datasource_
/* Implements svn_diff_fns2_t::datasources_open */
static svn_error_t *
-datasources_open(void *baton, apr_off_t *prefix_lines,
+datasources_open(void *baton,
+ apr_off_t *prefix_lines,
+ apr_off_t *suffix_lines,
const svn_diff_datasource_e *datasources,
apr_size_t datasources_len)
{
/* Do nothing: everything is already there and initialized to 0 */
*prefix_lines = 0;
+ *suffix_lines = 0;
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/libsvn_diff/lcs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/lcs.c?rev=1069961&r1=1069960&r2=1069961&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/lcs.c (original)
+++ subversion/trunk/subversion/libsvn_diff/lcs.c Fri Feb 11 21:38:55 2011
@@ -160,29 +160,28 @@ svn_diff__lcs_reverse(svn_diff__lcs_t *l
}
-/* Prepends a new lcs chunk for the amount of PREFIX_LINES to the given LCS
- * chain, and returns it. This function assumes PREFIX_LINES > 0. */
+/* Prepends a new lcs chunk for the amount of LINES at the given positions
+ * POS0_OFFSET and POS1_OFFSET to the given LCS chain, and returns it.
+ * This function assumes LINES > 0. */
static svn_diff__lcs_t *
-prepend_prefix_lcs(svn_diff__lcs_t *lcs,
- apr_off_t prefix_lines,
- apr_pool_t *pool)
+prepend_lcs(svn_diff__lcs_t *lcs, apr_off_t lines,
+ apr_off_t pos0_offset, apr_off_t pos1_offset,
+ apr_pool_t *pool)
{
- svn_diff__lcs_t *prefix_lcs;
+ svn_diff__lcs_t *new_lcs;
- SVN_ERR_ASSERT_NO_RETURN(prefix_lines > 0);
+ SVN_ERR_ASSERT_NO_RETURN(lines > 0);
- prefix_lcs = apr_palloc(pool, sizeof(*prefix_lcs));
- prefix_lcs->position[0] = apr_pcalloc(pool,
- sizeof(*prefix_lcs->position[0]));
- prefix_lcs->position[0]->offset = 1;
- prefix_lcs->position[1] = apr_pcalloc(pool,
- sizeof(*prefix_lcs->position[1]));
- prefix_lcs->position[1]->offset = 1;
- prefix_lcs->length = prefix_lines;
- prefix_lcs->refcount = 1;
- prefix_lcs->next = lcs;
+ new_lcs = apr_palloc(pool, sizeof(*new_lcs));
+ new_lcs->position[0] = apr_pcalloc(pool, sizeof(*new_lcs->position[0]));
+ new_lcs->position[0]->offset = pos0_offset;
+ new_lcs->position[1] = apr_pcalloc(pool, sizeof(*new_lcs->position[1]));
+ new_lcs->position[1]->offset = pos1_offset;
+ new_lcs->length = lines;
+ new_lcs->refcount = 1;
+ new_lcs->next = lcs;
- return prefix_lcs;
+ return new_lcs;
}
@@ -190,6 +189,7 @@ svn_diff__lcs_t *
svn_diff__lcs(svn_diff__position_t *position_list1, /* pointer to tail (ring) */
svn_diff__position_t *position_list2, /* pointer to tail (ring) */
apr_off_t prefix_lines,
+ apr_off_t suffix_lines,
apr_pool_t *pool)
{
int idx;
@@ -207,21 +207,28 @@ svn_diff__lcs(svn_diff__position_t *posi
*/
lcs = apr_palloc(pool, sizeof(*lcs));
lcs->position[0] = apr_pcalloc(pool, sizeof(*lcs->position[0]));
- lcs->position[0]->offset = position_list1 ?
- position_list1->offset + 1 : prefix_lines + 1;
+ lcs->position[0]->offset = position_list1
+ ? position_list1->offset + suffix_lines + 1
+ : prefix_lines + suffix_lines + 1;
lcs->position[1] = apr_pcalloc(pool, sizeof(*lcs->position[1]));
- lcs->position[1]->offset = position_list2 ?
- position_list2->offset + 1 : prefix_lines + 1;
+ lcs->position[1]->offset = position_list2
+ ? position_list2->offset + suffix_lines + 1
+ : prefix_lines + suffix_lines + 1;
lcs->length = 0;
lcs->refcount = 1;
lcs->next = NULL;
if (position_list1 == NULL || position_list2 == NULL)
{
+ if (suffix_lines)
+ lcs = prepend_lcs(lcs, suffix_lines,
+ lcs->position[0]->offset - suffix_lines,
+ lcs->position[1]->offset - suffix_lines,
+ pool);
if (prefix_lines)
- return prepend_prefix_lcs(lcs, prefix_lines, pool);
- else
- return lcs;
+ lcs = prepend_lcs(lcs, prefix_lines, 1, 1, pool);
+
+ return lcs;
}
/* Calculate length of both sequences to be compared */
@@ -277,14 +284,21 @@ svn_diff__lcs(svn_diff__position_t *posi
}
while (fp[d].position[1] != &sentinel_position[1]);
- lcs->next = fp[d].lcs;
+ if (suffix_lines)
+ lcs->next = prepend_lcs(fp[d].lcs, suffix_lines,
+ lcs->position[0]->offset - suffix_lines,
+ lcs->position[1]->offset - suffix_lines,
+ pool);
+ else
+ lcs->next = fp[d].lcs;
+
lcs = svn_diff__lcs_reverse(lcs);
position_list1->next = sentinel_position[idx].next;
position_list2->next = sentinel_position[abs(1 - idx)].next;
if (prefix_lines)
- return prepend_prefix_lcs(lcs, prefix_lines, pool);
+ return prepend_lcs(lcs, prefix_lines, 1, 1, pool);
else
return lcs;
}
Re: svn commit: r1069961 - in /subversion/trunk/subversion:
include/svn_diff.h libsvn_diff/diff.c libsvn_diff/diff.h libsvn_diff/diff3.c
libsvn_diff/diff4.c libsvn_diff/diff_file.c libsvn_diff/diff_memory.c libsvn_diff/lcs.c
Posted by Johan Corveleyn <jc...@gmail.com>.
On Sat, Feb 19, 2011 at 8:03 PM, Ivan Zhakov <iv...@visualsvn.com> wrote:
> On Sat, Feb 12, 2011 at 00:38, <jc...@apache.org> wrote:
>> Author: jcorvel
>> Date: Fri Feb 11 21:38:55 2011
>> New Revision: 1069961
>>
>> URL: http://svn.apache.org/viewvc?rev=1069961&view=rev
>> Log:
>> Re-enable elimination of the identical suffix for diff (and diff3 (merge) and
>> diff4), which was disabled in r1068613 because of truncation of suffix lines
>> during merge.
>>
>> This time, count the number of suffix lines so we can create an entirely
>> correct LCS, also containing the common suffix, so diff3 (merge) can do its
>> work properly.
>>
>> * subversion/include/svn_diff.h
>> (svn_diff_fns2_t): Add a new output parameter SUFFIX_LINES to the
>> datasources_open prototype. The svn_diff_fns2_t struct is new in 1.7 (was
>> already revved), so we can still do this.
>>
> Hi Johan,
>
> It seems libsvn_diff\deprecated.c:datasources_open() should be updated
> to new signature. I get the following warning when compiling:
> [[
> ..\..\..\subversion\libsvn_diff\deprecated.c(128) : warning C4113:
> 'svn_error_t *(__cdecl *)(void *,apr_off_t *,const
> svn_diff_datasource_e *,apr_size_t)' differs in parameter lists from
> 'svn_error_t *(__cdecl *)(void *,apr_off_t *,apr_off_t *,const
> svn_diff_datasource_e *,apr_size_t)'
> ]]
Ohhh, I knew I had forgotten something. Thanks for catching this.
Fixed in r1072447
--
Johan
Re: svn commit: r1069961 - in /subversion/trunk/subversion:
include/svn_diff.h libsvn_diff/diff.c libsvn_diff/diff.h libsvn_diff/diff3.c
libsvn_diff/diff4.c libsvn_diff/diff_file.c libsvn_diff/diff_memory.c libsvn_diff/lcs.c
Posted by Ivan Zhakov <iv...@visualsvn.com>.
On Sat, Feb 12, 2011 at 00:38, <jc...@apache.org> wrote:
> Author: jcorvel
> Date: Fri Feb 11 21:38:55 2011
> New Revision: 1069961
>
> URL: http://svn.apache.org/viewvc?rev=1069961&view=rev
> Log:
> Re-enable elimination of the identical suffix for diff (and diff3 (merge) and
> diff4), which was disabled in r1068613 because of truncation of suffix lines
> during merge.
>
> This time, count the number of suffix lines so we can create an entirely
> correct LCS, also containing the common suffix, so diff3 (merge) can do its
> work properly.
>
> * subversion/include/svn_diff.h
> (svn_diff_fns2_t): Add a new output parameter SUFFIX_LINES to the
> datasources_open prototype. The svn_diff_fns2_t struct is new in 1.7 (was
> already revved), so we can still do this.
>
Hi Johan,
It seems libsvn_diff\deprecated.c:datasources_open() should be updated
to new signature. I get the following warning when compiling:
[[
..\..\..\subversion\libsvn_diff\deprecated.c(128) : warning C4113:
'svn_error_t *(__cdecl *)(void *,apr_off_t *,const
svn_diff_datasource_e *,apr_size_t)' differs in parameter lists from
'svn_error_t *(__cdecl *)(void *,apr_off_t *,apr_off_t *,const
svn_diff_datasource_e *,apr_size_t)'
]]
--
Ivan Zhakov