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. */