Author: julianfoad
Date: Thu Mar 19 16:13:46 2015
New Revision: 1667800

URL: http://svn.apache.org/r1667800
Log:
On the 'move-tracking-2' branch: More factoring out selection of a subtree.

* subversion/include/private/svn_branch.h,
  subversion/libsvn_delta/branch.c
  (svn_branch_map_get_subtree): New.
  (svn_branch_instantiate_subtree): Was 'svn_branch_map_branch_children'.
    Take the subtree to be instantiated as a parameter instead of copying it
    directly from a given branch.
  (svn_branch_map_purge_orphans): Factor out the core as
    'map_purge_orphans'.
  (copy_content_from): Delete.
  (svn_branch_branch_subtree_r2): Adjust to use svn_branch_instantiate_subtree.
  (svn_branch_branchify,
   svn_branch_copy_subtree_r): Adjust to use svn_branch_map_get_subtree.

Modified:
    subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c

Modified: 
subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h?rev=1667800&r1=1667799&r2=1667800&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h 
(original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h 
Thu Mar 19 16:13:46 2015
@@ -434,6 +434,12 @@ typedef struct svn_branch_subtree_t
   int root_eid;
 } svn_branch_subtree_t;
 
+/* Return the subtree of BRANCH rooted at EID.
+ */
+svn_branch_subtree_t
+svn_branch_map_get_subtree(const svn_branch_instance_t *branch,
+                           int eid,
+                           apr_pool_t *result_pool);
 
 /* Declare that the following function requires/implies that in BRANCH's
  * mapping, for each existing element, the parent also exists.
@@ -499,30 +505,20 @@ void
 svn_branch_purge_r(svn_branch_instance_t *branch,
                    apr_pool_t *scratch_pool);
 
-/* Branch a subtree.
- *
- * For each element that in FROM_BRANCH is a pathwise descendant of
- * FROM_PARENT_EID, excluding FROM_PARENT_EID itself, instantiate the
- * same element in TO_BRANCH. For each element, keep the same parent
- * element (except, for first-level children, change FROM_PARENT_EID to
- * TO_PARENT_EID), name, and content that it had in FROM_BRANCH.
- *
- * ### It's not particularly useful to allow TO_PARENT_EID != FROM_PARENT_EID.
- *
- * FROM_BRANCH and TO_BRANCH must be different branch instances in the
- * same branch family.
+/* Instantiate a subtree.
  *
- * FROM_PARENT_EID MUST be an existing element in FROM_BRANCH. It may be the
- * root element of FROM_BRANCH.
+ * In TO_BRANCH, instantiate (or alter, if existing) each element of
+ * FROM_SUBTREE, keeping their tree structure and content. Set the subtree
+ * root element's parent to NEW_PARENT_EID and name to NEW_NAME.
  *
- * TO_PARENT_EID MUST be an existing element in TO_BRANCH. It may be the
+ * NEW_PARENT_EID MUST be an existing element in TO_BRANCH. It may be the
  * root element of TO_BRANCH.
  */
 svn_error_t *
