Author: cmpilato
Date: Mon Dec 14 19:04:02 2009
New Revision: 890442

URL: http://svn.apache.org/viewvc?rev=890442&view=rev
Log:
On the 'issue-3550-dev' branch, teach the fs_base code to
parse/unparse the new CHANGES_INFO stuff.

* subversion/libsvn_fs_base/fs.h
  (transaction_t): Add 'changes_id', 'changes_prefolded', and
    'num_changes' members.

* subversion/libsvn_fs_base/bdb/txn-table.c
  (svn_fs_bdb__create_txn): Initialize new members of the
    transaction_t structure.

* subversion/libsvn_fs_base/util/fs_skels.h
  (svn_fs_base__parse_transaction_skel,
   svn_fs_base__unparse_transaction_skel): Add 'format' parameter.

* subversion/libsvn_fs_base/util/fs_skels.c
  (is_valid_transaction_skel, svn_fs_base__parse_transaction_skel,
   svn_fs_base__unparse_transaction_skel): Add 'format' parameter, and
    allow for new transaction format.

Modified:
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/txn-table.c
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.c
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.h

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=890442&r1=890441&r2=890442&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 
Mon Dec 14 19:04:02 2009
@@ -89,7 +89,8 @@
   DBT key, value;
 
   /* Convert native type to skel. */
-  SVN_ERR(svn_fs_base__unparse_transaction_skel(&txn_skel, txn, pool));
+  SVN_ERR(svn_fs_base__unparse_transaction_skel(&txn_skel, txn,
+                                                bfd->format, pool));
 
   /* Only in the context of this function do we know that the DB call
      will not attempt to modify txn_name, so the cast belongs here.  */
@@ -172,6 +173,9 @@
   txn.proplist = NULL;
   txn.copies = NULL;
   txn.revision = SVN_INVALID_REVNUM;
+  txn.changes_id = NULL;
+  txn.changes_prefolded = FALSE;
+  txn.num_changes = -1;
   SVN_ERR(svn_fs_bdb__put_txn(fs, &txn, txn_name, trail, pool));
 
   *txn_name_p = txn_name;
@@ -235,7 +239,8 @@
     return svn_fs_base__err_corrupt_txn(fs, txn_name);
 
   /* Convert skel to native type. */
-  SVN_ERR(svn_fs_base__parse_transaction_skel(&transaction, skel, pool));
+  SVN_ERR(svn_fs_base__parse_transaction_skel(&transaction, skel,
+                                              bfd->format, pool));
   *txn_p = transaction;
   return SVN_NO_ERROR;
 }
@@ -304,7 +309,7 @@
 
       /* Convert skel to native type. */
       if ((err = svn_fs_base__parse_transaction_skel(&txn, txn_skel,
-                                                     subpool)))
+                                                     bfd->format, subpool)))
         {
           svn_bdb_dbc_close(cursor);
           return svn_error_return(err);

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h?rev=890442&r1=890441&r2=890442&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h Mon Dec 
14 19:04:02 2009
@@ -169,6 +169,19 @@
      no copies in this transaction.  */
   apr_array_header_t *copies;
 
+  /* key into the `changed' table by which changed paths for this
+     transaction may be found, or NULL if changes are keyed on the
+     transaction's ID.  */
+  const char *changes_id;
+
+  /* TRUE iff the changes records for this transaction are known to be
+     prefolded. */
+  svn_boolean_t changes_prefolded;
+
+  /* Number of changed paths associated with this transaction, or -1
+     to mean "unknown". */
+  int num_changes;
+
 } transaction_t;
 
 

Modified: 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.c?rev=890442&r1=890441&r2=890442&view=diff
==============================================================================
--- 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.c 
(original)
+++ 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.c 
Mon Dec 14 19:04:02 2009
@@ -83,11 +83,20 @@
 
 
 static svn_boolean_t
