You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/09/29 17:30:17 UTC

svn commit: r1705877 - in /subversion/branches/move-tracking-2/subversion: include/private/svn_branch.h libsvn_delta/branch.c libsvn_delta/compat3e.c libsvn_delta/editor3e.c libsvn_delta/element.c svnmover/svnmover.c

Author: julianfoad
Date: Tue Sep 29 15:30:16 2015
New Revision: 1705877

URL: http://svn.apache.org/viewvc?rev=1705877&view=rev
Log:
On the 'move-tracking-2' branch: Keep track of new EIDs assigned with a
transaction, and only convert them to permanent EIDs at commit time.

This allows us to add elements in a txn based on an old revision, and then
'update' the txn to be based on a newer revision, and the EIDs added in the
newer revision will not clash with the EIDs added in the txn. (This 'update'
could be either a client-side WC update or the automatic rebase-on-commit.)

* BRANCH-README
  Update: remove this TODO.

* subversion/libsvn_delta/editor3e.c
  (VALID_EID): Adjust for local EIDs being negative.

* subversion/include/private/svn_branch.h,
  subversion/libsvn_delta/branch.c
  (svn_branch_revision_root_t): Document that 'first_eid' holds less than
    zero for transaction-local EIDs.
  (svn_branch_txn_new_eid): Rename from 'svn_branch_revision_root_new_eid'.
    Allocate negative EIDs instead of positive EIDs.
  (branch_finalize_eids,
   svn_branch_txn_finalize_eids): New.
  (svn_branch_map_add_subtree): Track the rename.

* subversion/libsvn_delta/compat3e.c
  (editor3_new_eid): Track the rename.
  (editor3_alter): Track the rename. Adjust for local EIDs being negative.
  (editor3_complete): Finalize the txn EIDs before committing.

* subversion/libsvn_delta/element.c
  (svn_element_payload_invariants): Adjust for local EIDs being negative.

* subversion/svnmover/svnmover.c
  (do_branch): Track the rename.

Modified:
    subversion/branches/move-tracking-2/subversion/include/private/svn_branch.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/element.c
    subversion/branches/move-tracking-2/subversion/svnmover/svnmover.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=1705877&r1=1705876&r2=1705877&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 Tue Sep 29 15:30:16 2015
@@ -137,6 +137,8 @@ typedef struct svn_branch_revision_root_
   svn_revnum_t base_rev;
 
   /* The range of element ids assigned. */
+  /* EIDs local to the txn are negative, assigned by decrementing FIRST_EID
+   * (skipping -1). */
   int first_eid, next_eid;
 
   /* The root branches, indexed by top-level branch id (0...N). */
@@ -188,10 +190,19 @@ svn_branch_revision_root_get_branch_by_i
                                           const char *branch_id,
                                           apr_pool_t *scratch_pool);
 
-/* Assign a new element id in REV_ROOT.
+/* Assign a new txn-scope element id in REV_ROOT.
  */
 int
