Author: julianfoad
Date: Fri Feb 27 11:51:01 2015
New Revision: 1662667
URL: http://svn.apache.org/r1662667
Log:
On the 'move-tracking-2' branch: Start implementing sequence points in the
editor, and use them to fix the deletion problem encountered in r1662505.
* subversion/include/private/svn_editor3.h
(svn_editor3_sequence_point,
svn_editor3_cb_sequence_point_t): New.
(svn_editor3_cb_funcs_t): Add the 'sequence_point' method.
(svn_branch_purge_r): New.
* subversion/libsvn_delta/branching.c
(svn_branch_map_purge_orphans): Harden a condition: a subbranch-root
element must never have content.
(svn_branch_purge_r): New.
(svn_branch_get_all_sub_branches): Rewrite so it doesn't rely on
path-based queries and so doesn't require a sequence point.
* subversion/libsvn_delta/compat3b.c
(editor3_delete): Don't try to delete subbranches, and so don't require a
sequence point.
(convert_branch_to_paths): No longer 'purge orphan elements' here, as we
now reach a sequence point at a higher level.
(editor3_sequence_point): New method.
(editor3_complete): Also apply a sequence point here.
(svn_delta__ev3_from_delta_for_commit2): Add the new method in the vtable.
* subversion/libsvn_delta/compat3.c
(svn_delta__ev3_from_delta_for_commit): Add a null entry in the vtable.
* subversion/libsvn_delta/editor3.c
(svn_editor3_sequence_point,
wrap_sequence_point): New functions.
(svn_editor3__get_debug_editor): Add the new method in the vtable.
* subversion/svnmover/svnmover.c
(branch_merge_subtree_r,
do_move): Update comments.
(execute): Apply a sequence point at the beginning of each iteration.
Modified:
subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h
subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c
subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3.c
subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c
subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c
subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
Modified:
subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h?rev=1662667&r1=1662666&r2=1662667&view=diff
==============================================================================
---
subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h
(original)
+++
subversion/branches/move-tracking-2/subversion/include/private/svn_editor3.h
Fri Feb 27 11:51:01 2015
@@ -1143,6 +1143,22 @@ svn_editor3_alter(svn_editor3_t *editor,
const char *new_name,
const svn_editor3_node_content_t *new_content);
+/** Register a sequence point.
+ *
+ * At a sequence point, elements are arranged in a tree hierarchy: each
+ * element has exactly one parent element, except the root, and so on.
+ * Translation between paths and element addressing is defined only at
+ * a sequence point.
+ *
+ * The other edit operations -- add, alter, delete, etc. -- result in a
+ * state that is not a sequence point.
+ *
+ * The beginning of an edit is a sequence point. Completion of an edit
+ * (svn_editor3_complete()) creates a sequence point.
+ */
+svn_error_t *
+svn_editor3_sequence_point(svn_editor3_t *editor);
+
/** Drive @a editor's #svn_editor3_cb_complete_t callback.
*
* Send word that the edit has been completed successfully.
@@ -1312,6 +1328,12 @@ typedef svn_error_t *(*svn_editor3_cb_al
const svn_editor3_node_content_t *new_content,
apr_pool_t *scratch_pool);
+/** @see svn_editor3_sequence_point(), #svn_editor3_t
+ */
+typedef svn_error_t *(*svn_editor3_cb_sequence_point_t)(
+ void *baton,
+ apr_pool_t *scratch_pool);
+
/** @see svn_editor3_complete(), #svn_editor3_t
*/
typedef svn_error_t *(*svn_editor3_cb_complete_t)(
@@ -1357,6 +1379,7 @@ typedef struct svn_editor3_cb_funcs_t
svn_editor3_cb_delete_t cb_delete;
svn_editor3_cb_alter_t cb_alter;
+ svn_editor3_cb_sequence_point_t cb_sequence_point;
svn_editor3_cb_complete_t cb_complete;
svn_editor3_cb_abort_t cb_abort;
@@ -1922,6 +1945,12 @@ void
svn_branch_map_purge_orphans(svn_branch_instance_t *branch,
apr_pool_t *scratch_pool);
+/* Purge orphaned elements and subbranches.
+ */
+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
Modified:
subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c?rev=1662667&r1=1662666&r2=1662667&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branching.c Fri
Feb 27 11:51:01 2015
@@ -513,19 +513,48 @@ svn_branch_map_purge_orphans(svn_branch_
svn_branch_el_rev_content_t *parent_node
= svn_branch_map_get(branch, this_node->parent_eid);
- /* Purge if parent is deleted or is a subbranch-root node */
- if (! parent_node || ! parent_node->content)
+ /* Purge if parent is deleted */
+ if (! parent_node)
{
SVN_DBG(("purge orphan: e%d", this_eid));
svn_branch_map_delete(branch, this_eid);
changed = TRUE;
}
+ else
+ SVN_ERR_ASSERT_NO_RETURN(parent_node->content);
}
}
}
while (changed);
}
+void
+svn_branch_purge_r(svn_branch_instance_t *branch,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *subbranches
+ = svn_branch_get_all_sub_branches(branch, scratch_pool, scratch_pool);
+ int i;
+
+ /* first, remove elements that have no parent element */
+ svn_branch_map_purge_orphans(branch, scratch_pool);
+
+ /* second, remove subbranches that have no subbranch-root element */
+ for (i = 0; i < subbranches->nelts; i++)
+ {
+ svn_branch_instance_t *b = APR_ARRAY_IDX(subbranches, i, void *);
+
+ if (svn_branch_map_get(branch, b->outer_eid))
+ {
+ svn_branch_purge_r(b, scratch_pool);
+ }
+ else
+ {
+ svn_branch_delete_branch_instance_r(b, scratch_pool);
+ }
+ }
+}
+
const char *
svn_branch_get_root_rrpath(const svn_branch_instance_t *branch,
apr_pool_t *result_pool)
@@ -797,8 +826,22 @@ svn_branch_get_all_sub_branches(const sv
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- return svn_branch_get_subbranches(branch, branch->sibling_defn->root_eid,
- result_pool, scratch_pool);
+ apr_array_header_t *subbranches = apr_array_make(result_pool, 0,
+ sizeof(void *));
+ int i;
+
+ for (i = 0; i < branch->rev_root->branch_instances->nelts; i++)
+ {
+ svn_branch_instance_t *b
+ = APR_ARRAY_IDX(branch->rev_root->branch_instances, i, void *);
+
+ /* Is it an immediate child? */
+ if (b->outer_branch == branch)
+ {
+ APR_ARRAY_PUSH(subbranches, void *) = b;
+ }
+ }
+ return subbranches;
}
svn_branch_instance_t *
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3.c?rev=1662667&r1=1662666&r2=1662667&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3.c
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3.c Fri
Feb 27 11:51:01 2015
@@ -2488,6 +2488,7 @@ svn_delta__ev3_from_delta_for_commit(
editor3_rm,
editor3_put,
NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL,
editor3_complete,
editor3_abort
};
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c?rev=1662667&r1=1662666&r2=1662667&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3b.c Fri
Feb 27 11:51:01 2015
@@ -1041,25 +1041,9 @@ editor3_delete(void *baton,
svn_editor3_eid_t eid,
apr_pool_t *scratch_pool)
{
- apr_array_header_t *subbranches;
- int i;
-
SVN_DBG(("delete(b%d e%d)",
branch->sibling_defn->bid, eid));
- /* Delete nested branches. ### Shouldn't GC/purge-orphans take care of it? */
- subbranches = svn_branch_get_subbranches(branch, eid,
- scratch_pool, scratch_pool);
- for (i = 0; i < subbranches->nelts; i++)
- {
- svn_branch_instance_t *b = APR_ARRAY_IDX(subbranches, i, void *);
-
- SVN_DBG(("delete subbranch-tree (b%d) found at outer e%d",
- b->sibling_defn->bid, b->outer_eid));
- svn_branch_delete_branch_instance_r(b, scratch_pool);
- }
-
- /* Delete the specified element */
svn_branch_map_delete(branch, eid /* ### , since_rev? */);
return SVN_NO_ERROR;
@@ -1104,7 +1088,8 @@ convert_branch_to_paths(apr_hash_t *path
{
apr_hash_index_t *hi;
- svn_branch_map_purge_orphans(branch, scratch_pool);
+ /* assert(branch is at a sequence point); */
+
for (hi = apr_hash_first(scratch_pool, branch->e_map);
hi; hi = apr_hash_next(hi))
{
@@ -1571,12 +1556,25 @@ drive_changes_branch(ev3_from_delta_bato
/* An #svn_editor3_t method. */
static svn_error_t *
+editor3_sequence_point(void *baton,
+ apr_pool_t *scratch_pool)
+{
+ ev3_from_delta_baton_t *eb = baton;
+
+ svn_branch_purge_r(eb->edited_rev_root->root_branch, scratch_pool);
+ return SVN_NO_ERROR;
+}
+
+/* An #svn_editor3_t method. */
+static svn_error_t *
editor3_complete(void *baton,
apr_pool_t *scratch_pool)
{
ev3_from_delta_baton_t *eb = baton;
svn_error_t *err;
+ editor3_sequence_point(baton, scratch_pool);
+
/* Drive the tree we've created. */
err = drive_changes_branch(eb, scratch_pool);
if (!err)
@@ -1651,6 +1649,7 @@ svn_delta__ev3_from_delta_for_commit2(
editor3_copy_tree,
editor3_delete,
editor3_alter,
+ editor3_sequence_point,
editor3_complete,
editor3_abort
};
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c?rev=1662667&r1=1662666&r2=1662667&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c Fri
Feb 27 11:51:01 2015
@@ -416,6 +416,17 @@ svn_editor3_alter(svn_editor3_t *editor,
}
svn_error_t *
+svn_editor3_sequence_point(svn_editor3_t *editor)
+{
+ SHOULD_NOT_BE_FINISHED(editor);
+
+ DO_CALLBACK(editor, cb_sequence_point,
+ 0());
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_editor3_complete(svn_editor3_t *editor)
{
SHOULD_NOT_BE_FINISHED(editor);
@@ -911,6 +922,17 @@ wrap_alter(void *baton,
}
static svn_error_t *
+wrap_sequence_point(void *baton,
+ apr_pool_t *scratch_pool)
+{
+ wrapper_baton_t *eb = baton;
+
+ dbg(eb, scratch_pool, "sequence_point()");
+ SVN_ERR(svn_editor3_sequence_point(eb->wrapped_editor));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
wrap_complete(void *baton,
apr_pool_t *scratch_pool)
{
@@ -952,6 +974,7 @@ svn_editor3__get_debug_editor(svn_editor
wrap_copy_tree,
wrap_delete,
wrap_alter,
+ wrap_sequence_point,
wrap_complete,
wrap_abort
};
Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL:
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1662667&r1=1662666&r2=1662667&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
(original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Fri Feb
27 11:51:01 2015
@@ -697,8 +697,6 @@ branch_merge_subtree_r(svn_editor3_t *ed
else if (e_tgt)
{
notify("D <e%d> %s", eid, e_yca->name);
- /* ### Currently svn_editor3_delete() finds & deletes nested branches
- which is wrong here: we're working on a transient state */
SVN_ERR(svn_editor3_delete(editor, tgt->rev, tgt->branch, eid));
}
else if (result)
@@ -1188,14 +1186,13 @@ do_move(svn_editor3_t *editor,
editor, el_rev->branch, el_rev->eid,
scratch_pool, scratch_pool));
SVN_ERR_ASSERT(old_node);
- /* ### Currently svn_editor3_delete() finds & deletes nested
branches.
- We need to move them too. */
SVN_ERR(svn_editor3_delete(editor, el_rev->rev,
el_rev->branch, el_rev->eid));
SVN_ERR(svn_editor3_instantiate(editor,
to_parent_el_rev->branch,
el_rev->eid,
to_parent_el_rev->eid, to_name,
old_node->content));
+ /* ### We need to move nested branches too. */
return SVN_NO_ERROR;
}
}
@@ -1422,6 +1419,9 @@ execute(const apr_array_header_t *action
svn_pool_clear(iterpool);
+ /* Before translating paths to/from elements, need a sequence point */
+ svn_editor3_sequence_point(editor);
+
for (j = 0; j < 3; j++)
{
if (action->relpath[j])
@@ -1619,8 +1619,6 @@ execute(const apr_array_header_t *action
branch = el_rev[0]->branch->outer_branch;
}
- /* ### Currently svn_editor3_delete() finds & deletes nested
- branches, which is what we want in this case. */
SVN_ERR(svn_editor3_delete(editor, el_rev[0]->rev,
branch, eid));
}