You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/10/08 04:54:15 UTC
svn commit: r1395442 - /subversion/trunk/subversion/libsvn_repos/log.c
Author: stefan2
Date: Mon Oct 8 02:54:14 2012
New Revision: 1395442
URL: http://svn.apache.org/viewvc?rev=1395442&view=rev
Log:
When running "svn log -g", we will fetch the list of changed paths
(at least) twice for each revision. To prevent that, add the list
as an additional parameter to the relevant functions and let them
request the list only if it isn't already available through the
new parameter.
* subversion/libsvn_repos/log.c
(detect_changed,
fs_mergeinfo_changed,
get_combined_mergeinfo_changes,
fill_log_entry,
send_log): add optional refetched_changes parameter
(do_logs): use the above to fetch the changed path lists only once
(svn_repos_get_logs4): update other callers
Modified:
subversion/trunk/subversion/libsvn_repos/log.c
Modified: subversion/trunk/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/log.c?rev=1395442&r1=1395441&r2=1395442&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/log.c (original)
+++ subversion/trunk/subversion/libsvn_repos/log.c Mon Oct 8 02:54:14 2012
@@ -159,6 +159,10 @@ svn_repos_check_revision_access(svn_repo
* The CHANGED hash set and its keys and values are allocated in POOL;
* keys are const char * paths and values are svn_log_changed_path_t.
*
+ * To prevent changes from being processed over and over again, the
+ * changed paths for ROOT may be passed in PREFETCHED_CHANGES. If the
+ * latter is NULL, we will request the list inside this function.
+ *
* If optional AUTHZ_READ_FUNC is non-NULL, then use it (with
* AUTHZ_READ_BATON and FS) to check whether each changed-path (and
* copyfrom_path) is readable:
@@ -177,18 +181,20 @@ static svn_error_t *
detect_changed(apr_hash_t **changed,
svn_fs_root_t *root,
svn_fs_t *fs,
+ apr_hash_t *prefetched_changes,
svn_repos_authz_func_t authz_read_func,
void *authz_read_baton,
apr_pool_t *pool)
{
- apr_hash_t *changes;
+ apr_hash_t *changes = prefetched_changes;
apr_hash_index_t *hi;
apr_pool_t *subpool;
svn_boolean_t found_readable = FALSE;
svn_boolean_t found_unreadable = FALSE;
*changed = apr_hash_make(pool);
- SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));
+ if (changes == NULL)
+ SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));
if (apr_hash_count(changes) == 0)
/* No paths changed in this revision? Uh, sure, I guess the
@@ -551,19 +557,21 @@ next_history_rev(const apr_array_header_
/* Set *DELETED_MERGEINFO_CATALOG and *ADDED_MERGEINFO_CATALOG to
catalogs describing how mergeinfo values on paths (which are the
- keys of those catalogs) were changed in REV. */
+ keys of those catalogs) were changed in REV. If *PREFETCHED_CAHNGES
+ already contains the changed paths for REV, use that. Otherwise,
+ request that data and return it in *PREFETCHED_CHANGES. */
/* ### TODO: This would make a *great*, useful public function,
### svn_repos_fs_mergeinfo_changed()! -- cmpilato */
static svn_error_t *
fs_mergeinfo_changed(svn_mergeinfo_catalog_t *deleted_mergeinfo_catalog,
svn_mergeinfo_catalog_t *added_mergeinfo_catalog,
+ apr_hash_t **prefetched_changes,
svn_fs_t *fs,
svn_revnum_t rev,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- apr_hash_t *changes;
svn_fs_root_t *root;
apr_pool_t *iterpool;
apr_hash_index_t *hi;
@@ -579,17 +587,20 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
/* We're going to use the changed-paths information for REV to
narrow down our search. */
SVN_ERR(svn_fs_revision_root(&root, fs, rev, scratch_pool));
- SVN_ERR(svn_fs_paths_changed2(&changes, root, scratch_pool));
+ if (*prefetched_changes == NULL)
+ SVN_ERR(svn_fs_paths_changed2(prefetched_changes, root, scratch_pool));
/* No changed paths? We're done. */
- if (apr_hash_count(changes) == 0)
+ if (apr_hash_count(*prefetched_changes) == 0)
return SVN_NO_ERROR;
/* Loop over changes, looking for anything that might carry an
svn:mergeinfo change and is one of our paths of interest, or a
child or [grand]parent directory thereof. */
iterpool = svn_pool_create(scratch_pool);
- for (hi = apr_hash_first(scratch_pool, changes); hi; hi = apr_hash_next(hi))
+ for (hi = apr_hash_first(scratch_pool, *prefetched_changes);
+ hi;
+ hi = apr_hash_next(hi))
{
const void *key;
void *val;
@@ -769,10 +780,14 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
/* Determine what (if any) mergeinfo for PATHS was modified in
revision REV, returning the differences for added mergeinfo in
*ADDED_MERGEINFO and deleted mergeinfo in *DELETED_MERGEINFO.
+ If *PREFETCHED_CAHNGES already contains the changed paths for
+ REV, use that. Otherwise, request that data and return it in
+ *PREFETCHED_CHANGES.
Use POOL for all allocations. */
static svn_error_t *
get_combined_mergeinfo_changes(svn_mergeinfo_t *added_mergeinfo,
svn_mergeinfo_t *deleted_mergeinfo,
+ apr_hash_t **prefetched_changes,
svn_fs_t *fs,
const apr_array_header_t *paths,
svn_revnum_t rev,
@@ -804,6 +819,7 @@ get_combined_mergeinfo_changes(svn_merge
/* Fetch the mergeinfo changes for REV. */
err = fs_mergeinfo_changed(&deleted_mergeinfo_catalog,
&added_mergeinfo_catalog,
+ prefetched_changes,
fs, rev, scratch_pool, scratch_pool);
if (err)
{
@@ -989,6 +1005,7 @@ static svn_error_t *
fill_log_entry(svn_log_entry_t *log_entry,
svn_revnum_t rev,
svn_fs_t *fs,
+ apr_hash_t *prefetched_changes,
svn_boolean_t discover_changed_paths,
const apr_array_header_t *revprops,
svn_repos_authz_func_t authz_read_func,
@@ -1008,7 +1025,7 @@ fill_log_entry(svn_log_entry_t *log_entr
SVN_ERR(svn_fs_revision_root(&newroot, fs, rev, pool));
patherr = detect_changed(&changed_paths,
- newroot, fs,
+ newroot, fs, prefetched_changes,
authz_read_func, authz_read_baton,
pool);
@@ -1119,6 +1136,7 @@ fill_log_entry(svn_log_entry_t *log_entr
static svn_error_t *
send_log(svn_revnum_t rev,
svn_fs_t *fs,
+ apr_hash_t *prefetched_changes,
svn_mergeinfo_t log_target_history_as_mergeinfo,
apr_hash_t *nested_merges,
svn_boolean_t discover_changed_paths,
@@ -1137,7 +1155,7 @@ send_log(svn_revnum_t rev,
svn_boolean_t found_rev_of_interest = TRUE;
log_entry = svn_log_entry_create(pool);
- SVN_ERR(fill_log_entry(log_entry, rev, fs,
+ SVN_ERR(fill_log_entry(log_entry, rev, fs, prefetched_changes,
discover_changed_paths || handling_merged_revision,
revprops, authz_read_func, authz_read_baton,
pool));
@@ -1941,6 +1959,7 @@ do_logs(svn_fs_t *fs,
svn_mergeinfo_t added_mergeinfo = NULL;
svn_mergeinfo_t deleted_mergeinfo = NULL;
svn_boolean_t has_children = FALSE;
+ apr_hash_t *changes = NULL;
/* If we're including merged revisions, we need to calculate
the mergeinfo deltas committed in this revision to our
@@ -1961,6 +1980,7 @@ do_logs(svn_fs_t *fs,
}
SVN_ERR(get_combined_mergeinfo_changes(&added_mergeinfo,
&deleted_mergeinfo,
+ &changes,
fs, cur_paths,
current, iterpool,
iterpool));
@@ -1973,7 +1993,7 @@ do_logs(svn_fs_t *fs,
in anyway). */
if (descending_order)
{
- SVN_ERR(send_log(current, fs,
+ SVN_ERR(send_log(current, fs, changes,
log_target_history_as_mergeinfo, nested_merges,
discover_changed_paths,
subtractive_merge, handling_merged_revisions,
@@ -2078,8 +2098,8 @@ do_logs(svn_fs_t *fs,
|| apr_hash_count(deleted_mergeinfo) > 0);
}
- SVN_ERR(send_log(current, fs, log_target_history_as_mergeinfo,
- nested_merges,
+ SVN_ERR(send_log(current, fs, NULL,
+ log_target_history_as_mergeinfo, nested_merges,
discover_changed_paths, subtractive_merge,
handling_merged_revisions, revprops, has_children,
receiver, receiver_baton, authz_read_func,
@@ -2302,7 +2322,8 @@ svn_repos_get_logs4(svn_repos_t *repos,
rev = end - i;
else
rev = start + i;
- SVN_ERR(send_log(rev, fs, NULL, NULL, discover_changed_paths, FALSE,
+ SVN_ERR(send_log(rev, fs, NULL, NULL, NULL,
+ discover_changed_paths, FALSE,
FALSE, revprops, FALSE, receiver,
receiver_baton, authz_read_func,
authz_read_baton, iterpool));