Author: julianfoad
Date: Thu Mar 19 12:34:58 2015
New Revision: 1667725

URL: http://svn.apache.org/r1667725
Log:
On the 'move-tracking-2' branch: Start to factor out selection of a subtree.

* subversion/include/private/svn_branch.h,
  subversion/libsvn_delta/branch.c
  (svn_branch_subtree_t): New.
  (svn_branch_map_add_subtree): Was 'svn_branch_map_copy_children'.
    Take the subtree to be added as a parameter instead of copying it
    directly from a given branch.
  (branch_branchify,
   svn_branch_branchify,
   svn_branch_copy_subtree_r): Adjust to use it.

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=1667725&r1=1667724&r2=1667725&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 12:34:58 2015
@@ -412,6 +412,29 @@ svn_branch_el_rev_content_equal(const sv
                                 apr_pool_t *scratch_pool);
 
 
+/* Describe a subtree of elements.
+ *
+ * A subtree is described by the content of element ROOT_EID in E_MAP,
+ * and its children (as determined by their parent links) and their names
+ * and their content recursively. For the element ROOT_EID itself, only
+ * its content is relevant; its parent and name are to be ignored.
+ *
+ * E_MAP may also contain entries that are not part of the subtree. Thus,
+ * to select a sub-subtree, it is only necessary to change ROOT_EID.
+ *
+ * The EIDs used in here are in effect stand-alone, in their own name-space,
+ * although they may actually be copied from the originating branch family.
+ */
+typedef struct svn_branch_subtree_t
+{
+  /* EID -> svn_branch_el_rev_content_t mapping. */
+  apr_hash_t *e_map;
+
+  /* Subtree root EID. (EID must be an existing key in E_MAP.) */
+  int root_eid;
+} svn_branch_subtree_t;
+
+
 /* Declare that the following function requires/implies that in BRANCH's
  * mapping, for each existing element, the parent also exists.
  *
@@ -538,31 +561,19 @@ svn_branch_branch_subtree_r2(svn_branch_
                              svn_branch_sibling_t *new_branch_def,
                              apr_pool_t *scratch_pool);
 
-/* Copy a subtree.
- *
- * For each element that in FROM_BRANCH is a pathwise descendant of
- * FROM_PARENT_EID, excluding FROM_PARENT_EID itself, instantiate a
- * new 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.
+/* Create a copy of NEW_SUBTREE at TO_BRANCH:TO_EID, generating new elements
+ * for all elements in NEW_SUBTREE except the root. Set the root element's
+ * parent to NEW_PARENT_EID and name to NEW_NAME.
  *
- * Assign a new EID in TO_BRANCH's family for each copied element.
- *
- * FROM_BRANCH and TO_BRANCH may be the same or different branch instances
- * in the same or different branch families.
- *
- * FROM_PARENT_EID MUST be an existing element in FROM_BRANCH. It may be the
- * root element of FROM_BRANCH.
- *
- * TO_PARENT_EID MUST be an existing element in TO_BRANCH. It may be the
- * root element of TO_BRANCH.
+ * Alter the 'to' element if it already exists, otherwise instantiate it.
  */
 svn_error_t *