-is_valid_transaction_skel(svn_skel_t *skel, transaction_kind_t *kind)
+is_valid_transaction_skel(svn_skel_t *skel,
+                          int format,
+                          transaction_kind_t *kind)
 {
   int len = svn_skel__list_length(skel);
-
-  if (len != 5)
+  
+  /* As of SVN_FS_BASE__MIN_CHANGES_INFO_FORMAT version, the
+     transaction record can have a CHANGES_INFO list at the end. */
+  if (format >= SVN_FS_BASE__MIN_CHANGES_INFO_FORMAT)
+    {
+      if (len != 5 && len != 6)
+        return FALSE;
+    }
+  else if (len != 5)
     return FALSE;
 
   /* Determine (and verify) the kind. */
@@ -100,13 +109,26 @@
   else
     return FALSE;
 
-  if (skel->children->next->is_atom
-      && skel->children->next->next->is_atom
-      && (! skel->children->next->next->next->is_atom)
-      && (! skel->children->next->next->next->next->is_atom))
-    return TRUE;
+  /* The next 4 items are fixed across formats. */
+  if (! (skel->children->next->is_atom
+         && skel->children->next->next->is_atom
+         && (! skel->children->next->next->next->is_atom)
+         && (! skel->children->next->next->next->next->is_atom)))
+    return FALSE;
 
-  return FALSE;
+  /* Now the optional CHANGES_INFO list. */
+  if (len > 5)
+    {
+      svn_skel_t *changes_info = skel->children->next->next->next->next->next;
+      int len_changes_info;
+      if (! changes_info->is_atom)
+        return FALSE;
+      len_changes_info = svn_skel__list_length(changes_info);
+      if (len_changes_info != 2 && len_changes_info != 3)
+        return FALSE;
+    }
+
+  return TRUE;
 }
 
 
@@ -406,17 +428,20 @@
 svn_error_t *
 svn_fs_base__parse_transaction_skel(transaction_t **transaction_p,
                                     svn_skel_t *skel,
+                                    int format,
                                     apr_pool_t *pool)
 {
   transaction_t *transaction;
   transaction_kind_t kind;
   svn_skel_t *root_id, *base_id_or_rev, *proplist, *copies;
-  int len;
+  int skel_len, len;
 
   /* Validate the skel. */
-  if (! is_valid_transaction_skel(skel, &kind))
+  if (! is_valid_transaction_skel(skel, format, &kind))
     return skel_err("transaction");
 
+  skel_len = svn_skel__list_length(skel);
+
   root_id = skel->children->next;
   base_id_or_rev = skel->children->next->next;
   proplist = skel->children->next->next->next;
@@ -424,6 +449,7 @@
 
   /* Create the returned structure */
   transaction = apr_pcalloc(pool, sizeof(*transaction));
+  transaction->num_changes = -1;
 
   /* KIND */
   transaction->kind = kind;
@@ -472,6 +498,37 @@
       transaction->copies = txncopies;
     }
 
+  /* [CHANGES_INFO] */
+  if (skel_len > 5)
+    {
+      svn_skel_t *changes_info = skel->children->next->next->next->next->next; 
+      const char *state;
+
+      /* CHANGES_STATE */
+      state = apr_pstrmemdup(pool,
+                             changes_info->children->data,
+                             changes_info->children->len);
+      if (strcmp(state, "folded") == 0)
+        transaction->changes_prefolded = TRUE;
+      else if (strcmp(state, "unfolded") == 0)
+        transaction->changes_prefolded = FALSE;
+      else
+        return skel_err("transaction");
+
+      /* CHNG */
+      transaction->changes_id = 
+        apr_pstrmemdup(pool,
+                       changes_info->children->next->data,
+                       changes_info->children->next->len);
+        
+      /* [NUM_CHANGES] */
+      if (svn_skel__list_length(changes_info) > 2)
+        transaction->num_changes =
+          atoi(apr_pstrmemdup(pool,
+                              changes_info->children->next->next->data,
+                              changes_info->children->next->next->len));
+    }
+
   /* Return the structure. */
   *transaction_p = transaction;
   return SVN_NO_ERROR;
