You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2014/02/21 00:18:48 UTC

svn commit: r1570387 - in /subversion/trunk/subversion/libsvn_fs_x: id.c id.h transaction.c

Author: stefan2
Date: Thu Feb 20 23:18:48 2014
New Revision: 1570387

URL: http://svn.apache.org/r1570387
Log:
In FSX, assign unique IDs immediately when creating items in a transaction.

Noderev IDs in particular, are now unique from the start.  That requires
(logical) item numbers to be allocated before we know their (physical)
offset is known.

* subversion/libsvn_fs_x/id.h
  (svn_fs_x__id_txn_create): Add the item number as a parameter to enforce
                             that all noderev ids are "complete" and thus
                             unique.

* subversion/libsvn_fs_x/id.c
  (svn_fs_x__id_txn_create): Update implementation.

* subversion/libsvn_fs_x/transaction.c
  (allocate_item_index): Allocate the item index only, i.e. the index
                         file information must be stored explicitly at
                         some later point.
  (get_new_txn_node_id,
   svn_fs_x__reserve_copy_id): Make node and copy ID unique amoungst
                               different transactions.
  (svn_fs_x__create_node,
   svn_fs_x__create_successor): Create the noderev with a unique ID as well.
  (rep_write_contents_close,
   write_hash_delta_rep): Explicitly write the proto index file as that is
                          no longer part of the item number allocation.
  (svn_fs_x__set_proplist): Like all items, property reps are now expected
                            to have item index numbers assigned to them
                            from the start.
  (get_final_id): Replace transaction and undefined change set with
                  the current revision changeset. 
  (write_final_rev): Since the noderev ID is now "complete" from its
                     creation on, we can simply handle it like the other
                     ID parts.  Again, the proto index has to be written
                     explicitly.

Modified:
    subversion/trunk/subversion/libsvn_fs_x/id.c
    subversion/trunk/subversion/libsvn_fs_x/id.h
    subversion/trunk/subversion/libsvn_fs_x/transaction.c

