Author: cmpilato
Date: Tue Dec 15 19:26:29 2009
New Revision: 890955

URL: http://svn.apache.org/viewvc?rev=890955&view=rev
Log:
On the 'issue-3550-dev' branch, teach the transaction creation code to
use arbitrary changes keys when the format so permits.

* subversion/libsvn_fs_base/bdb/txn-table.h,
* subversion/libsvn_fs_base/bdb/txn-table.c
  (svn_fs_bdb__create_txn): Add 'changes_id' parameter, used to
    populate the transaction_t.

* subversion/libsvn_fs_base/bdb/changes-table.h,
* subversion/libsvn_fs_base/bdb/changes-table.c
  (svn_fs_bdb__changes_reserve_id): New.

* subversion/libsvn_fs_base/revs-txns.c
  (changes_dup): s/old_txn_id/old_key, s/new_txn_id/new_key.  Add
    FIXME comment about a questionable assertion.
  (txn_body_begin_txn): If the format so allows, reserve a new changes
    ID and pass its value to svn_fs_bdb__create_txn().
  (txn_body_begin_obliteration_txn): Update calls to
    svn_fs_bdb__create_txn() and changed_dup() to deal with arbitrary
    changes IDs.

* subversion/libsvn_fs_base/dag.h
  (svn_fs_base__dag_init_fs): Now accept 'format' parameter.

* subversion/libsvn_fs_base/dag.c
  (txn_body_dag_init_fs): If the format (which is now provided via the
    function baton) so allows, reserve a new changes ID and pass its
    value to svn_fs_bdb__create_txn().
  (svn_fs_base__dag_init_fs): Now accept 'format' parameter, and pass
    a pointer to it to txn_body_dag_init_fs() as its baton.

* subversion/libsvn_fs_base/fs.c
  (base_create): Update call to svn_fs_base__dag_init_fs().

Modified:
    
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.c
    
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.h
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.c
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.h
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.c
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.h
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.c
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c

Modified: 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.c?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.c
 (original)
+++ 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.c
 Tue Dec 15 19:26:29 2009
@@ -116,6 +116,45 @@
 }
 
 
+svn_error_t *
+svn_fs_bdb__changes_reserve_id(const char **id_p,
+                               svn_fs_t *fs,
+                               trail_t *trail,
+                               apr_pool_t *pool)
+{
+  base_fs_data_t *bfd = fs->fsap_data;
+  DBT query, result;
+  apr_size_t len;
+  char next_key[MAX_KEY_SIZE];
+  int db_err;
+
+  svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY);
+
+  /* Get the current value associated with the `next-key' key in the
+     changes table.  */
+  svn_fs_base__trail_debug(trail, "changes", "get");
+  SVN_ERR(BDB_WRAP(fs, _("allocating new changes ID (getting 'next-key')"),
+                   bfd->changes->get(bfd->changes, trail->db_txn, &query,
+                                     svn_fs_base__result_dbt(&result),
+                                     0)));
+  svn_fs_base__track_dbt(&result, pool);
+
+  /* Set our return value. */
+  *id_p = apr_pstrmemdup(pool, result.data, result.size);
+
+  /* Bump to future key. */
+  len = result.size;
+  svn_fs_base__next_key(result.data, &len, next_key);
+  svn_fs_base__trail_debug(trail, "changes", "put");
+  db_err = bfd->changes->put(bfd->changes, trail->db_txn,
+                             svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY),
+                             svn_fs_base__str_to_dbt(&result, next_key),
+                             0);
+
+  return BDB_WRAP(fs, _("bumping next changes key"), db_err);
+}
+
+
 
 /*** Storing and retrieving changes.  ***/
 

Modified: 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.h?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.h
 (original)
+++ 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/changes-table.h
 Tue Dec 15 19:26:29 2009
@@ -45,8 +45,6 @@
                                    int version,
                                    svn_boolean_t create);
 
-
-
 /* Create a 'next-key' key in the `changes' table with value
    INITIAL_VALUE as part of TRAIL.  Return SVN_ERR_FS_CORRUPT if the
    'next-key' row already exists in the `changes' table.  */
