Author: philip
Date: Thu Jul 21 10:53:15 2011
New Revision: 1149105
URL: http://svn.apache.org/viewvc?rev=1149105&view=rev
Log:
Fix issue 3966, log_noop_revs in merge is far too slow.
* subversion/libsvn_client/merge.c:
(rangelist_merge_revision): New, specialised rangelist merge.
(log_noop_revs): Use specialised rangelist merge.
Modified:
subversion/trunk/subversion/libsvn_client/merge.c
Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1149105&r1=1149104&r2=1149105&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu Jul 21 10:53:15 2011
@@ -7868,6 +7868,36 @@ typedef struct log_noop_baton_t
apr_pool_t *pool;
} log_noop_baton_t;
+/* Helper for log_noop_revs, this is not a general purpose rangelist
+ merge. Merge the single revision range REVISION-1 to REVISION into
+ RANGELIST. The existing ranges in RANGELIST must be ordered from
+ highest/youngest to lowest/oldest. */
+static svn_error_t *
+rangelist_merge_revision(apr_array_header_t *rangelist,
+ svn_revnum_t revision,
+ apr_pool_t *result_pool)
+{
+ svn_merge_range_t *new_range;
+ if (rangelist->nelts)
+ {
+ svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, rangelist->nelts - 1,
+ svn_merge_range_t *);
+ if (range->start == revision)
+ {
+ range->start = revision - 1;
+ return SVN_NO_ERROR;
+ }
+ }
+ new_range = apr_palloc(result_pool, sizeof(*new_range));
+ new_range->start = revision - 1;
+ new_range->end = revision;
+ new_range->inheritable = TRUE;
+
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = new_range;
+
+ return SVN_NO_ERROR;
+}
+
/* Implements the svn_log_entry_receiver_t interface.
BATON is an log_noop_baton_t *.
@@ -7892,7 +7922,6 @@ log_noop_revs(void *baton,
svn_boolean_t log_entry_rev_required = FALSE;
apr_array_header_t *rl1;
apr_array_header_t *rl2;
- apr_array_header_t *rangelist;
/* The baton's pool is essentially an iterpool so we must clear it
* for each invocation of this function, preserving the result
@@ -7909,12 +7938,10 @@ log_noop_revs(void *baton,
revision = log_entry->revision;
- rangelist = svn_rangelist__initialize(revision - 1, revision, TRUE,
- log_gap_baton->pool);
/* Unconditionally add LOG_ENTRY->REVISION to BATON->OPERATIVE_MERGES. */
- SVN_ERR(svn_rangelist_merge(&(log_gap_baton->operative_ranges),
- rangelist,
- log_gap_baton->pool));
+ SVN_ERR(rangelist_merge_revision(log_gap_baton->operative_ranges,
+ revision,
+ log_gap_baton->pool));
/* Examine each path affected by LOG_ENTRY->REVISION. If the explicit or
inherited mergeinfo for *all* of the corresponding paths under
@@ -7977,6 +8004,10 @@ log_noop_revs(void *baton,
if (paths_explicit_rangelist)
{
apr_array_header_t *intersecting_range;
+ apr_array_header_t *rangelist;
+
+ rangelist = svn_rangelist__initialize(revision - 1, revision, TRUE,
+ log_gap_baton->pool);
/* If PATH inherited mergeinfo we must consider inheritance in the
event the inherited mergeinfo is actually non-inheritable. */
@@ -7995,9 +8026,9 @@ log_noop_revs(void *baton,
}
if (!log_entry_rev_required)
- SVN_ERR(svn_rangelist_merge(&(log_gap_baton->merged_ranges),
- rangelist,
- log_gap_baton->pool));
+ SVN_ERR(rangelist_merge_revision(log_gap_baton->merged_ranges,
+ revision,
+ log_gap_baton->pool));
return SVN_NO_ERROR;
}