@@ -922,10 +979,12 @@
 svn_error_t *
 svn_fs_base__unparse_transaction_skel(svn_skel_t **skel_p,
                                       const transaction_t *transaction,
+                                      int format,
                                       apr_pool_t *pool)
 {
   svn_skel_t *skel;
   svn_skel_t *proplist_skel, *copies_skel, *header_skel;
+  svn_skel_t *changes_info_skel = NULL;
   svn_string_t *id_str;
   transaction_kind_t kind;
 
@@ -956,6 +1015,42 @@
       return skel_err("transaction");
     }
 
+  /* [CHANGES_INFO]
+
+     NOTE: we only bother to write any of this information if we have
+     a non-NULL TRANSACTION->changes_id value.  We're exploiting our
+     knowledge that without that, the system can't guarantee prefolded
+     changes or a valid num-changes count.  */
+  if ((format >= SVN_FS_BASE__MIN_CHANGES_INFO_FORMAT)
+      && (transaction->changes_id))
+    {
+      changes_info_skel = svn_skel__make_empty_list(pool);
+      
+      /* [NUM_CHANGES] */
+      if (transaction->num_changes > 0)
+        {
+          const char *num_str = 
+            apr_psprintf(pool, "%d", transaction->num_changes);
+          svn_skel__prepend(svn_skel__str_atom(num_str, pool),
+                            changes_info_skel);
+        }
+      
+      /* CHNG */
+      if (transaction->changes_id)
+        svn_skel__prepend(svn_skel__str_atom(transaction->changes_id, pool),
+                          changes_info_skel);
+      else
+        svn_skel__prepend(svn_skel__mem_atom(NULL, 0, pool),
+                          changes_info_skel);
+
+      /* CHANGES_STATE */
+      svn_skel__prepend(svn_skel__str_atom(transaction->changes_prefolded
+                                             ? "folded" : "unfolded",
+                                           pool),
+                        changes_info_skel);
+
+      svn_skel__prepend(changes_info_skel, skel);
+    }
 
   /* COPIES */
   copies_skel = svn_skel__make_empty_list(pool);
@@ -1002,7 +1097,7 @@
   svn_skel__prepend(header_skel, skel);
 
   /* Validate and return the skel. */
-  if (! is_valid_transaction_skel(skel, &kind))
+  if (! is_valid_transaction_skel(skel, format, &kind))
     return skel_err("transaction");
   if (kind != transaction->kind)
     return skel_err("transaction");

Modified: 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.h?rev=890442&r1=890441&r2=890442&view=diff
==============================================================================
--- 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.h 
(original)
+++ 
subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/util/fs_skels.h 
Mon Dec 14 19:04:02 2009
@@ -50,15 +50,15 @@
                                  apr_pool_t *pool);
 
 /* Parse a `TRANSACTION' SKEL into *TRANSACTION_P.  Use POOL for all
-   allocations.  */
+   allocations.  FORMAT is the format version of the filesystem. */
 svn_error_t *
 svn_fs_base__parse_transaction_skel(transaction_t **transaction_p,
                                     svn_skel_t *skel,
+                                    int format,
                                     apr_pool_t *pool);
 
 /* Parse a `REPRESENTATION' SKEL into *REP_P.  Use POOL for all
    allocations.  */
-
 svn_error_t *
 svn_fs_base__parse_representation_skel(representation_t **rep_p,
                                        svn_skel_t *skel,
@@ -111,10 +111,11 @@
                                    apr_pool_t *pool);
 
 /* Unparse TRANSACTION into a `TRANSACTION' skel *SKEL_P.  Use POOL
-   for all allocations.  */
+   for all allocations.  FORMAT is the format version of the filesystem. */
 svn_error_t *
 svn_fs_base__unparse_transaction_skel(svn_skel_t **skel_p,
                                       const transaction_t *transaction,
+                                      int format,
                                       apr_pool_t *pool);
 
 /* Unparse REP into a `REPRESENTATION' skel *SKEL_P.  Use POOL for all


Reply via email to