@@ -55,6 +53,15 @@
                                                trail_t *trail,
                                                apr_pool_t *pool);
 
+/* Reserve a slot in the `changes' table in FS for a new set of path
+   changes as part of TRAIL.  Return the slot's id in *CHANGES_ID_P,
+   allocated in POOL.  */
+svn_error_t *svn_fs_bdb__changes_reserve_id(const char **changes_id_p,
+                                            svn_fs_t *fs,
+                                            trail_t *trail,
+                                            apr_pool_t *pool);
+
+
 /* Add CHANGE as a record to the `changes' table in FS as part of
    TRAIL, keyed on KEY.
 

Modified: 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.c?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.c 
(original)
+++ 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.c 
Tue Dec 15 19:26:29 2009
@@ -160,6 +160,7 @@
 svn_fs_bdb__create_txn(const char **txn_name_p,
                        svn_fs_t *fs,
                        const svn_fs_id_t *root_id,
+                       const char *changes_id,
                        trail_t *trail,
                        apr_pool_t *pool)
 {
@@ -173,7 +174,7 @@
   txn.proplist = NULL;
   txn.copies = NULL;
   txn.revision = SVN_INVALID_REVNUM;
-  txn.changes_id = NULL;
+  txn.changes_id = changes_id;
   txn.changes_prefolded = FALSE;
   txn.num_changes = -1;
   SVN_ERR(svn_fs_bdb__put_txn(fs, &txn, txn_name, trail, pool));

Modified: 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.h?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.h 
(original)
+++ 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.h 
Tue Dec 15 19:26:29 2009
@@ -49,11 +49,14 @@
                                          apr_pool_t *pool);
 
 /* Create a new transaction in FS as part of TRAIL, with an initial
-   root and base root ID of ROOT_ID.  Set *TXN_NAME_P to the name of the
-   new transaction, allocated in POOL.  */
+   root and base root ID of ROOT_ID.  Set *TXN_NAME_P to the name of
+   the new transaction, allocated in POOL.  If non-NULL, CHANGES_ID is
+   the key into the `changes' table for changes associated with this
+   transaction.  */
 svn_error_t *svn_fs_bdb__create_txn(const char **txn_name_p,
                                     svn_fs_t *fs,
                                     const svn_fs_id_t *root_id,
+                                    const char *changes_id,
                                     trail_t *trail,
                                     apr_pool_t *pool);
 

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.c?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.c 
(original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.c Tue Dec 
15 19:26:29 2009
@@ -45,6 +45,7 @@
 #include "bdb/txn-table.h"
 #include "bdb/rev-table.h"
 #include "bdb/nodes-table.h"
+#include "bdb/changes-table.h"
 #include "bdb/copies-table.h"
 #include "bdb/reps-table.h"
 #include "bdb/strings-table.h"
@@ -196,16 +197,19 @@
 }
 
 
-/* Trail body for svn_fs_base__dag_init_fs. */
+/* Trail body for svn_fs_base__dag_init_fs.  Baton is a pointer to an
+   'int format'.  */
 static svn_error_t *
 txn_body_dag_init_fs(void *baton,
                      trail_t *trail)
 {
+  int format = *((int *)baton);
   node_revision_t noderev;
   revision_t revision;
   svn_revnum_t rev = SVN_INVALID_REVNUM;
   svn_fs_t *fs = trail->fs;
   svn_string_t date;
+  const char *changes_id;
   const char *txn_id;
   const char *copy_id;
   svn_fs_id_t *root_id = svn_fs_base__id_create("0", "0", "0", trail->pool);
@@ -217,8 +221,16 @@
   SVN_ERR(svn_fs_bdb__put_node_revision(fs, root_id, &noderev,
                                         trail, trail->pool));
 
+  /* Reserve a changes ID if our format allows such a thing. */
+  if (format >= SVN_FS_BASE__MIN_CHANGES_INFO_FORMAT)
+    SVN_ERR(svn_fs_bdb__changes_reserve_id(&changes_id, fs,
+                                           trail, trail->pool));
+  else
+    changes_id = NULL;
+
   /* Create a new transaction (better have an id of "0") */
-  SVN_ERR(svn_fs_bdb__create_txn(&txn_id, fs, root_id, trail, trail->pool));
+  SVN_ERR(svn_fs_bdb__create_txn(&txn_id, fs, root_id, changes_id,
+                                 trail, trail->pool));
   if (strcmp(txn_id, "0"))
     return svn_error_createf
       (SVN_ERR_FS_CORRUPT, 0,
@@ -255,9 +267,9 @@
 
 
 svn_error_t *
-svn_fs_base__dag_init_fs(svn_fs_t *fs)
+svn_fs_base__dag_init_fs(svn_fs_t *fs, int format)
 {
-  return svn_fs_base__retry_txn(fs, txn_body_dag_init_fs, NULL,
+  return svn_fs_base__retry_txn(fs, txn_body_dag_init_fs, &format,
                                 TRUE, fs->pool);
 }
 

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.h?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.h 
(original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/dag.h Tue Dec 
15 19:26:29 2009
@@ -61,8 +61,11 @@
 
 
 /* Given a filesystem FS, which contains all the necessary tables,
-   create the initial revision 0, and the initial root directory.  */
-svn_error_t *svn_fs_base__dag_init_fs(svn_fs_t *fs);
+   create the initial revision 0, the initial root directory, and
+   related database information.  FORMAT is the version of the
+   filesystem which is being initialized.  */
+svn_error_t *svn_fs_base__dag_init_fs(svn_fs_t *fs,
+                                      int format);
 
 
 

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.c?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.c Tue Dec 
15 19:26:29 2009
@@ -679,7 +679,7 @@
   if (svn_err) goto error;
 
   /* Initialize the DAG subsystem. */
-  svn_err = svn_fs_base__dag_init_fs(fs);
+  svn_err = svn_fs_base__dag_init_fs(fs, format);
   if (svn_err) goto error;
 
   /* This filesystem is ready.  Stamp it with a format number. */

Modified: 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c?rev=890955&r1=890954&r2=890955&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c 
(original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c 
Tue Dec 15 19:26:29 2009
@@ -473,24 +473,24 @@
 }
 
 
-/* Duplicate all entries in the "changes" table that are keyed by OLD_TXN_ID,
- * creating new entries that are keyed by NEW_TXN_ID.
+/* Duplicate all entries in the "changes" table that are keyed by OLD_KEY,
+ * creating new entries that are keyed by NEW_KEY.
  *
  * Each new "change" has the same content as the old one, except with the
  * txn-id component of its noderev-id (which is assumed to have been
- * OLD_TXN_ID) changed to NEW_TXN_ID.
+ * OLD_KEY) changed to NEW_KEY.
  *
  * Work within TRAIL. */
 static svn_error_t *
-changes_dup(const char *new_txn_id,
-            const char *old_txn_id,
+changes_dup(const char *new_key,
+            const char *old_key,
             trail_t *trail,
             apr_pool_t *scratch_pool)
 {
   apr_array_header_t *changes;
   int i;
 
-  SVN_ERR(svn_fs_bdb__changes_fetch_raw(&changes, trail->fs, old_txn_id, trail,
+  SVN_ERR(svn_fs_bdb__changes_fetch_raw(&changes, trail->fs, old_key, trail,
                                         scratch_pool));
   for (i = 0; i < changes->nelts; i++)
     {
@@ -501,18 +501,20 @@
         {
           const char *node_id, *copy_id;
 
-          /* Modify the "change": change noderev_id's txn_id to NEW_TXN_ID */
+          /* Modify the "change": change noderev_id's txn_id to NEW_KEY */
           node_id = svn_fs_base__id_node_id(change->noderev_id);
           copy_id = svn_fs_base__id_copy_id(change->noderev_id);
+          /* ### FIXME:  Not sure this assertion makes sense when
+             `changes' are arbitrarily keyed. */
           SVN_ERR_ASSERT(svn_fs_base__key_compare(
-            svn_fs_base__id_txn_id(change->noderev_id), old_txn_id) == 0);
+            svn_fs_base__id_txn_id(change->noderev_id), old_key) == 0);
           change->noderev_id = svn_fs_base__id_create(node_id, copy_id,
-                                                      new_txn_id,
+                                                      new_key,
                                                       scratch_pool);
         }
 
       /* Save the new "change" */
