Author: hwright
Date: Thu Jul 21 20:09:22 2011
New Revision: 1149340
URL: http://svn.apache.org/viewvc?rev=1149340&view=rev
Log:
Merge r1148877, r1148882, r1149105, r1149141, r1149228 from trunk:
* r1148877,r1148882,r1149105,r1149141, r1149228
Issue 3966, log_noop_revs too slow.
Justification:
Merge is far too slow when lots of revisions have to be checked.
Notes:
r1148877 is pool cleanup
r1148882 is docstring cleanup
r1149105 is the actual fix
r1149141 is more pool cleanup
r1149228 is a fix for r1149105
(see http://svn.haxx.se/dev/archive-2011-07/0645.shtml)
Votes:
+1: philip, hwright, pburba
+1: rhuijben (all but r1149228)
Modified:
subversion/branches/1.7.x/ (props changed)
subversion/branches/1.7.x/STATUS
subversion/branches/1.7.x/subversion/libsvn_client/merge.c
Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jul 21 20:09:22 2011
@@ -54,4 +54,4 @@
/subversion/branches/tree-conflicts:868291-873154
/subversion/branches/tree-conflicts-notify:873926-874008
/subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147309,1148071,1148131,1148374,1148566,1148588,1148853,1148936
+/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147309,1148071,1148131,1148374,1148566,1148588,1148853,1148877,1148882,1148936,1149105,1149141,1149228
Modified: subversion/branches/1.7.x/STATUS
URL:
http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1149340&r1=1149339&r2=1149340&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Thu Jul 21 20:09:22 2011
@@ -113,18 +113,3 @@ Veto-blocked changes:
Approved changes:
=================
-
- * r1148877,r1148882,r1149105,r1149141, r1149228
- Issue 3966, log_noop_revs too slow.
- Justification:
- Merge is far too slow when lots of revisions have to be checked.
- Notes:
- r1148877 is pool cleanup
- r1148882 is docstring cleanup
- r1149105 is the actual fix
- r1149141 is more pool cleanup
- r1149228 is a fix for r1149105
- (see http://svn.haxx.se/dev/archive-2011-07/0645.shtml)
- Votes:
- +1: philip, hwright, pburba
- +1: rhuijben (all but r1149228)
Modified: subversion/branches/1.7.x/subversion/libsvn_client/merge.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_client/merge.c?rev=1149340&r1=1149339&r2=1149340&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_client/merge.c Thu Jul 21
20:09:22 2011
@@ -7843,13 +7843,53 @@ typedef struct log_noop_baton_t
being diffed. */
const char *source_repos_abs;
- /* Initially empty rangelists allocated in POOL. */
+ /* Initially empty rangelists allocated in POOL. The rangelists are
+ * populated across multiple invocations of the log_noop_revs(). */
apr_array_header_t *operative_ranges;
apr_array_header_t *merged_ranges;
+ /* Pool to store the rangelists. */
apr_pool_t *pool;
} log_noop_baton_t;
+/* Helper for log_noop_revs: Merge a svn_merge_range_t representation of
+ REVISION into RANGELIST. New elements added to rangelist are allocated
+ in RESULT_POOL.
+
+ This is *not* a general purpose rangelist merge but a special replacement
+ for svn_rangelist_merge when REVISION is guaranteed to be younger than any
+ element in RANGELIST. svn_rangelist_merge is O(n) worst-case (i.e. when
+ all the ranges in output rangelist are older than the incoming changes).
+ This turns the special case of a single incoming younger range into O(1).
+ */
+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->end == revision - 1)
+ {
+ /* REVISION is adjacent to the youngest range in RANGELIST
+ so we can simply expand that range to encompass REVISION. */
+ range->end = revision;
+ 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 *.
@@ -7860,46 +7900,31 @@ typedef struct log_noop_baton_t
MERGE_B->TARGET_ABSPATH per the mergeinfo in CHILDREN_WITH_MERGEINFO,
then add LOG_ENTRY->REVISION to BATON->MERGED_RANGES.
- Use POOL for temporary allocations. Allocate additions to
+ Use SCRATCH_POOL for temporary allocations. Allocate additions to
BATON->MERGED_RANGES and BATON->OPERATIVE_RANGES in BATON->POOL.
*/
static svn_error_t *
log_noop_revs(void *baton,
svn_log_entry_t *log_entry,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
log_noop_baton_t *log_gap_baton = baton;
apr_hash_index_t *hi;
svn_revnum_t revision;
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. */
- rl1 = svn_rangelist_dup(log_gap_baton->operative_ranges, pool);
- rl2 = svn_rangelist_dup(log_gap_baton->merged_ranges, pool);
- svn_pool_clear(log_gap_baton->pool);
- log_gap_baton->operative_ranges = svn_rangelist_dup(rl1,
- log_gap_baton->pool);
- log_gap_baton->merged_ranges = svn_rangelist_dup(rl2,
- log_gap_baton->pool);
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
MERGE_B->TARGET_ABSPATH reflects that LOG_ENTRY->REVISION has been
merged, then add LOG_ENTRY->REVISION to BATON->MERGED_RANGES. */
- for (hi = apr_hash_first(pool, log_entry->changed_paths2);
+ for (hi = apr_hash_first(scratch_pool, log_entry->changed_paths2);
hi;
hi = apr_hash_next(hi))
{
@@ -7918,7 +7943,7 @@ log_noop_revs(void *baton,
if (rel_path == NULL)
continue;
cwmi_path = svn_dirent_join(log_gap_baton->merge_b->target_abspath,
- rel_path, pool);
+ rel_path, scratch_pool);
/* Find any explicit or inherited mergeinfo for PATH. */
while (!log_entry_rev_required)
@@ -7946,8 +7971,8 @@ log_noop_revs(void *baton,
}
/* Didn't find anything so crawl up to the parent. */
- cwmi_path = svn_dirent_dirname(cwmi_path, pool);
- path = svn_dirent_dirname(path, pool);
+ cwmi_path = svn_dirent_dirname(cwmi_path, scratch_pool);
+ path = svn_dirent_dirname(path, scratch_pool);
/* At this point *if* we find mergeinfo it will be inherited. */
mergeinfo_inherited = TRUE;
@@ -7956,13 +7981,17 @@ 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,
+ scratch_pool);
/* If PATH inherited mergeinfo we must consider inheritance in the
event the inherited mergeinfo is actually non-inheritable. */
SVN_ERR(svn_rangelist_intersect(&intersecting_range,
paths_explicit_rangelist,
rangelist,
- mergeinfo_inherited, pool));
+ mergeinfo_inherited, scratch_pool));
if (intersecting_range->nelts == 0)
log_entry_rev_required = TRUE;
@@ -7974,9 +8003,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;
}
@@ -8110,8 +8139,8 @@ remove_noop_subtree_ranges(const char *u
APR_ARRAY_PUSH(log_targets, const char *) = "";
- SVN_ERR(svn_ra_get_log2(ra_session, log_targets, youngest_gap_rev->end,
- oldest_gap_rev->start + 1, 0, TRUE, TRUE, FALSE,
+ SVN_ERR(svn_ra_get_log2(ra_session, log_targets, oldest_gap_rev->start + 1,
+ youngest_gap_rev->end, 0, TRUE, TRUE, FALSE,
apr_array_make(scratch_pool, 0,
sizeof(const char *)),
log_noop_revs, &log_gap_baton, scratch_pool));