Modified: subversion/trunk/subversion/libsvn_fs_x/id.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/id.c?rev=1570387&r1=1570386&r2=1570387&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/id.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/id.c Thu Feb 20 23:18:48 2014
@@ -341,6 +341,7 @@ svn_fs_id_t *
 svn_fs_x__id_txn_create(const svn_fs_x__id_part_t *node_id,
                         const svn_fs_x__id_part_t *copy_id,
                         svn_fs_x__txn_id_t txn_id,
+                        apr_uint64_t item,
                         apr_pool_t *pool)
 {
   fs_x__id_t *id = apr_pcalloc(pool, sizeof(*id));
@@ -349,6 +350,7 @@ svn_fs_x__id_txn_create(const svn_fs_x__
   id->copy_id = *copy_id;
 
   id->noderev_id.change_set = svn_fs_x__change_set_by_txn(txn_id);
+  id->noderev_id.number = item;
 
   id->generic_id.vtable = &id_vtable;
   id->generic_id.fsap_data = id;

Modified: subversion/trunk/subversion/libsvn_fs_x/id.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/id.h?rev=1570387&r1=1570386&r2=1570387&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/id.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/id.h Thu Feb 20 23:18:48 2014
@@ -142,11 +142,12 @@ svn_fs_id_t *svn_fs_x__id_txn_create_roo
 svn_fs_id_t *svn_fs_x__id_create_root(const svn_revnum_t revision,
                                       apr_pool_t *pool);
 
-/* Create an ID within a transaction based on NODE_ID, COPY_ID, and
-   TXN_ID, allocated in POOL. */
+/* Create an ID within a transaction based on NODE_ID, COPY_ID, TXN_ID
+   and ITEM number, allocated in POOL. */
 svn_fs_id_t *svn_fs_x__id_txn_create(const svn_fs_x__id_part_t *node_id,
                                      const svn_fs_x__id_part_t *copy_id,
                                      svn_fs_x__txn_id_t txn_id,
+                                     apr_uint64_t item,
                                      apr_pool_t *pool);
 
 /* Create a permanent ID based on NODE_ID, COPY_ID and NODEREV_ID,

Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.c?rev=1570387&r1=1570386&r2=1570387&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.c Thu Feb 20 23:18:48 2014
@@ -1273,18 +1273,13 @@ store_p2l_index_entry(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
-/* Allocate an item index for the given MY_OFFSET in the transaction TXN_ID
- * of file system FS and return it in *ITEM_INDEX.  For old formats, it
- * will simply return the offset as item index; in new formats, it will
- * increment the txn's item index counter file and store the mapping in
- * the proto index file.
- * Use POOL for allocations.
+/* Allocate an item index in the transaction TXN_ID of file system FS and
+ * return it in *ITEM_INDEX.  Use POOL for allocations.
  */
 static svn_error_t *
 allocate_item_index(apr_uint64_t *item_index,
                     svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
-                    apr_off_t my_offset,
                     apr_pool_t *pool)
 {
   apr_file_t *file;
@@ -1294,7 +1289,7 @@ allocate_item_index(apr_uint64_t *item_i
   apr_size_t read;
   apr_off_t offset = 0;
 
-  /* read number, increment it and write it back to disk */
+  /* read number */
   SVN_ERR(svn_io_file_open(&file,
                             svn_fs_x__path_txn_item_index(fs, txn_id, pool),
                             APR_READ | APR_WRITE
@@ -1307,15 +1302,14 @@ allocate_item_index(apr_uint64_t *item_i
   else
     *item_index = SVN_FS_X__ITEM_INDEX_FIRST_USER;
 
+  /* increment it */
   to_write = svn__ui64toa(buffer, *item_index + 1);
+
+  /* write it back to disk */
   SVN_ERR(svn_io_file_seek(file, SEEK_SET, &offset, pool));
   SVN_ERR(svn_io_file_write_full(file, buffer, to_write, NULL, pool));
   SVN_ERR(svn_io_file_close(file, pool));
 
-  /* write log-to-phys index */
-  SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, *item_index,
-                                pool));
-
   return SVN_NO_ERROR;
 }
 
@@ -1398,7 +1392,7 @@ get_new_txn_node_id(svn_fs_x__id_part_t 
   /* First read in the current next-ids file. */
   SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));
 
-  node_id_p->change_set = SVN_FS_X__INVALID_CHANGE_SET;
+  node_id_p->change_set = svn_fs_x__change_set_by_txn(txn_id);
   node_id_p->number = node_id;
 
   SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, pool));
@@ -1417,7 +1411,7 @@ svn_fs_x__reserve_copy_id(svn_fs_x__id_p
   /* First read in the current next-ids file. */
   SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));
 
-  copy_id_p->change_set = SVN_FS_X__INVALID_CHANGE_SET;
+  copy_id_p->change_set = svn_fs_x__change_set_by_txn(txn_id);
   copy_id_p->number = copy_id;
 
   SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, pool));