-      SVN_ERR(svn_fs_bdb__changes_add(trail->fs, new_txn_id, change, trail,
+      SVN_ERR(svn_fs_bdb__changes_add(trail->fs, new_key, change, trail,
                                       scratch_pool));
     }
   return SVN_NO_ERROR;
@@ -744,12 +746,22 @@
 txn_body_begin_txn(void *baton, trail_t *trail)
 {
   struct begin_txn_args *args = baton;
+  base_fs_data_t *bfd = trail->fs->fsap_data;
   const svn_fs_id_t *root_id;
   const char *txn_id;
+  const char *changes_id;
 
   SVN_ERR(svn_fs_base__rev_get_root(&root_id, trail->fs, args->base_rev,
                                     trail, trail->pool));
-  SVN_ERR(svn_fs_bdb__create_txn(&txn_id, trail->fs, root_id,
+
+  /* Reserve a changes ID if our format allows such a thing. */
+  if (bfd->format >= SVN_FS_BASE__MIN_CHANGES_INFO_FORMAT)
+    SVN_ERR(svn_fs_bdb__changes_reserve_id(&changes_id, trail->fs,
+                                           trail, trail->pool));
+  else
+    changes_id = NULL;
+  
+  SVN_ERR(svn_fs_bdb__create_txn(&txn_id, trail->fs, root_id, changes_id,
                                  trail, trail->pool));
 
   if (args->flags & SVN_FS_TXN_CHECK_OOD)
@@ -800,10 +812,12 @@
 txn_body_begin_obliteration_txn(void *baton, trail_t *trail)
 {
   struct begin_txn_args *args = baton;
+  base_fs_data_t *bfd = trail->fs->fsap_data;
   int replacing_rev = args->base_rev + 1;
   const svn_fs_id_t *base_root_id;
   const char *old_txn_id, *new_txn_id;
   transaction_t *old_txn, *new_txn;
+  const char *changes_id;
 
   /* Obliteration doesn't support these flags */
   SVN_ERR_ASSERT(! (args->flags & SVN_FS_TXN_CHECK_OOD));
@@ -840,8 +854,16 @@
    * to the previous revision, like txn_body_begin_txn() does. */
   SVN_ERR(svn_fs_base__rev_get_root(&base_root_id, trail->fs,
                                     args->base_rev, trail, trail->pool));
+
+  /* Reserve a changes ID if our format allows such a thing. */
+  if (bfd->format >= SVN_FS_BASE__MIN_CHANGES_INFO_FORMAT)
+    SVN_ERR(svn_fs_bdb__changes_reserve_id(&changes_id, trail->fs,
+                                           trail, trail->pool));
+  else
+    changes_id = NULL;
+
   SVN_ERR(svn_fs_bdb__create_txn(&new_txn_id, trail->fs, base_root_id,
-                                 trail, trail->pool));
+                                 changes_id, trail, trail->pool));
 
   /* Read the old and new txns */
   SVN_ERR(svn_fs_base__rev_get_txn_id(&old_txn_id, trail->fs, replacing_rev,
@@ -901,7 +923,9 @@
     }
 
   /* Dup the "changes" that are keyed by the txn_id. */
-  SVN_ERR(changes_dup(new_txn_id, old_txn_id, trail, trail->pool));
+  SVN_ERR(changes_dup(changes_id,
+                      old_txn->changes_id ? old_txn->changes_id : old_txn_id,
+                      trail, trail->pool));
 
   /* ### TODO: Update the "node-origins" table.
    * Or can this be deferred till commit time? Probably not. */


Reply via email to