Author: julianfoad
Date: Tue Dec 22 14:25:51 2009
New Revision: 893179

URL: http://svn.apache.org/viewvc?rev=893179&view=rev
Log:
For obliterate in BDB, change the way we update the "copies" table.

Instead of updating it at oblit-begin time, update it at oblit-commit time,
which is not necessarily correct but at least ensures no user-visible
changes are made until oblit-commit time, which is a step closer to
correctness.

* subversion/libsvn_fs_base/revs-txns.c
  (copy_dup): Removed.
  (txn_body_begin_obliteration_txn): Instead of updating the "copies" table,
    just refer to the existing rows in it, even though they do not refer
    back to this txn.

* subversion/libsvn_fs_base/dag.c
  (svn_fs_base__dag_commit_obliteration_txn): Update the "copies" table to
    refer to the new txn.

Modified:
    subversion/trunk/subversion/libsvn_fs_base/dag.c
    subversion/trunk/subversion/libsvn_fs_base/revs-txns.c

Modified: subversion/trunk/subversion/libsvn_fs_base/dag.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/dag.c?rev=893179&r1=893178&r2=893179&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_base/dag.c (original)
+++ subversion/trunk/subversion/libsvn_fs_base/dag.c Tue Dec 22 14:25:51 2009
@@ -1631,8 +1631,61 @@
                                          trail_t *trail,
                                          apr_pool_t *pool)
 {
+  transaction_t *txn_obj;
   revision_t revision;
 
+  /* Read the txn so we can access its "copies" list */
+  SVN_ERR(svn_fs_bdb__get_txn(&txn_obj, trail->fs, txn->id, trail,
+                              trail->pool));
+
+  /* Finish updating the "copies" table, which was started in
+   * svn_fs_base__begin_obliteration_txn().  Change the keys of all the
+   * "copies" table rows that we created back to their original keys.
+   *
+   * This assumes that the old 'replacing_rev' transaction is now obsolete,
+   * so that the old "copies" table rows are no longer referenced.
+   *
+   * ### TODO: See txn_body_begin_obliteration_txn().
+   * ### TODO: Guarantee the old txn is obsolete.
+   */
+  if (txn_obj->copies)
+    {
+      int i;
+
+      for (i = 0; i < txn_obj->copies->nelts; i++)
+        {
+          const char *txn_copy_id = APR_ARRAY_IDX(txn_obj->copies, i,
+                                                  const char *);
+          const char *final_copy_id;
+          copy_t *copy;
+          const char *id_node_id, *id_copy_id, *id_txn_id;
+
+          /* Get the old copy */
+          SVN_ERR(svn_fs_bdb__get_copy(&copy, trail->fs, txn_copy_id, trail,
+                                       pool));
+
+          /* Modify it: change dst_noderev_id's txn_id to the new txn's id */
+          id_node_id = svn_fs_base__id_node_id(copy->dst_noderev_id);
+          id_copy_id = svn_fs_base__id_copy_id(copy->dst_noderev_id);
+          id_txn_id = svn_fs_base__id_txn_id(copy->dst_noderev_id);
+          /* SVN_ERR_ASSERT(svn_fs_base__key_compare(id_copy_id, old_copy_id)
+                            == 0); */
+          /* SVN_ERR_ASSERT(svn_fs_base__key_compare(id_txn_id, old_txn_id)
+                            == 0); */
+          copy->dst_noderev_id = svn_fs_base__id_create(id_node_id,
+                                                        id_copy_id,
+                                                        txn->id,
+                                                        pool);
+
+          /* Save the new copy */
+          final_copy_id = id_copy_id;
+          SVN_ERR(svn_fs_bdb__create_copy(trail->fs, final_copy_id,
+                                          copy->src_path, copy->src_txn_id,
+                                          copy->dst_noderev_id, copy->kind,
+                                          trail, pool));
+        }
+    }
+
   /* Replace the revision entry in the `revisions' table. */
   revision.txn_id = txn->id;
   SVN_ERR(svn_fs_bdb__put_rev(&replacing_rev, txn->fs, &revision, trail, 
pool));

Modified: subversion/trunk/subversion/libsvn_fs_base/revs-txns.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/revs-txns.c?rev=893179&r1=893178&r2=893179&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/trunk/subversion/libsvn_fs_base/revs-txns.c Tue Dec 22 14:25:51 
2009
@@ -434,45 +434,6 @@
 }
 
 