@@ -1435,12 +1429,16 @@ svn_fs_x__create_node(const svn_fs_id_t 
 {
   svn_fs_x__id_part_t node_id;
   const svn_fs_id_t *id;
+  apr_uint64_t number;
 
   /* Get a new node-id for this node. */
   SVN_ERR(get_new_txn_node_id(&node_id, fs, txn_id, pool));
 
-  id = svn_fs_x__id_txn_create(&node_id, copy_id, txn_id, pool);
+  /* Item number within this change set. */
+  SVN_ERR(allocate_item_index(&number, fs, txn_id, pool));
 
+  /* Construct the ID object from all the above parts. */
+  id = svn_fs_x__id_txn_create(&node_id, copy_id, txn_id, number, pool);
   noderev->id = id;
 
   SVN_ERR(svn_fs_x__put_node_revision(fs, noderev->id, noderev, FALSE, pool));
@@ -2081,8 +2079,9 @@ rep_write_contents_close(void *baton)
     {
       /* Write out our cosmetic end marker. */
       SVN_ERR(svn_stream_puts(b->rep_stream, "ENDREP\n"));
-      SVN_ERR(allocate_item_index(&rep->id.number, b->fs, txn_id,
-                                  b->rep_offset, b->pool));
+      SVN_ERR(allocate_item_index(&rep->id.number, b->fs, txn_id, b->pool));
+      SVN_ERR(store_l2p_index_entry(b->fs, txn_id, b->rep_offset,
+                                    rep->id.number, b->pool));
 
       b->noderev->data_rep = rep;
     }
@@ -2168,11 +2167,14 @@ svn_fs_x__create_successor(const svn_fs_
                            apr_pool_t *pool)
 {
   const svn_fs_id_t *id;
+  apr_uint64_t number;
 
   if (! copy_id)
     copy_id = svn_fs_x__id_copy_id(old_idp);
+
+  SVN_ERR(allocate_item_index(&number, fs, txn_id, pool));
   id = svn_fs_x__id_txn_create(svn_fs_x__id_node_id(old_idp), copy_id,
-                               txn_id, pool);
+                               txn_id, number, pool);
 
   new_noderev->id = id;
 
@@ -2216,7 +2218,9 @@ svn_fs_x__set_proplist(svn_fs_t *fs,
     {
       noderev->prop_rep = apr_pcalloc(pool, sizeof(*noderev->prop_rep));
       noderev->prop_rep->id.change_set
-        = svn_fs_x__change_set_by_txn(svn_fs_x__id_txn_id(noderev->id));
+        = svn_fs_x__id_noderev_id(noderev->id)->change_set;
+      SVN_ERR(allocate_item_index(&noderev->prop_rep->id.number, fs,
+                                  svn_fs_x__id_txn_id(noderev->id), pool));
       SVN_ERR(svn_fs_x__put_node_revision(fs, noderev->id, noderev, FALSE,
                                           pool));
     }
@@ -2360,8 +2364,8 @@ write_hash_delta_rep(representation_t *r
       SVN_ERR(svn_fs_x__get_file_offset(&rep_end, file, pool));
       SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
 
-      SVN_ERR(allocate_item_index(&rep->id.number, fs, txn_id, offset,
-                                  pool));
+      SVN_ERR(allocate_item_index(&rep->id.number, fs, txn_id, pool));
+      SVN_ERR(store_l2p_index_entry(fs, txn_id, offset, rep->id.number, pool));
 
       noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
       noderev_id.number = rep->id.number;
@@ -2451,7 +2455,7 @@ static void
 get_final_id(svn_fs_x__id_part_t *part,
              svn_revnum_t revision)
 {
-  if (part->change_set == SVN_FS_X__INVALID_CHANGE_SET)
+  if (!svn_fs_x__is_revision(part->change_set))
     part->change_set = svn_fs_x__change_set_by_rev(revision);
 }
 
@@ -2590,25 +2594,17 @@ write_final_rev(const svn_fs_id_t **new_
   get_final_id(&node_id, rev);
   copy_id = *svn_fs_x__id_copy_id(noderev->id);
   get_final_id(&copy_id, rev);
+  noderev_id = *svn_fs_x__id_noderev_id(noderev->id);
+  get_final_id(&noderev_id, rev);
 
   if (noderev->copyroot_rev == SVN_INVALID_REVNUM)
     noderev->copyroot_rev = rev;
 
   SVN_ERR(svn_fs_x__get_file_offset(&my_offset, file, pool));
-  if (at_root)
-    {
-      /* reference the root noderev from the log-to-phys index */
-      noderev_id.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
-      SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, noderev_id.number,
-                                    pool));
-    }
-  else
-    SVN_ERR(allocate_item_index(&noderev_id.number, fs, txn_id, my_offset,
-                                pool));
 
-  noderev_id.change_set = change_set;
+  SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, noderev_id.number,
+                                pool));
   new_id = svn_fs_x__id_create(&node_id, &copy_id, &noderev_id, pool);
-
   noderev->id = new_id;
 
   if (ffd->rep_sharing_allowed)