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