You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/08/04 15:11:36 UTC
svn commit: r1153877 - in /subversion/branches/1.7.x: ./ STATUS
subversion/libsvn_repos/log.c
Author: hwright
Date: Thu Aug 4 13:11:35 2011
New Revision: 1153877
URL: http://svn.apache.org/viewvc?rev=1153877&view=rev
Log:
Merge r1152282 from trunk:
* r1152282
Improve performance of "log -g".
Justification:
Can be too slow to be useable.
Votes:
+1: philip, pburba, rhuijben
Modified:
subversion/branches/1.7.x/ (props changed)
subversion/branches/1.7.x/STATUS
subversion/branches/1.7.x/subversion/libsvn_repos/log.c
Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Aug 4 13:11:35 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,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147309,1147882,1148071,1148131,1148374,1148424,1148566,1148588,1148853,1148877,1148882,1148936,1149105,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149675,1149701,1149713,1150242,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151911,1152129,1152726,1153416
+/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147309,1147882,1148071,1148131,1148374,1148424,1148566,1148588,1148853,1148877,1148882,1148936,1149105,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149675,1149701,1149713,1150242,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151911,1152129,1152282,1152726,1153416
Modified: subversion/branches/1.7.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1153877&r1=1153876&r2=1153877&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Thu Aug 4 13:11:35 2011
@@ -213,10 +213,3 @@ Approved changes:
this revision depends for a clean merge).
Votes:
+1: rhuijben, danielsh, cmpilato
-
- * r1152282
- Improve performance of "log -g".
- Justification:
- Can be too slow to be useable.
- Votes:
- +1: philip, pburba, rhuijben
Modified: subversion/branches/1.7.x/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_repos/log.c?rev=1153877&r1=1153876&r2=1153877&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_repos/log.c Thu Aug 4 13:11:35 2011
@@ -857,6 +857,9 @@ get_combined_mergeinfo_changes(svn_merge
iterpool));
mergeinfo = apr_hash_get(catalog, path, APR_HASH_KEY_STRING);
+ if (!prev_mergeinfo && !mergeinfo)
+ continue;
+
/* Compare, constrast, and combine the results. */
SVN_ERR(svn_mergeinfo_diff(&deleted, &added, prev_mergeinfo,
mergeinfo, FALSE, iterpool));
@@ -1514,6 +1517,7 @@ static svn_error_t *
do_logs(svn_fs_t *fs,
const apr_array_header_t *paths,
svn_mergeinfo_t log_target_history_as_mergeinfo,
+ svn_mergeinfo_t processed,
apr_hash_t *nested_merges,
svn_revnum_t hist_start,
svn_revnum_t hist_end,
@@ -1568,6 +1572,7 @@ handle_merged_revisions(svn_revnum_t rev
svn_fs_t *fs,
svn_mergeinfo_t log_target_history_as_mergeinfo,
apr_hash_t *nested_merges,
+ svn_mergeinfo_t processed,
svn_mergeinfo_t added_mergeinfo,
svn_mergeinfo_t deleted_mergeinfo,
svn_boolean_t discover_changed_paths,
@@ -1610,7 +1615,7 @@ handle_merged_revisions(svn_revnum_t rev
svn_pool_clear(iterpool);
SVN_ERR(do_logs(fs, pl_range->paths, log_target_history_as_mergeinfo,
- nested_merges,
+ processed, nested_merges,
pl_range->range.start, pl_range->range.end, 0,
discover_changed_paths, strict_node_history,
TRUE, pl_range->reverse_merge, TRUE, TRUE,
@@ -1633,6 +1638,115 @@ struct added_deleted_mergeinfo
svn_mergeinfo_t deleted_mergeinfo;
};
+/* Reduce the search range PATHS, HIST_START, HIST_END by removing
+ parts already covered by PROCESSED. If reduction is possible
+ elements may be removed from PATHS and *START_REDUCED and
+ *END_REDUCED may be set to a narrower range. */
+static svn_error_t *
+reduce_search(apr_array_header_t *paths,
+ svn_revnum_t *hist_start,
+ svn_revnum_t *hist_end,
+ svn_mergeinfo_t processed,
+ apr_pool_t *scratch_pool)
+{
+ /* We add 1 to end to compensate for store_search */
+ svn_revnum_t start = *hist_start <= *hist_end ? *hist_start : *hist_end;
+ svn_revnum_t end = *hist_start <= *hist_end ? *hist_end + 1 : *hist_start + 1;
+ int i;
+
+ for (i = 0; i < paths->nelts; ++i)
+ {
+ const char *path = APR_ARRAY_IDX(paths, i, const char *);
+ apr_array_header_t *ranges = apr_hash_get(processed, path,
+ APR_HASH_KEY_STRING);
+ int j;
+
+ if (!ranges)
+ continue;
+
+ /* ranges is ordered, could we use some sort of binay search
+ rather than iterating? */
+ for (j = 0; j < ranges->nelts; ++j)
+ {
+ svn_merge_range_t *range = APR_ARRAY_IDX(ranges, j,
+ svn_merge_range_t *);
+ if (range->start <= start && range->end >= end)
+ {
+ for (j = i; j < paths->nelts - 1; ++j)
+ APR_ARRAY_IDX(paths, j, const char *)
+ = APR_ARRAY_IDX(paths, j + 1, const char *);
+
+ --paths->nelts;
+ --i;
+ break;
+ }
+
+ /* If there is only one path then we also check for a
+ partial overlap rather than the full overlap above, and
+ reduce the [hist_start, hist_end] range rather than
+ dropping the path. */
+ if (paths->nelts == 1)
+ {
+ if (range->start <= start && range->end > start)
+ {
+ if (start == *hist_start)
+ *hist_start = range->end - 1;
+ else
+ *hist_end = range->end - 1;
+ break;
+ }
+ if (range->start < end && range->end >= end)
+ {
+ if (start == *hist_start)
+ *hist_end = range->start;
+ else
+ *hist_start = range->start;
+ break;
+ }
+ }
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Extend PROCESSED to cover PATHS from HIST_START to HIST_END */
+static svn_error_t *
+store_search(svn_mergeinfo_t processed,
+ const apr_array_header_t *paths,
+ svn_revnum_t hist_start,
+ svn_revnum_t hist_end,
+ apr_pool_t *scratch_pool)
+{
+ /* We add 1 to end so that we can use the mergeinfo API to handle
+ singe revisions where HIST_START is equal to HIST_END. */
+ svn_revnum_t start = hist_start <= hist_end ? hist_start : hist_end;
+ svn_revnum_t end = hist_start <= hist_end ? hist_end + 1 : hist_start + 1;
+ svn_mergeinfo_t mergeinfo = apr_hash_make(scratch_pool);
+ apr_pool_t *processed_pool = apr_hash_pool_get(processed);
+ int i;
+
+ for (i = 0; i < paths->nelts; ++i)
+ {
+ const char *path = APR_ARRAY_IDX(paths, i, const char *);
+ apr_array_header_t *ranges = apr_array_make(processed_pool, 1,
+ sizeof(svn_merge_range_t*));
+ svn_merge_range_t *range = apr_palloc(processed_pool,
+ sizeof(svn_merge_range_t));
+
+ range->start = start;
+ range->end = end;
+ range->inheritable = TRUE;
+ APR_ARRAY_PUSH(ranges, svn_merge_range_t *) = range;
+ apr_hash_set(mergeinfo, apr_pstrdup(processed_pool, path),
+ APR_HASH_KEY_STRING, ranges);
+ }
+ SVN_ERR(svn_mergeinfo_merge(processed, mergeinfo,
+ apr_hash_pool_get(processed)));
+
+ return SVN_NO_ERROR;
+}
+
/* Find logs for PATHS from HIST_START to HIST_END in FS, and invoke
RECEIVER with RECEIVER_BATON on them. If DESCENDING_ORDER is TRUE, send
the logs back as we find them, else buffer the logs and send them back
@@ -1657,12 +1771,17 @@ struct added_deleted_mergeinfo
do_logs()/send_logs()/handle_merge_revisions() recursions, see also the
argument of the same name in send_logs().
+ If PROCESSED is a mergeinfo hash that represents the paths and
+ revisions that have already been searched. Allocated like
+ NESTED_MERGES above.
+
All other parameters are the same as svn_repos_get_logs4().
*/
static svn_error_t *
do_logs(svn_fs_t *fs,
const apr_array_header_t *paths,
svn_mergeinfo_t log_target_history_as_mergeinfo,
+ svn_mergeinfo_t processed,
apr_hash_t *nested_merges,
svn_revnum_t hist_start,
svn_revnum_t hist_end,
@@ -1691,6 +1810,20 @@ do_logs(svn_fs_t *fs,
int send_count = 0;
int i;
+ if (processed)
+ {
+ /* Casting away const. This only happens on recursive calls when
+ it is known to be safe because we allocated paths. */
+ SVN_ERR(reduce_search((apr_array_header_t *)paths, &hist_start, &hist_end,
+ processed, pool));
+ }
+
+ if (!paths->nelts)
+ return SVN_NO_ERROR;
+
+ if (processed)
+ SVN_ERR(store_search(processed, paths, hist_start, hist_end, pool));
+
/* We have a list of paths and a revision range. But we don't care
about all the revisions in the range -- only the ones in which
one of our paths was changed. So let's go figure out which
@@ -1779,11 +1912,13 @@ do_logs(svn_fs_t *fs,
recursions so we can track and squelch duplicates. */
subpool = svn_pool_create(pool);
nested_merges = apr_hash_make(subpool);
+ processed = apr_hash_make(subpool);
}
SVN_ERR(handle_merged_revisions(
current, fs,
log_target_history_as_mergeinfo, nested_merges,
+ processed,
added_mergeinfo, deleted_mergeinfo,
discover_changed_paths,
strict_node_history,
@@ -1882,6 +2017,7 @@ do_logs(svn_fs_t *fs,
SVN_ERR(handle_merged_revisions(current, fs,
log_target_history_as_mergeinfo,
nested_merges,
+ processed,
added_mergeinfo,
deleted_mergeinfo,
discover_changed_paths,
@@ -2092,7 +2228,7 @@ svn_repos_get_logs4(svn_repos_t *repos,
svn_pool_destroy(subpool);
}
- return do_logs(repos->fs, paths, paths_history_mergeinfo, NULL, start, end,
+ return do_logs(repos->fs, paths, paths_history_mergeinfo, NULL, NULL, start, end,
limit, discover_changed_paths, strict_node_history,
include_merged_revisions, FALSE, FALSE, FALSE, revprops,
descending_order, receiver, receiver_baton,