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


Reply via email to