-/* Create a new row in the "copies" table that is a deep copy of the row
- * keyed by OLD_COPY_ID. Assume that the txn-id component of its
- * 'dst_noderev_id' field is OLD_TXN_ID, and change that to NEW_TXN_ID.
- * Set *NEW_COPY_ID to the key of the new row.
- * Work in TRAIL and allocate *NEW_COPY_ID in TRAIL->POOL. */
-static svn_error_t *
-copy_dup(const char **new_copy_id,
-         const char *old_copy_id,
-         const char *new_txn_id,
-         const char *old_txn_id,
-         trail_t *trail,
-         apr_pool_t *scratch_pool)
-{
-  copy_t *copy;
-  const char *node_id, *copy_id, *txn_id;
-
-  /* Get the old copy */
-  SVN_ERR(svn_fs_bdb__get_copy(&copy, trail->fs, old_copy_id, trail,
-                               scratch_pool));
-
-  /* Modify it: change dst_noderev_id's txn_id to NEW_TXN_ID */
-  node_id = svn_fs_base__id_node_id(copy->dst_noderev_id);
-  copy_id = svn_fs_base__id_copy_id(copy->dst_noderev_id);
-  txn_id = svn_fs_base__id_txn_id(copy->dst_noderev_id);
-  SVN_ERR_ASSERT(svn_fs_base__key_compare(copy_id, old_copy_id) == 0);
-  SVN_ERR_ASSERT(svn_fs_base__key_compare(txn_id, old_txn_id) == 0);
-  copy->dst_noderev_id = svn_fs_base__id_create(node_id, copy_id, new_txn_id,
-                                                scratch_pool);
-
-  /* Save the new copy */
-  SVN_ERR(svn_fs_bdb__reserve_copy_id(new_copy_id, trail->fs, trail,
-                                      trail->pool));
-  SVN_ERR(svn_fs_bdb__create_copy(trail->fs, *new_copy_id, copy->src_path,
-                                  copy->src_txn_id, copy->dst_noderev_id,
-                                  copy->kind, trail, scratch_pool));
-  return SVN_NO_ERROR;
-}
-
-
 /* Duplicate all entries in the "changes" table that are keyed by OLD_TXN_ID,
  * creating new entries that are keyed by NEW_TXN_ID.
  *
@@ -863,41 +824,25 @@
   /* Dup txn->proplist */
   new_txn->proplist = old_txn->proplist;
 
-  /* ### TODO: Update "copies" table entries referenced by txn->copies.
-   * This is hard, because I don't want to change the copy_ids, because they
-   * pervade node-ids throughout history. But what actually uses them, and
-   * does anything use them during txn construction? */
-
-  /* Dup txn->copies
+  /* Prepare to update the "copies" table.
    *
-   * ### PROBLEM:
-   * This code makes new rows in the 'copies' table, keyed by a NEW COPY-ID
-   * that is not the copy-id of the node-rev it refers to. WRONG!
+   * As part of obliteration, we need to update all of the "copies" table
+   * rows that are referenced by this txn, to refer to the new txn's
+   * node-rev ids instead. At txn begin time, just keep the references to
+   * the old rows. At commit time, we will update those rows to refer to
+   * this txn's node-rev ids.
    *
-   * For the purpose of the txn keeping track of which "copies" table rows
-   * it allocated, this is fine. It is no good if something needs to look
-   * up copy info based on copy-id during txn construction.
+   * We cannot simply create new "copies" table rows now and make the old
+   * ones obsolete at commit time, because the rows are keyed by copy-id,
+   * and we don't want to change the copy_ids because they pervade node-ids
+   * throughout history.
    *
-   * If no look-ups are required until after the txn is committed, maybe we
-   * could overwrite the old "copies" table entries with the new ones at
-   * commit time.
-   */
+   * ### What actually uses the "copies" table? Does anything use it during
+   * txn construction? Does it need to be keyed by copy-id or could we
+   * change the schema to use arbitrary keys? */
   if (old_txn->copies)
     {
-      int i;
-
-      new_txn->copies = apr_array_make(trail->pool, old_txn->copies->nelts,
-                                       sizeof(const char *));
-      for (i = 0; i < old_txn->copies->nelts; i++)
-        {
-          const char *old_copy_id = APR_ARRAY_IDX(old_txn->copies, i,
-                                                  const char *);
-          const char *new_copy_id;
-
-          SVN_ERR(copy_dup(&new_copy_id, old_copy_id, new_txn_id, old_txn_id,
-                           trail, trail->pool));
-          APR_ARRAY_PUSH(new_txn->copies, const char *) = new_copy_id;
-        }
+      new_txn->copies = apr_array_copy(trail->pool, old_txn->copies);
     }
 
   /* Dup the "changes" that are keyed by the txn_id. */


Reply via email to