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 2016/02/14 19:48:03 UTC
svn commit: r1730372 - /subversion/trunk/subversion/libsvn_repos/replay.c
Author: stefan2
Date: Sun Feb 14 18:48:03 2016
New Revision: 1730372
URL: http://svn.apache.org/viewvc?rev=1730372&view=rev
Log:
Some refactoring in the repos layer to eliminate duplicate code.
* subversion/libsvn_repos/replay.c
(get_relevant_changes): New function, factored out from ...
(svn_repos_replay2,
svn_repos__replay_ev2): ... these two.
Modified:
subversion/trunk/subversion/libsvn_repos/replay.c
Modified: subversion/trunk/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/replay.c?rev=1730372&r1=1730371&r2=1730372&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/replay.c (original)
+++ subversion/trunk/subversion/libsvn_repos/replay.c Sun Feb 14 18:48:03 2016
@@ -843,55 +843,49 @@ fetch_props_func(apr_hash_t **props,
-svn_error_t *
-svn_repos_replay2(svn_fs_root_t *root,
- const char *base_path,
- svn_revnum_t low_water_mark,
- svn_boolean_t send_deltas,
- const svn_delta_editor_t *editor,
- void *edit_baton,
- svn_repos_authz_func_t authz_read_func,
- void *authz_read_baton,
- apr_pool_t *pool)
+/* Retrieve the path changes under ROOT, filter them with AUTHZ_READ_FUNC
+ and AUTHZ_READ_BATON and return those that intersect with BASE_RELPATH.
+
+ The svn_fs_path_change2_t* will be returned in *CHANGED_PATHS, keyed by
+ their path. The paths themselves are additionally returned in *PATHS.
+
+ Allocate the returned data in RESULT_POOL and use SCRATCH_POOL for
+ temporary allocations.
+ */
+static svn_error_t *
+get_relevant_changes(apr_hash_t **changed_paths,
+ apr_array_header_t **paths,
+ svn_fs_root_t *root,
+ const char *base_relpath,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
-#ifndef USE_EV2_IMPL
apr_hash_t *fs_changes;
- apr_hash_t *changed_paths;
apr_hash_index_t *hi;
- apr_array_header_t *paths;
- struct path_driver_cb_baton cb_baton;
-
- /* Special-case r0, which we know is an empty revision; if we don't
- special-case it we might end up trying to compare it to "r-1". */
- if (svn_fs_is_revision_root(root) && svn_fs_revision_root_revision(root) == 0)
- {
- SVN_ERR(editor->set_target_revision(edit_baton, 0, pool));
- return SVN_NO_ERROR;
- }
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
/* Fetch the paths changed under ROOT. */
- SVN_ERR(svn_fs_paths_changed2(&fs_changes, root, pool));
-
- if (! base_path)
- base_path = "";
- else if (base_path[0] == '/')
- ++base_path;
+ SVN_ERR(svn_fs_paths_changed2(&fs_changes, root, result_pool));
/* Make an array from the keys of our CHANGED_PATHS hash, and copy
the values into a new hash whose keys have no leading slashes. */
- paths = apr_array_make(pool, apr_hash_count(fs_changes),
- sizeof(const char *));
- changed_paths = apr_hash_make(pool);
- for (hi = apr_hash_first(pool, fs_changes); hi; hi = apr_hash_next(hi))
+ *paths = apr_array_make(result_pool, 16, sizeof(const char *));
+ *changed_paths = apr_hash_make(result_pool);
+ for (hi = apr_hash_first(scratch_pool, fs_changes);
+ hi;
+ hi = apr_hash_next(hi))
{
const char *path = apr_hash_this_key(hi);
apr_ssize_t keylen = apr_hash_this_key_len(hi);
svn_fs_path_change2_t *change = apr_hash_this_val(hi);
svn_boolean_t allowed = TRUE;
+ svn_pool_clear(iterpool);
if (authz_read_func)
SVN_ERR(authz_read_func(&allowed, root, path, authz_read_baton,
- pool));
+ iterpool));
if (allowed)
{
@@ -902,22 +896,56 @@ svn_repos_replay2(svn_fs_root_t *root,
}
/* If the base_path doesn't match the top directory of this path
- we don't want anything to do with it... */
- if (svn_relpath_skip_ancestor(base_path, path) != NULL)
- {
- APR_ARRAY_PUSH(paths, const char *) = path;
- apr_hash_set(changed_paths, path, keylen, change);
- }
- /* ...unless this was a change to one of the parent directories of
+ we don't want anything to do with it...
+ ...unless this was a change to one of the parent directories of
base_path. */
- else if (svn_relpath_skip_ancestor(path, base_path) != NULL)
+ if ( svn_relpath_skip_ancestor(base_relpath, path)
+ || svn_relpath_skip_ancestor(path, base_relpath))
{
- APR_ARRAY_PUSH(paths, const char *) = path;
- apr_hash_set(changed_paths, path, keylen, change);
+ APR_ARRAY_PUSH(*paths, const char *) = path;
+ apr_hash_set(*changed_paths, path, keylen, change);
}
}
}
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_repos_replay2(svn_fs_root_t *root,
+ const char *base_path,
+ svn_revnum_t low_water_mark,
+ svn_boolean_t send_deltas,
+ const svn_delta_editor_t *editor,
+ void *edit_baton,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ apr_pool_t *pool)
+{
+#ifndef USE_EV2_IMPL
+ apr_hash_t *changed_paths;
+ apr_array_header_t *paths;
+ struct path_driver_cb_baton cb_baton;
+
+ /* Special-case r0, which we know is an empty revision; if we don't
+ special-case it we might end up trying to compare it to "r-1". */
+ if (svn_fs_is_revision_root(root) && svn_fs_revision_root_revision(root) == 0)
+ {
+ SVN_ERR(editor->set_target_revision(edit_baton, 0, pool));
+ return SVN_NO_ERROR;
+ }
+
+ if (! base_path)
+ base_path = "";
+ else if (base_path[0] == '/')
+ ++base_path;
+
+ /* Fetch the paths changed under ROOT. */
+ SVN_ERR(get_relevant_changes(&changed_paths, &paths, root, base_path,
+ authz_read_func, authz_read_baton,
+ pool, pool));
+
/* If we were not given a low water mark, assume that everything is there,
all the way back to revision 0. */
if (! SVN_IS_VALID_REVNUM(low_water_mark))
@@ -1485,9 +1513,7 @@ svn_repos__replay_ev2(svn_fs_root_t *roo
void *authz_read_baton,
apr_pool_t *scratch_pool)
{
- apr_hash_t *fs_changes;
apr_hash_t *changed_paths;
- apr_hash_index_t *hi;
apr_array_header_t *paths;
apr_array_header_t *copies;
apr_pool_t *iterpool;
@@ -1505,49 +1531,10 @@ svn_repos__replay_ev2(svn_fs_root_t *roo
}
/* Fetch the paths changed under ROOT. */
- SVN_ERR(svn_fs_paths_changed2(&fs_changes, root, scratch_pool));
-
- /* Make an array from the keys of our CHANGED_PATHS hash, and copy
- the values into a new hash whose keys have no leading slashes. */
- paths = apr_array_make(scratch_pool, apr_hash_count(fs_changes),
- sizeof(const char *));
- changed_paths = apr_hash_make(scratch_pool);
- for (hi = apr_hash_first(scratch_pool, fs_changes); hi;
- hi = apr_hash_next(hi))
- {
- const char *path = apr_hash_this_key(hi);
- apr_ssize_t keylen = apr_hash_this_key_len(hi);
- svn_fs_path_change2_t *change = apr_hash_this_val(hi);
- svn_boolean_t allowed = TRUE;
-
- if (authz_read_func)
- SVN_ERR(authz_read_func(&allowed, root, path, authz_read_baton,
- scratch_pool));
-
- if (allowed)
- {
- if (path[0] == '/')
- {
- path++;
- keylen--;
- }
-
- /* If the base_path doesn't match the top directory of this path
- we don't want anything to do with it... */
- if (svn_relpath_skip_ancestor(base_repos_relpath, path) != NULL)
- {
- APR_ARRAY_PUSH(paths, const char *) = path;
- apr_hash_set(changed_paths, path, keylen, change);
- }
- /* ...unless this was a change to one of the parent directories of
- base_path. */
- else if (svn_relpath_skip_ancestor(path, base_repos_relpath) != NULL)
- {
- APR_ARRAY_PUSH(paths, const char *) = path;
- apr_hash_set(changed_paths, path, keylen, change);
- }
- }
- }
+ SVN_ERR(get_relevant_changes(&changed_paths, &paths, root,
+ base_repos_relpath,
+ authz_read_func, authz_read_baton,
+ scratch_pool, scratch_pool));
/* If we were not given a low water mark, assume that everything is there,
all the way back to revision 0. */