-svn_branch_map_branch_children(svn_branch_instance_t *from_branch,
-                               int from_parent_eid,
-                               svn_branch_instance_t *to_branch,
-                               int to_parent_eid,
+svn_branch_instantiate_subtree(svn_branch_instance_t *to_branch,
+                               svn_branch_eid_t new_parent_eid,
+                               const char *new_name,
+                               svn_branch_subtree_t from_subtree,
                                apr_pool_t *scratch_pool);
 
 /* Branch a subtree.

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c?rev=1667800&r1=1667799&r2=1667800&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c Thu 
Mar 19 16:13:46 2015
@@ -546,9 +546,24 @@ svn_branch_map_update_as_subbranch_root(
   branch_map_set(branch, eid, node);
 }
 
-void
-svn_branch_map_purge_orphans(svn_branch_instance_t *branch,
-                             apr_pool_t *scratch_pool)
+svn_branch_subtree_t
+svn_branch_map_get_subtree(const svn_branch_instance_t *branch,
+                           int eid,
+                           apr_pool_t *result_pool)
+{
+  svn_branch_subtree_t new_subtree;
+
+  SVN_BRANCH_SEQUENCE_POINT(branch);
+
+  new_subtree.e_map = apr_hash_copy(result_pool, branch->e_map);
+  new_subtree.root_eid = eid;
+  return new_subtree;
+}
+
+static void
+map_purge_orphans(apr_hash_t *e_map,
+                  int root_eid,
+                  apr_pool_t *scratch_pool)
 {
   apr_hash_index_t *hi;
   svn_boolean_t changed;
@@ -557,22 +572,22 @@ svn_branch_map_purge_orphans(svn_branch_
     {
       changed = FALSE;
 
-      for (hi = apr_hash_first(scratch_pool, branch->e_map);
+      for (hi = apr_hash_first(scratch_pool, e_map);
            hi; hi = apr_hash_next(hi))
         {
           int this_eid = svn_int_hash_this_key(hi);
           svn_branch_el_rev_content_t *this_node = apr_hash_this_val(hi);
 
-          if (this_node->parent_eid != -1)
+          if (this_eid != root_eid)
             {
               svn_branch_el_rev_content_t *parent_node
-                = svn_branch_map_get(branch, this_node->parent_eid);
+                = svn_int_hash_get(e_map, this_node->parent_eid);
 
               /* Purge if parent is deleted */
               if (! parent_node)
                 {
                   SVN_DBG(("purge orphan: e%d", this_eid));
-                  svn_branch_map_delete(branch, this_eid);
+                  svn_int_hash_set(e_map, this_eid, NULL);
                   changed = TRUE;
                 }
               else
@@ -584,6 +599,13 @@ svn_branch_map_purge_orphans(svn_branch_
 }
 
 void
+svn_branch_map_purge_orphans(svn_branch_instance_t *branch,
+                             apr_pool_t *scratch_pool)
+{
+  map_purge_orphans(branch->e_map, branch->sibling_defn->root_eid, 
scratch_pool);
+}
+
+void
 svn_branch_purge_r(svn_branch_instance_t *branch,
                    apr_pool_t *scratch_pool)
 {
@@ -713,34 +735,6 @@ svn_branch_get_eid_by_rrpath(svn_branch_
   return eid;
 }
 
-/* Get an element's content (props, text, ...) in full or by reference.
- */
-static svn_error_t *
-copy_content_from(svn_element_content_t **content_p,
-                  svn_branch_instance_t *from_branch,
-                  int from_eid,
-                  apr_pool_t *result_pool,
-                  apr_pool_t *scratch_pool)
-{
-  svn_branch_el_rev_content_t *old_el = svn_branch_map_get(from_branch, 
from_eid);
-  svn_element_content_t *content = old_el->content;
-
-  /* If content is unknown, then presumably this is a committed rev and
-     so we can provide a reference to the committed content. */
-  if (! content)
-    {
-      svn_pathrev_t peg;
-
-      SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(from_branch->rev_root->rev));
-      peg.rev = from_branch->rev_root->rev;
-      peg.relpath = svn_branch_get_rrpath_by_eid(from_branch, from_eid,
-                                                 scratch_pool);
-      content = svn_element_content_create_ref(peg, result_pool);
-    }
-  *content_p = content;
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 svn_branch_map_add_subtree(svn_branch_instance_t *to_branch,
                            int to_eid,
@@ -788,44 +782,39 @@ svn_branch_map_add_subtree(svn_branch_in
 }
 
 svn_error_t *
-svn_branch_map_branch_children(svn_branch_instance_t *from_branch,
-                               int from_parent_eid,
-                               svn_branch_instance_t *to_branch,
-                               int to_parent_eid,
+svn_branch_instantiate_subtree(svn_branch_instance_t *to_branch,
+                               svn_branch_eid_t new_parent_eid,
+                               const char *new_name,
+                               svn_branch_subtree_t new_subtree,
                                apr_pool_t *scratch_pool)
 {
   apr_hash_index_t *hi;
+  svn_branch_el_rev_content_t *new_root_content;
 
-  SVN_ERR_ASSERT(BRANCHES_IN_SAME_FAMILY(from_branch, to_branch));
-  SVN_ERR_ASSERT(from_branch != to_branch);
+  /*SVN_ERR_ASSERT(SAME_FAMILY(to_branch...family, new_subtree...family));*/
 
-  /* The 'from' and 'to' nodes must exist. */
-  SVN_ERR_ASSERT(svn_branch_map_get(from_branch, from_parent_eid));
-  SVN_ERR_ASSERT(svn_branch_map_get(to_branch, to_parent_eid));
+  /* Instantiate the root element of NEW_SUBTREE */
+  new_root_content = svn_int_hash_get(new_subtree.e_map, new_subtree.root_eid);
+  if (new_root_content->content)
+    svn_branch_map_update(to_branch, new_subtree.root_eid,
+                          new_parent_eid, new_name, new_root_content->content);
+  else
+    svn_branch_map_update_as_subbranch_root(to_branch, new_subtree.root_eid,
+                                            new_parent_eid, new_name);
 
-  /* Process the immediate children of FROM_PARENT_EID. */
-  for (hi = apr_hash_first(scratch_pool, from_branch->e_map);
+  /* Instantiate all the children of NEW_SUBTREE */
+  /* ### Writes to NEW_SUBTREE.e_map. No semantic change; just purges orphan
+     elements. Could easily avoid this by duplicating first. */
+  map_purge_orphans(new_subtree.e_map, new_subtree.root_eid, scratch_pool);
+  for (hi = apr_hash_first(scratch_pool, new_subtree.e_map);
        hi; hi = apr_hash_next(hi))
     {
       int this_eid = svn_int_hash_this_key(hi);
-      svn_branch_el_rev_content_t *from_node = svn_branch_map_get(from_branch,
-                                                                  this_eid);
+      svn_branch_el_rev_content_t *this_node = apr_hash_this_val(hi);
 
-      if (from_node->parent_eid == from_parent_eid)
+      if (this_eid != new_subtree.root_eid)
         {
-          svn_element_content_t *this_content;
-
-          SVN_ERR(copy_content_from(&this_content, from_branch, this_eid,
-                                    scratch_pool, scratch_pool));
-          svn_branch_map_update(to_branch, this_eid,
-                                from_node->parent_eid, from_node->name,
-                                this_content);
-
-          /* Recurse. (We don't try to check whether it's a directory node,
-             as we might not have the node kind in the map.) */
-          SVN_ERR(svn_branch_map_branch_children(from_branch, this_eid,
-                                                 to_branch, this_eid,
-                                                 scratch_pool));
+          branch_map_set(to_branch, this_eid, this_node);
         }
     }
 
@@ -1443,10 +1432,10 @@ svn_branch_branch_subtree_r2(svn_branch_
                              svn_branch_sibling_t *new_branch_def,
                              apr_pool_t *scratch_pool)
 {
+  svn_branch_subtree_t from_subtree
+    = svn_branch_map_get_subtree(from_branch, from_eid, scratch_pool);
   svn_branch_instance_t *new_branch;
 
-  /* Source element must exist */
-  SVN_ERR_ASSERT(svn_branch_get_path_by_eid(from_branch, from_eid, 
scratch_pool));
   /* When creating a new branch-sibling in same outer branch, TO_OUTER_BRANCH
      is the parent of FROM_BRANCH. When instantiating the same branch-sibling
      into a different outer-branch, TO_OUTER_BRANCH is in the same family as
@@ -1457,20 +1446,8 @@ svn_branch_branch_subtree_r2(svn_branch_
   new_branch = svn_branch_add_new_branch_instance(to_outer_branch, 
to_outer_eid,
                                                   new_branch_def, 
scratch_pool);
 
-  /* Initialize the new (inner) branch root element */
-  {
-    svn_element_content_t *old_content;
-
-    SVN_ERR(copy_content_from(&old_content,
-                              from_branch, from_eid,
-                              scratch_pool, scratch_pool));
-    svn_branch_map_update(new_branch, new_branch_def->root_eid,
-                      -1, "", old_content);
-  }
-
-  /* Populate the rest of the new branch mapping */
-  SVN_ERR(svn_branch_map_branch_children(from_branch, from_eid,
-                                         new_branch, new_branch_def->root_eid,
+  /* Populate the new branch mapping */
+  SVN_ERR(svn_branch_instantiate_subtree(new_branch, -1, "", from_subtree,
                                          scratch_pool));
 
   /* branch any subbranches under FROM_BRANCH:FROM_EID */
@@ -1478,8 +1455,8 @@ svn_branch_branch_subtree_r2(svn_branch_
     SVN_ITER_T(svn_branch_instance_t) *bi;
 
     for (SVN_ARRAY_ITER(bi, svn_branch_get_subbranches(
-                              from_branch, from_eid, scratch_pool, 
scratch_pool),
-                        scratch_pool))
+                              from_branch, from_subtree.root_eid,
+                              scratch_pool, scratch_pool), scratch_pool))
       {
         svn_branch_instance_t *subbranch = bi->val;
 
@@ -1582,8 +1559,6 @@ svn_branch_branchify(svn_branch_instance
                      svn_branch_eid_t outer_eid,
                      apr_pool_t *scratch_pool)
 {
-  svn_branch_subtree_t new_subtree;
-
   /* Check the element is not already a branch root */
   /* ### TODO: and its subtree does not contain any branch roots. */
   if (IS_BRANCH_ROOT_EID(outer_branch, outer_eid)
@@ -1591,10 +1566,11 @@ svn_branch_branchify(svn_branch_instance
     return svn_error_createf(SVN_ERR_BRANCHING, NULL,
                              _("is already a subbranch root"));
 
-  new_subtree.e_map = outer_branch->e_map;
-  new_subtree.root_eid = outer_eid;
   SVN_ERR(branch_branchify(new_branch_p,
-                           outer_branch, outer_eid, new_subtree, 
scratch_pool));
+                           outer_branch, outer_eid,
+                           svn_branch_map_get_subtree(outer_branch, outer_eid,
+                                                      scratch_pool),
+                           scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -1606,17 +1582,16 @@ svn_branch_copy_subtree_r(const svn_bran
                           apr_pool_t *scratch_pool)
 {
   int to_eid;
-  svn_branch_subtree_t new_subtree;
 
   /* Assign a new EID for the new subtree's root element */
   to_eid = svn_branch_family_add_new_element(to_branch->sibling_defn->family);
 
-  new_subtree.e_map = from_el_rev->branch->e_map;
-  new_subtree.root_eid = from_el_rev->eid;
-
   /* copy the subtree, assigning new EIDs */
   SVN_ERR(svn_branch_map_add_subtree(to_branch, to_eid,
-                                     to_parent_eid, to_name, new_subtree,
+                                     to_parent_eid, to_name,
+                                     svn_branch_map_get_subtree(
+                                       from_el_rev->branch, from_el_rev->eid,
+                                       scratch_pool),
                                      scratch_pool));
 
   /* handle any subbranches under FROM_BRANCH:FROM_EID */


Reply via email to