-svn_branch_map_copy_children(svn_branch_instance_t *from_branch,
-                             int from_parent_eid,
-                             svn_branch_instance_t *to_branch,
-                             int to_parent_eid,
-                             apr_pool_t *scratch_pool);
+svn_branch_map_add_subtree(svn_branch_instance_t *to_branch,
+                           int to_eid,
+                           svn_branch_eid_t new_parent_eid,
+                           const char *new_name,
+                           svn_branch_subtree_t new_subtree,
+                           apr_pool_t *scratch_pool);
 
 /* Copy 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=1667725&r1=1667724&r2=1667725&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 12:34:58 2015
@@ -742,39 +742,45 @@ copy_content_from(svn_element_content_t
 }
 
 svn_error_t *
-svn_branch_map_copy_children(svn_branch_instance_t *from_branch,
-                             int from_parent_eid,
-                             svn_branch_instance_t *to_branch,
-                             int to_parent_eid,
-                             apr_pool_t *scratch_pool)
+svn_branch_map_add_subtree(svn_branch_instance_t *to_branch,
+                           int to_eid,
+                           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;
 
-  /* 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));
+  /* Create the new subtree root element */
+  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, to_eid,
+                          new_parent_eid, new_name, new_root_content->content);
+  else
+    svn_branch_map_update_as_subbranch_root(to_branch, to_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);
+  /* Process its immediate children */
+  for (hi = apr_hash_first(scratch_pool, new_subtree.e_map);
        hi; hi = apr_hash_next(hi))
     {
       int this_from_eid = svn_int_hash_this_key(hi);
       svn_branch_el_rev_content_t *from_node = apr_hash_this_val(hi);
 
-      if (from_node->parent_eid == from_parent_eid)
+      if (from_node->parent_eid == new_subtree.root_eid)
         {
           int new_eid
             = 
svn_branch_family_add_new_element(to_branch->sibling_defn->family);
-
-          svn_branch_map_update(to_branch, new_eid,
-                            to_parent_eid, from_node->name,
-                            from_node->content);
+          svn_branch_subtree_t this_subtree;
 
           /* 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_copy_children(from_branch, this_from_eid,
-                                               to_branch, new_eid,
-                                               scratch_pool));
+          this_subtree.e_map = new_subtree.e_map;
+          this_subtree.root_eid = this_from_eid;
+          SVN_ERR(svn_branch_map_add_subtree(to_branch, new_eid,
+                                             to_eid, from_node->name,
+                                             this_subtree, scratch_pool));
         }
     }
 
@@ -1527,7 +1533,8 @@ get_family(svn_branch_family_t *outer_fa
 static svn_error_t *
 branch_branchify(svn_branch_instance_t **new_branch_p,
                  svn_branch_instance_t *outer_branch,
-                 svn_branch_eid_t outer_eid,
+                 svn_branch_eid_t old_outer_eid,
+                 svn_branch_subtree_t new_subtree,
                  apr_pool_t *scratch_pool)
 {
   svn_branch_family_t *new_family
@@ -1545,23 +1552,19 @@ branch_branchify(svn_branch_instance_t *
   svn_branch_el_rev_content_t *old_content;
 
   SVN_DBG(("branchify(b%d e%d at ^/%s): new f%d b%d e%d",
-           outer_branch->sibling_defn->bsid, outer_eid,
-           svn_branch_get_rrpath_by_eid(outer_branch, outer_eid, scratch_pool),
+           outer_branch->sibling_defn->bsid, old_outer_eid,
+           svn_branch_get_rrpath_by_eid(outer_branch, old_outer_eid, 
scratch_pool),
            new_family->fid, new_branch_def->bsid, new_branch_def->root_eid));
 
-  /* create the new root element */
-  old_content = svn_branch_map_get(outer_branch, outer_eid);
-  svn_branch_map_update(new_branch, new_branch_def->root_eid,
-                        -1, "", old_content->content);
-
-  /* copy all the children into the new branch, assigning new EIDs */
-  SVN_ERR(svn_branch_map_copy_children(outer_branch, outer_eid,
-                                       new_branch, new_branch_def->root_eid,
-                                       scratch_pool));
+  old_content = svn_branch_map_get(outer_branch, old_outer_eid);
+
+  /* copy the subtree into the new branch, assigning new EIDs */
+  SVN_ERR(svn_branch_map_add_subtree(new_branch, new_branch_def->root_eid,
+                                     -1, "", new_subtree, scratch_pool));
 
   /* delete the old subtree-root element (which implicitly deletes all its
      children from the old branch, if nothing further touches them) */
-  svn_branch_map_delete(outer_branch, outer_eid);
+  svn_branch_map_delete(outer_branch, old_outer_eid);
 
   /* replace the old subtree-root element with a new subbranch-root element */
   svn_branch_map_update_as_subbranch_root(outer_branch, new_outer_eid,
@@ -1579,6 +1582,8 @@ 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)
@@ -1586,8 +1591,10 @@ 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, scratch_pool));
+                           outer_branch, outer_eid, new_subtree, 
scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -1599,27 +1606,24 @@ svn_branch_copy_subtree_r(const svn_bran
                           apr_pool_t *scratch_pool)
 {
   int to_eid;
-  svn_branch_el_rev_content_t *old_content;
+  svn_branch_subtree_t new_subtree;
 
-  /* Copy the root element */
+  /* Assign a new EID for the new subtree's root element */
   to_eid = svn_branch_family_add_new_element(to_branch->sibling_defn->family);
-  old_content = svn_branch_map_get(from_el_rev->branch, from_el_rev->eid);
 
-  /* ### If this element is a subbranch root, need to call
-         branch_map_update_as_subbranch_root() instead. */
-  svn_branch_map_update(to_branch, to_eid,
-                        to_parent_eid, to_name, old_content->content);
-
-  /* Copy the children within this branch */
-  SVN_ERR(svn_branch_map_copy_children(from_el_rev->branch, from_el_rev->eid,
-                                       to_branch, to_eid,
-                                       scratch_pool));
+  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,
+                                     scratch_pool));
 
   /* handle any subbranches under FROM_BRANCH:FROM_EID */
   /* ### Later. */
 
-  SVN_DBG(("cp subtree from e%d (%d/%s) to e%d (%d/%s)",
-           from_el_rev->eid, old_content->parent_eid, old_content->name,
+  SVN_DBG(("cp subtree from e%d to e%d (%d/%s)",
+           from_el_rev->eid,
            to_eid, to_parent_eid, to_name));
   return SVN_NO_ERROR;
 }


Reply via email to