-svn_branch_revision_root_new_eid(svn_branch_revision_root_t *rev_root);
+svn_branch_txn_new_eid(svn_branch_revision_root_t *rev_root);
+
+/* Change txn-local EIDs (negative integers) in TXN to revision EIDs, by
+ * assigning a new revision-EID (positive integer) for each one.
+ *
+ * Rewrite TXN->first_eid and TXN->next_eid accordingly.
+ */
+svn_error_t *
+svn_branch_txn_finalize_eids(svn_branch_revision_root_t *txn,
+                             apr_pool_t *scratch_pool);
 
 /* Often, branches have the same root element. For example,
  * branching /trunk to /branches/br1 results in:

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=1705877&r1=1705876&r2=1705877&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c Tue Sep 29 15:30:16 2015
@@ -72,13 +72,83 @@ svn_branch_revision_root_create(svn_bran
 }
 
 int
-svn_branch_revision_root_new_eid(svn_branch_revision_root_t *rev_root)
+svn_branch_txn_new_eid(svn_branch_revision_root_t *rev_root)
 {
-  int eid = rev_root->next_eid++;
+  int eid = (rev_root->first_eid < 0) ? rev_root->first_eid - 1 : -2;
 
+  rev_root->first_eid = eid;
   return eid;
 }
 
+/* Change txn-local EIDs (negative integers) in BRANCH to revision EIDs, by
+ * assigning a new revision-EID (positive integer) for each one.
+ */
+static svn_error_t *
+branch_finalize_eids(svn_branch_state_t *branch,
+                     int mapping_offset,
+                     apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *hi;
+
+  if (branch->root_eid < -1)
+    {
+      branch->root_eid = mapping_offset - branch->root_eid;
+    }
+
+  if (branch->outer_eid < -1)
+    {
+      branch->outer_eid = mapping_offset - branch->outer_eid;
+    }
+
+  for (hi = apr_hash_first(scratch_pool, branch->e_map);
+       hi; hi = apr_hash_next(hi))
+    {
+      int old_eid = svn_int_hash_this_key(hi);
+      svn_branch_el_rev_content_t *element = apr_hash_this_val(hi);
+
+      if (old_eid < -1)
+        {
+          int new_eid = mapping_offset - old_eid;
+
+          svn_int_hash_set(branch->e_map, old_eid, NULL);
+          svn_int_hash_set(branch->e_map, new_eid, element);
+        }
+      if (element->parent_eid < -1)
+        {
+          element->parent_eid = mapping_offset - element->parent_eid;
+        }
+    }
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_branch_txn_finalize_eids(svn_branch_revision_root_t *txn,
+                             apr_pool_t *scratch_pool)
+{
+  int n_txn_eids = (-1) - txn->first_eid;
+  int mapping_offset;
+  int i;
+
+  if (txn->first_eid == 0)
+    return SVN_NO_ERROR;
+
+  /* mapping from txn-local (negative) EID to committed (positive) EID is:
+       txn_local_eid == -2  =>  committed_eid := (txn.next_eid + 0)
+       txn_local_eid == -3  =>  committed_eid := (txn.next_eid + 1) ... */
+  mapping_offset = txn->next_eid - 2;
+
+  for (i = 0; i < txn->branches->nelts; i++)
+    {
+      svn_branch_state_t *b = APR_ARRAY_IDX(txn->branches, i, void *);
+
+      SVN_ERR(branch_finalize_eids(b, mapping_offset, scratch_pool));
+    }
+
+  txn->next_eid += n_txn_eids;
+  txn->first_eid = 0;
+  return SVN_NO_ERROR;
+}
+
 svn_branch_state_t *
 svn_branch_revision_root_get_root_branch(svn_branch_revision_root_t *rev_root,
                                          int top_branch_num)
@@ -688,7 +758,7 @@ svn_branch_map_add_subtree(svn_branch_st
   /* Get a new EID for the root element, if not given. */
   if (to_eid == -1)
     {
-      to_eid = svn_branch_revision_root_new_eid(to_branch->rev_root);
+      to_eid = svn_branch_txn_new_eid(to_branch->rev_root);
     }
 
   /* Create the new subtree root element */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c?rev=1705877&r1=1705876&r2=1705877&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c Tue Sep 29 15:30:16 2015
@@ -1143,7 +1143,7 @@ editor3_new_eid(void *baton,
                 apr_pool_t *scratch_pool)
 {
   ev3_from_delta_baton_t *eb = baton;
-  int eid = svn_branch_revision_root_new_eid(eb->edited_rev_root);
+  int eid = svn_branch_txn_new_eid(eb->edited_rev_root);
 
   *eid_p = eid;
   return SVN_NO_ERROR;
@@ -1201,9 +1201,9 @@ editor3_alter(void *baton,
   /* ### Ensure the requested EIDs are allocated... This is not the
          right way to do it. Instead the Editor should map 'to be
          created' EIDs to new EIDs? See BRANCH-README. */
-  while (eid >= eb->edited_rev_root->next_eid
-         || (new_parent_eid >= eb->edited_rev_root->next_eid))
-    svn_branch_revision_root_new_eid(eb->edited_rev_root);
+  while (eid < eb->edited_rev_root->first_eid
+         || (new_parent_eid < eb->edited_rev_root->first_eid))
+    svn_branch_txn_new_eid(eb->edited_rev_root);
 
   if (new_payload)
     {
@@ -1869,7 +1869,9 @@ editor3_complete(void *baton,
   ev3_from_delta_baton_t *eb = baton;
   svn_error_t *err;
 
+  /* Convert the transaction to a revision */
   SVN_ERR(editor3_sequence_point(baton, scratch_pool));
+  SVN_ERR(svn_branch_txn_finalize_eids(eb->edited_rev_root, scratch_pool));
 
   err = drive_changes(eb, scratch_pool);
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c?rev=1705877&r1=1705876&r2=1705877&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3e.c Tue Sep 29 15:30:16 2015
@@ -172,7 +172,7 @@ check_cancel(svn_editor3_t *editor)
  */
 
 #define VALID_NODE_KIND(kind) ((kind) != svn_node_unknown && (kind) != svn_node_none)
-#define VALID_EID(eid) ((eid) >= 0)
+#define VALID_EID(eid) ((eid) != -1)
 #define VALID_NAME(name) ((name) && (name)[0] && svn_relpath_is_canonical(name))
 #define VALID_PAYLOAD(payload) svn_element_payload_invariants(payload)
 #define VALID_EL_REV_ID(el_rev) (el_rev && el_rev->branch && VALID_EID(el_rev->eid))

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/element.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/element.c?rev=1705877&r1=1705876&r2=1705877&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/element.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/element.c Tue Sep 29 15:30:16 2015
@@ -76,7 +76,7 @@ svn_element_payload_invariants(const svn
   if (payload->kind == svn_node_unknown)
     if (SVN_IS_VALID_REVNUM(payload->branch_ref.rev)
         && payload->branch_ref.branch_id
-        && payload->branch_ref.eid >= 0)
+        && payload->branch_ref.eid != -1)
       return TRUE;
   if ((payload->kind == svn_node_dir
        || payload->kind == svn_node_file

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=1705877&r1=1705876&r2=1705877&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Tue Sep 29 15:30:16 2015
@@ -2354,7 +2354,7 @@ do_branch(svn_branch_state_t **new_branc
 
   /* assign new eid to root element (outer branch) */
   to_outer_eid
-    = svn_branch_revision_root_new_eid(to_outer_branch->rev_root);
+    = svn_branch_txn_new_eid(to_outer_branch->rev_root);
   svn_branch_update_subbranch_root_element(to_outer_branch, to_outer_eid,
                                            to_outer_parent_eid, new_name);