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;
}