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/15 22:31:05 UTC

svn commit: r1568684 - in /subversion/trunk/subversion/libsvn_fs_x: cached_data.c changes.c fs_x.c id.c id.h index.c noderevs.c pack.c transaction.c tree.c verify.c

Author: stefan2
Date: Sat Feb 15 21:31:04 2014
New Revision: 1568684

URL: http://svn.apache.org/r1568684
Log:
In FSX, unifify the concept of revision and transaction numbers and
call it a "change set".

The mapping is trivial (revs == non-neg change sets, txns are negative
change set numbers) and a few conversion functions are being provided.
As a first step, we use it in fs_x__id_t to represent the noderev_id
unifying txn_id and rev_item.  The API is kept unchanged but the textual
representation changes.

* subversion/libsvn_fs_x/id.h
  (svn_fs_x__change_set_t): Define the new change set number type.
  (SVN_FS_X__INVALID_CHANGE_SET): Define the corresponding NULL value.
  (svn_fs_x__is_revision,
   svn_fs_x__is_txn,
   svn_fs_x__get_revnum,
   svn_fs_x__get_txn_id,
   svn_fs_x__change_set_by_rev,
   svn_fs_x__change_set_by_txn): Declare new conversion & check functions.
  (svn_fs_x__id_part_t): Replace REVISION with CHANGE_SET.

* subversion/libsvn_fs_x/id.c
  (fs_x__id_t): Replace TXN_ID and REV_NUM by NODEREV_ID.
  (svn_fs_x__is_revision,
   svn_fs_x__is_txn,
   svn_fs_x__get_revnum,
   svn_fs_x__get_txn_id,
   svn_fs_x__change_set_by_rev,
   svn_fs_x__change_set_by_txn): Declare new conversion & check functions.
  (txn_id_parse): Drop because we don't have separate txn ids anymore.
  (part_parse): Store ID parts as <number[+,-]change_set> with both
                elements encoded in base36.
  (unparse_id_part): Rename to ...
  (part_unparse): ... this and re-implement.
  (svn_fs_x__id_part_is_root,
   svn_fs_x__id_part_eq): Update due to struct member rename. 
  (svn_fs_x__id_txn_id): Extract the txn id from the noderev change set.
  (svn_fs_x__id_rev_item): Make sure to return a well-defined "invalid" /
                           "unused" struct for non-revision IDs.
  (svn_fs_x__id_rev): Extract the revnum from the noderev change set.
  (svn_fs_x__id_item): Update due to struct member rename.
  (svn_fs_x__id_is_txn): Use the new change set number API.
  (svn_fs_x__id_unparse): Simplify writing just the 3 ID parts.
  (svn_fs_x__id_eq): Adapt to struct change.
  (svn_fs_x__id_check_related): Update check for TXN IDs.
  (svn_fs_x__id_part_compare,
   svn_fs_x__id_txn_create_root, 
   svn_fs_x__id_create_root,
   svn_fs_x__id_txn_create, 
   svn_fs_x__id_rev_create): Adapt to struct update. 
  (svn_fs_x__id_parse): Simplify as we just have to parse 3 id parts.

* subversion/libsvn_fs_x/changes.c
  (binary_change_t): Rename REV_ID to NODEREV_ID.
  (append_change): Update to rename and usage of change set numbers.
  (svn_fs_x__write_changes_container, 
   svn_fs_x__read_changes_container): Adapt to struct member renames. 
  (svn_fs_x__changes_get_list,
   svn_fs_x__changes_get_list_func): Adapt to ID API changes.

* subversion/libsvn_fs_x/transaction.c
  (get_new_txn_node_id,
   svn_fs_x__reserve_copy_id,
   rep_write_contents_close, 
   write_hash_delta_rep,
   get_final_id,
   write_final_rev): Use change set instead of revision numbers and say
                     "noderev_id" instead of "rev_item".

* subversion/libsvn_fs_x/fs_x.c
  (write_revision_zero): Update rev 0 template to use the new ID format.

* subversion/libsvn_fs_x/noderevs.c
  (svn_fs_x__write_noderevs_container,
   svn_fs_x__read_noderevs_container): Adapt to id part member rename. 

* subversion/libsvn_fs_x/verify.c
  (compare_l2p_to_p2l_index,
   compare_p2l_to_l2p_index): Convert from and to change set numbers as
                              required by the APIs and follow renames. 

* subversion/libsvn_fs_x/cached_data.c
  (get_node_revision_body, 
   svn_fs_x__get_node_revision,
   svn_fs_x__get_mergeinfo_count, 
   init_rep_state,
   svn_fs_x__get_representation_length, 
   block_read_changes, 
   block_read_changes_container,
   block_read_noderevs_container, 
   block_read_reps_container,
   block_read): Ditto

* subversion/libsvn_fs_x/pack.c
  (add_item_rep_mapping,
   get_item,
   copy_rep_to_temp,
   copy_node_to_temp,
   compare_p2l_info,
   compare_sub_items,
   compare_p2l_info_rev,
   write_reps_containers, 
   write_l2p_index): Same. 

* subversion/libsvn_fs_x/index.c
  (svn_fs_x__p2l_index_create,
   read_entry): Ditto. 

* subversion/libsvn_fs_x/tree.c
  (x_node_origin_rev): Ditto.


Modified:
    subversion/trunk/subversion/libsvn_fs_x/cached_data.c
    subversion/trunk/subversion/libsvn_fs_x/changes.c
    subversion/trunk/subversion/libsvn_fs_x/fs_x.c
    subversion/trunk/subversion/libsvn_fs_x/id.c
    subversion/trunk/subversion/libsvn_fs_x/id.h
    subversion/trunk/subversion/libsvn_fs_x/index.c
    subversion/trunk/subversion/libsvn_fs_x/noderevs.c
    subversion/trunk/subversion/libsvn_fs_x/pack.c
    subversion/trunk/subversion/libsvn_fs_x/transaction.c
    subversion/trunk/subversion/libsvn_fs_x/tree.c
    subversion/trunk/subversion/libsvn_fs_x/verify.c

Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.c Sat Feb 15 21:31:04 2014
@@ -326,20 +326,21 @@ get_node_revision_body(node_revision_t *
   else
     {
       /* noderevs in rev / pack files can be cached */
-      const svn_fs_x__id_part_t *rev_item = svn_fs_x__id_rev_item(id);
+      const svn_fs_x__id_part_t *noderev_id = svn_fs_x__id_rev_item(id);
+      svn_revnum_t revision = svn_fs_x__get_revnum(noderev_id->change_set);
       pair_cache_key_t key;
 
       /* First, try a noderevs container cache lookup. */
-      if (   svn_fs_x__is_packed_rev(fs, rev_item->revision)
+      if (   svn_fs_x__is_packed_rev(fs, revision)
           && ffd->noderevs_container_cache)
         {
           apr_off_t offset;
           apr_uint32_t sub_item;
           SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs,
-                                        rev_item->revision,
+                                        revision,
                                         SVN_FS_X__INVALID_TXN_ID,
-                                        rev_item->number, pool));
-          key.revision = svn_fs_x__packed_base_rev(fs, rev_item->revision);
+                                        noderev_id->number, pool));
+          key.revision = svn_fs_x__packed_base_rev(fs, revision);
           key.second = offset;
 
           SVN_ERR(svn_cache__get_partial((void **)noderev_p, &is_cached,
@@ -350,8 +351,8 @@ get_node_revision_body(node_revision_t *
             return SVN_NO_ERROR;
         }
 
-      key.revision = rev_item->revision;
-      key.second = rev_item->number;
+      key.revision = revision;
+      key.second = noderev_id->number;
 
       /* Not found or not applicable. Try a noderev cache lookup.
        * If that succeeds, we are done here. */
@@ -368,15 +369,15 @@ get_node_revision_body(node_revision_t *
 
       /* someone needs to read the data from this file: */
       err = open_and_seek_revision(&revision_file, fs,
-                                   rev_item->revision,
-                                   rev_item->number,
+                                   revision,
+                                   noderev_id->number,
                                    pool);
 
       /* block-read will parse the whole block and will also return
           the one noderev that we need right now. */
       SVN_ERR(block_read((void **)noderev_p, fs,
-                         rev_item->revision,
-                         rev_item->number,
+                         revision,
+                         noderev_id->number,
                          revision_file,
                          pool,
                          pool));
@@ -392,7 +393,7 @@ svn_fs_x__get_node_revision(node_revisio
                             const svn_fs_id_t *id,
                             apr_pool_t *pool)
 {
-  const svn_fs_x__id_part_t *rev_item = svn_fs_x__id_rev_item(id);
+  const svn_fs_x__id_part_t *noderev_id = svn_fs_x__id_rev_item(id);
 
   svn_error_t *err = get_node_revision_body(noderev_p, fs, id, pool);
   if (err && err->apr_err == SVN_ERR_FS_CORRUPT)
@@ -403,12 +404,9 @@ svn_fs_x__get_node_revision(node_revisio
                                id_string->data);
     }
 
-  SVN_ERR(dgb__log_access(fs,
-                          rev_item->revision,
-                          rev_item->number,
-                          *noderev_p,
-                          SVN_FS_X__ITEM_TYPE_NODEREV,
-                          pool));
+  SVN_ERR(dgb__log_access(fs, svn_fs_x__get_revnum(noderev_id->change_set),
+                          noderev_id->number, *noderev_p,
+                          SVN_FS_X__ITEM_TYPE_NODEREV, pool));
 
   return svn_error_trace(err);
 }
@@ -430,10 +428,11 @@ svn_fs_x__get_mergeinfo_count(apr_int64_
   if (! svn_fs_x__id_is_txn(id))
     {
       /* noderevs in rev / pack files can be cached */
-      const svn_fs_x__id_part_t *rev_item = svn_fs_x__id_rev_item(id);
+      const svn_fs_x__id_part_t *noderev_id = svn_fs_x__id_rev_item(id);
       fs_x_data_t *ffd = fs->fsap_data;
+      svn_revnum_t revision = svn_fs_x__get_revnum(noderev_id->change_set);
 
-      if (   svn_fs_x__is_packed_rev(fs, rev_item->revision)
+      if (   svn_fs_x__is_packed_rev(fs, revision)
           && ffd->noderevs_container_cache)
         {
           pair_cache_key_t key;
@@ -442,10 +441,10 @@ svn_fs_x__get_mergeinfo_count(apr_int64_
           svn_boolean_t is_cached;
 
           SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs,
-                                        rev_item->revision,
+                                        revision,
                                         SVN_FS_X__INVALID_TXN_ID,
-                                        rev_item->number, pool));
-          key.revision = svn_fs_x__packed_base_rev(fs, rev_item->revision);
+                                        noderev_id->number, pool));
+          key.revision = svn_fs_x__packed_base_rev(fs, revision);
           key.second = offset;
 
           SVN_ERR(svn_cache__get_partial((void **)count, &is_cached,
@@ -1511,11 +1510,11 @@ init_rep_state(rep_state_t *rs,
   shared_file->file = file;
   shared_file->stream = stream;
   shared_file->fs = fs;
-  shared_file->revision = entry->items[0].revision;
+  shared_file->revision = svn_fs_x__get_revnum(entry->items[0].change_set);
   shared_file->pool = pool;
 
   rs->file = shared_file;
-  rs->revision = entry->items[0].revision;
+  rs->revision = svn_fs_x__get_revnum(entry->items[0].change_set);
   rs->item_index = entry->items[0].number;
   rs->header_size = rep_header->header_size;
   rs->start = entry->offset + rs->header_size;
@@ -1642,7 +1641,7 @@ svn_fs_x__get_representation_length(svn_
   SVN_ERR_ASSERT(entry->item_count == 1);
 
   /* get / read the representation header */  
-  key.revision = entry->items[0].revision;
+  key.revision = svn_fs_x__get_revnum(entry->items[0].change_set);
   key.is_packed = svn_fs_x__is_packed_rev(fs, key.revision);
   key.item_index = entry->items[0].number;
   SVN_ERR(read_rep_header(&rep_header, fs, stream, &key, pool));
@@ -2394,6 +2393,7 @@ block_read_changes(apr_array_header_t **
 {
   fs_x_data_t *ffd = fs->fsap_data;
   svn_stream_t *stream;
+  svn_revnum_t revision = svn_fs_x__get_revnum(entry->items[0].change_set);
   if (!must_read && !ffd->changes_cache)
     return SVN_NO_ERROR;
 
@@ -2404,8 +2404,8 @@ block_read_changes(apr_array_header_t **
   if (!must_read && ffd->changes_cache)
     {
       svn_boolean_t is_cached = FALSE;
-      SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_cache,
-                                 &entry->items[0].revision, pool));
+      SVN_ERR(svn_cache__has_key(&is_cached, ffd->changes_cache, &revision,
+                                 pool));
       if (is_cached)
         return SVN_NO_ERROR;
     }
@@ -2419,8 +2419,7 @@ block_read_changes(apr_array_header_t **
   /* cache for future reference */
 
   if (ffd->changes_cache)
-    SVN_ERR(svn_cache__set(ffd->changes_cache, &entry->items[0].revision,
-                           *changes, pool));
+    SVN_ERR(svn_cache__set(ffd->changes_cache, &revision, *changes, pool));
 
   return SVN_NO_ERROR;
 }
@@ -2439,8 +2438,9 @@ block_read_changes_container(apr_array_h
   svn_fs_x__changes_t *container;
   pair_cache_key_t key;
   svn_stream_t *stream;
+  svn_revnum_t revision = svn_fs_x__get_revnum(entry->items[0].change_set);
 
-  key.revision = svn_fs_x__packed_base_rev(fs, entry->items[0].revision);
+  key.revision = svn_fs_x__packed_base_rev(fs, revision);
   key.second = entry->offset;
 
   /* already in cache? */
@@ -2528,8 +2528,9 @@ block_read_noderevs_container(node_revis
   svn_fs_x__noderevs_t *container;
   svn_stream_t *stream;
   pair_cache_key_t key;
+  svn_revnum_t revision = svn_fs_x__get_revnum(entry->items[0].change_set);
 
-  key.revision = svn_fs_x__packed_base_rev(fs, entry->items[0].revision);
+  key.revision = svn_fs_x__packed_base_rev(fs, revision);
   key.second = entry->offset;
 
   /* already in cache? */
@@ -2574,8 +2575,9 @@ block_read_reps_container(svn_fs_x__rep_
   svn_fs_x__reps_t *container;
   svn_stream_t *stream;
   pair_cache_key_t key;
+  svn_revnum_t revision = svn_fs_x__get_revnum(entry->items[0].change_set);
 
-  key.revision = svn_fs_x__packed_base_rev(fs, entry->items[0].revision);
+  key.revision = svn_fs_x__packed_base_rev(fs, revision);
   key.second = entry->offset;
 
   /* already in cache? */
@@ -2659,7 +2661,8 @@ block_read(void **result,
           is_result =    result
                       && entry->offset == wanted_offset
                       && entry->item_count >= wanted_sub_item
-                      && entry->items[wanted_sub_item].revision == revision
+                      && entry->items[wanted_sub_item].change_set
+                         == svn_fs_x__change_set_by_rev(revision)
                       && entry->items[wanted_sub_item].number == item_index;
 
           /* select the pool that we want the item to be allocated in */
@@ -2673,7 +2676,7 @@ block_read(void **result,
             {
               void *item = NULL;
               pair_cache_key_t key = { 0 };
-              key.revision = entry->items[0].revision;
+              key.revision = svn_fs_x__get_revnum(entry->items[0].change_set);
               key.second = entry->items[0].number;
 
               SVN_ERR(svn_io_file_seek(revision_file, SEEK_SET,

Modified: subversion/trunk/subversion/libsvn_fs_x/changes.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/changes.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/changes.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/changes.c Sat Feb 15 21:31:04 2014
@@ -81,9 +81,7 @@ typedef struct binary_change_t
    * Empty, if REV_ID is not "used". */
   svn_fs_x__id_part_t node_id;
   svn_fs_x__id_part_t copy_id;
-  svn_fs_x__id_part_t rev_id;  /* if CHANGE_TXN_NODE set in FLAGS:
-                                  revision = SVN_INVALID_REVNUM
-                                  number = TXN_ID */
+  svn_fs_x__id_part_t noderev_id;
 
 } binary_change_t;
 
@@ -185,18 +183,18 @@ append_change(svn_fs_x__changes_t *chang
       binary_change.copy_id = *svn_fs_x__id_copy_id(info->node_rev_id);
       if (is_txn_id)
         {
-          binary_change.rev_id.revision = SVN_INVALID_REVNUM;
-          binary_change.rev_id.number = svn_fs_x__id_txn_id(info->node_rev_id);
+          binary_change.noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
+          binary_change.noderev_id.number = svn_fs_x__id_txn_id(info->node_rev_id);
         }
       else
         {
-          binary_change.rev_id = *svn_fs_x__id_rev_item(info->node_rev_id);
+          binary_change.noderev_id = *svn_fs_x__id_rev_item(info->node_rev_id);
         }
     }
   else
     {
-      binary_change.rev_id.revision = SVN_INVALID_REVNUM;
-      svn_fs_x__id_txn_reset((svn_fs_x__txn_id_t *)&binary_change.rev_id.number);
+      binary_change.noderev_id.number = 0;
+      binary_change.noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
     }
 
   APR_ARRAY_PUSH(changes->changes, binary_change_t) = binary_change;
@@ -283,17 +281,16 @@ svn_fs_x__changes_get_list(apr_array_hea
                                                      &change->path.len,
                                                      pool);
 
-      if (binary_change->flags & CHANGE_TXN_NODE)
+      if (binary_change->noderev_id.change_set != SVN_FS_X__INVALID_CHANGE_SET)
         info->node_rev_id
-          = svn_fs_x__id_txn_create(&binary_change->node_id,
+          = binary_change->flags & CHANGE_TXN_NODE
+          ? svn_fs_x__id_txn_create(&binary_change->node_id,
                                     &binary_change->copy_id,
-                                    binary_change->rev_id.number,
-                                    pool);
-      else if (binary_change->rev_id.revision != SVN_INVALID_REVNUM)
-        info->node_rev_id
-          = svn_fs_x__id_rev_create(&binary_change->node_id,
+                                    binary_change->noderev_id.number,
+                                    pool)
+          : svn_fs_x__id_rev_create(&binary_change->node_id,
                                     &binary_change->copy_id,
-                                    &binary_change->rev_id,
+                                    &binary_change->noderev_id,
                                     pool);
 
       info->change_kind = (svn_fs_path_change_kind_t)
@@ -369,12 +366,12 @@ svn_fs_x__write_changes_container(svn_st
       svn_packed__add_int(changes_stream, change->copyfrom_rev);
       svn_packed__add_uint(changes_stream, change->copyfrom_path);
 
-      svn_packed__add_int(changes_stream, change->node_id.revision);
+      svn_packed__add_int(changes_stream, change->node_id.change_set);
       svn_packed__add_uint(changes_stream, change->node_id.number);
-      svn_packed__add_int(changes_stream, change->copy_id.revision);
+      svn_packed__add_int(changes_stream, change->copy_id.change_set);
       svn_packed__add_uint(changes_stream, change->copy_id.number);
-      svn_packed__add_int(changes_stream, change->rev_id.revision);
-      svn_packed__add_uint(changes_stream, change->rev_id.number);
+      svn_packed__add_int(changes_stream, change->noderev_id.change_set);
+      svn_packed__add_uint(changes_stream, change->noderev_id.number);
     }
 
   /* write to disk */
@@ -429,12 +426,12 @@ svn_fs_x__read_changes_container(svn_fs_
       change.copyfrom_rev = (svn_revnum_t)svn_packed__get_int(changes_stream);
       change.copyfrom_path = (apr_size_t)svn_packed__get_uint(changes_stream);
 
-      change.node_id.revision = (svn_revnum_t)svn_packed__get_int(changes_stream);
+      change.node_id.change_set = (svn_revnum_t)svn_packed__get_int(changes_stream);
       change.node_id.number = svn_packed__get_uint(changes_stream);
-      change.copy_id.revision = (svn_revnum_t)svn_packed__get_int(changes_stream);
+      change.copy_id.change_set = (svn_revnum_t)svn_packed__get_int(changes_stream);
       change.copy_id.number = svn_packed__get_uint(changes_stream);
-      change.rev_id.revision = (svn_revnum_t)svn_packed__get_int(changes_stream);
-      change.rev_id.number = svn_packed__get_uint(changes_stream);
+      change.noderev_id.change_set = (svn_revnum_t)svn_packed__get_int(changes_stream);
+      change.noderev_id.number = svn_packed__get_uint(changes_stream);
 
       APR_ARRAY_PUSH(changes->changes, binary_change_t) = change;
     }
@@ -555,17 +552,16 @@ svn_fs_x__changes_get_list_func(void **o
         = svn_fs_x__string_table_get_func(paths, binary_change->path,
                                           &change->path.len, pool);
 
-      if (binary_change->flags & CHANGE_TXN_NODE)
+      if (binary_change->noderev_id.change_set != SVN_FS_X__INVALID_CHANGE_SET)
         info->node_rev_id
-          = svn_fs_x__id_txn_create(&binary_change->node_id,
+          = binary_change->flags & CHANGE_TXN_NODE
+          ? svn_fs_x__id_txn_create(&binary_change->node_id,
                                     &binary_change->copy_id,
-                                    binary_change->rev_id.number,
-                                    pool);
-      else if (binary_change->rev_id.revision != SVN_INVALID_REVNUM)
-        info->node_rev_id
-          = svn_fs_x__id_rev_create(&binary_change->node_id,
+                                    binary_change->noderev_id.number,
+                                    pool)
+          : svn_fs_x__id_rev_create(&binary_change->node_id,
                                     &binary_change->copy_id,
-                                    &binary_change->rev_id,
+                                    &binary_change->noderev_id,
                                     pool);
 
       info->change_kind = (svn_fs_path_change_kind_t)

Modified: subversion/trunk/subversion/libsvn_fs_x/fs_x.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs_x.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs_x.c Sat Feb 15 21:31:04 2014
@@ -725,14 +725,14 @@ write_revision_zero(svn_fs_t *fs)
                  "\1\x84"     /* 1 instr byte, new 4 bytes */
                  "\4END\n"    /* 4 new bytes, E, N, D, \n */
                  "ENDREP\n"
-               "id: 0.0.r0/2\n"
+               "id: 0+0.0+0.2+0\n"
                "type: dir\n"
                "count: 0\n"
                "text: 0 3 16 4 "
                "2d2977d1c96f487abe4a1e202dd03b4e\n"
                "cpath: /\n"
                "\n\n",
-               0x78, fs->pool));
+               0x7b, fs->pool));
 
   SVN_ERR(svn_io_set_file_read_only(path_revision_zero, FALSE, fs->pool));
 
@@ -742,7 +742,7 @@ write_revision_zero(svn_fs_t *fs)
               "\0\1\x80\x40\1\1" /* rev 0, single page */
               "\5\4"             /* page size: bytes, count */
               "\0"               /* 0 container offsets in list */
-              "\0\x78\x1e\1",    /* phys offsets + 1 */
+              "\0\x7b\x1e\1",    /* phys offsets + 1 */
               13,
               fs->pool));
   SVN_ERR(svn_io_set_file_read_only(path, FALSE, fs->pool));
@@ -754,9 +754,9 @@ write_revision_zero(svn_fs_t *fs)
               "\x80\x80\4\1\x11"  /* 64k pages, 1 page using 17 bytes */
               "\0"                /* offset entry 0 page 1 */
               "\x1d\x11\0\6"      /* len, type + 16 * count, (rev, 2*item)* */
-              "\x5a\x15\0\4"
+              "\x5d\x15\0\4"
               "\1\x16\0\2"
-              "\x88\xff\3\0",     /* last entry fills up 64k page */
+              "\x85\xff\3\0",     /* last entry fills up 64k page */
               23,
               fs->pool));
   SVN_ERR(svn_io_set_file_read_only(path, FALSE, fs->pool));

Modified: subversion/trunk/subversion/libsvn_fs_x/id.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/id.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/id.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/id.c Sat Feb 15 21:31:04 2014
@@ -20,6 +20,7 @@
  * ====================================================================
  */
 
+#include <assert.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -40,86 +41,98 @@ typedef struct fs_x__id_t
   /* private members */
   svn_fs_x__id_part_t node_id;
   svn_fs_x__id_part_t copy_id;
-  svn_fs_x__id_part_t rev_item;
-  svn_fs_x__txn_id_t txn_id;
+  svn_fs_x__id_part_t noderev_id;
 
   apr_pool_t *pool; /* pool that was used to allocate this struct */
 } fs_x__id_t;
 
 
 
-/* Parse the NUL-terminated ID part at DATA and write the result into *PART.
- * Return TRUE if no errors were detected. */
-static svn_boolean_t
-part_parse(svn_fs_x__id_part_t *part,
-           const char *data)
+svn_boolean_t
+svn_fs_x__is_txn(svn_fs_x__change_set_t change_set)
 {
-  /* special case: ID inside some transaction */
-  if (data[0] == '_')
-    {
-      part->revision = SVN_INVALID_REVNUM;
-      part->number = svn__base36toui64(&data, data + 1);
-      return *data == '\0';
-    }
+  return change_set < SVN_FS_X__INVALID_CHANGE_SET;
+}
 
-  /* special case: 0 / default ID */
-  if (data[0] == '0' && data[1] == '\0')
-    {
-      part->revision = 0;
-      part->number = 0;
-      return TRUE;
-    }
+svn_boolean_t
+svn_fs_x__is_revision(svn_fs_x__change_set_t change_set)
+{
+  return change_set > SVN_FS_X__INVALID_CHANGE_SET;
+}
 
-  /* read old style / new style ID */
-  part->number = svn__base36toui64(&data, data);
-  if (data[0] != '-')
-    {
-      part->revision = 0;
-      return *data == '\0';
-    }
+svn_revnum_t
+svn_fs_x__get_revnum(svn_fs_x__change_set_t change_set)
+{
+  return svn_fs_x__is_revision(change_set)
+       ? (svn_revnum_t)change_set
+       : SVN_INVALID_REVNUM;
+}
+
+apr_int64_t
+svn_fs_x__get_txn_id(svn_fs_x__change_set_t change_set)
+{
+  return svn_fs_x__is_txn(change_set)
+       ? -change_set + SVN_FS_X__INVALID_CHANGE_SET -1
+       : SVN_FS_X__INVALID_TXN_ID;
+}
 
-  part->revision = SVN_STR_TO_REV(++data);
 
-  return TRUE;
+svn_fs_x__change_set_t
+svn_fs_x__change_set_by_rev(svn_revnum_t revnum)
+{
+  assert(revnum >= SVN_FS_X__INVALID_CHANGE_SET);
+  return revnum;
 }
 
-/* Parse the transaction id in DATA and store the result in *TXN_ID.
- * Return FALSE if there was some problem.
- */
+svn_fs_x__change_set_t
+svn_fs_x__change_set_by_txn(apr_int64_t txn_id)
+{
+  assert(txn_id >= SVN_FS_X__INVALID_CHANGE_SET);
+  return -txn_id + SVN_FS_X__INVALID_CHANGE_SET -1;
+}
+
+
+/* Parse the NUL-terminated ID part at DATA and write the result into *PART.
+ * Return TRUE if no errors were detected. */
 static svn_boolean_t
-txn_id_parse(svn_fs_x__txn_id_t *txn_id,
-             const char *data)
+part_parse(svn_fs_x__id_part_t *part,
+           const char *data)
 {
-  *txn_id = svn__base36toui64(&data, data);
-  return *data == '\0';
+  part->number = svn__base36toui64(&data, data);
+  switch (data[0])
+    {
+      /* txn number? */
+      case '-': part->change_set = -svn__base36toui64(&data, data + 1);
+                return TRUE;
+
+      /* revision number? */
+      case '+': part->change_set = svn__base36toui64(&data, data + 1);
+                return TRUE;
+
+      /* everything else is forbidden */
+      default:  return FALSE;
+    }
 }
 
 /* Write the textual representation of *PART into P and return a pointer
  * to the first position behind that string.
  */
 static char *
-unparse_id_part(char *p,
-                const svn_fs_x__id_part_t *part)
+part_unparse(char *p,
+             const svn_fs_x__id_part_t *part)
 {
-  if (SVN_IS_VALID_REVNUM(part->revision))
+  p += svn__ui64tobase36(p, part->number);
+  if (part->change_set >= 0)
     {
-      /* ordinary old style / new style ID */
-      p += svn__ui64tobase36(p, part->number);
-      if (part->revision > 0)
-        {
-          *(p++) = '-';
-          p += svn__i64toa(p, part->revision);
-        }
+      *(p++) = '+';
+      p += svn__ui64tobase36(p, part->change_set);
     }
   else
     {
-      /* in txn: mark with "_" prefix */
-      *(p++) = '_';
-      p += svn__ui64tobase36(p, part->number);
+      *(p++) = '-';
+      p += svn__ui64tobase36(p, -part->change_set);
     }
 
-  *(p++) = '.';
-
   return p;
 }
 
@@ -130,14 +143,14 @@ unparse_id_part(char *p,
 svn_boolean_t
 svn_fs_x__id_part_is_root(const svn_fs_x__id_part_t* part)
 {
-  return part->revision == 0 && part->number == 0;
+  return part->change_set == 0 && part->number == 0;
 }
 
 svn_boolean_t
 svn_fs_x__id_part_eq(const svn_fs_x__id_part_t *lhs,
                      const svn_fs_x__id_part_t *rhs)
 {
-  return lhs->revision == rhs->revision && lhs->number == rhs->number;
+  return lhs->change_set == rhs->change_set && lhs->number == rhs->number;
 }
 
 svn_boolean_t
@@ -179,16 +192,18 @@ svn_fs_x__id_txn_id(const svn_fs_id_t *f
 {
   fs_x__id_t *id = (fs_x__id_t *)fs_id;
 
-  return id->txn_id;
+  return svn_fs_x__get_txn_id(id->noderev_id.change_set);
 }
 
 
 const svn_fs_x__id_part_t *
 svn_fs_x__id_rev_item(const svn_fs_id_t *fs_id)
 {
+  const static svn_fs_x__id_part_t invalid
+    = { SVN_FS_X__INVALID_CHANGE_SET, 0};
   fs_x__id_t *id = (fs_x__id_t *)fs_id;
 
-  return &id->rev_item;
+  return svn_fs_x__id_is_txn(fs_id) ? &invalid : &id->noderev_id;
 }
 
 svn_revnum_t
@@ -196,7 +211,7 @@ svn_fs_x__id_rev(const svn_fs_id_t *fs_i
 {
   fs_x__id_t *id = (fs_x__id_t *)fs_id;
 
-  return id->rev_item.revision;
+  return svn_fs_x__get_revnum(id->noderev_id.change_set);
 }
 
 
@@ -205,7 +220,7 @@ svn_fs_x__id_item(const svn_fs_id_t *fs_
 {
   fs_x__id_t *id = (fs_x__id_t *)fs_id;
 
-  return id->rev_item.number;
+  return id->noderev_id.number;
 }
 
 svn_boolean_t
@@ -213,7 +228,7 @@ svn_fs_x__id_is_txn(const svn_fs_id_t *f
 {
   fs_x__id_t *id = (fs_x__id_t *)fs_id;
 
-  return svn_fs_x__id_txn_used(id->txn_id);
+  return svn_fs_x__is_txn(id->noderev_id.change_set);
 }
 
 svn_string_t *
@@ -223,21 +238,11 @@ svn_fs_x__id_unparse(const svn_fs_id_t *
   char string[6 * SVN_INT64_BUFFER_SIZE + 10];
   fs_x__id_t *id = (fs_x__id_t *)fs_id;
 
-  char *p = unparse_id_part(string, &id->node_id);
-  p = unparse_id_part(p, &id->copy_id);
-
-  if (svn_fs_x__id_txn_used(id->txn_id))
-    {
-      *(p++) = 't';
-      p += svn__ui64tobase36(p, id->txn_id);
-    }
-  else
-    {
-      *(p++) = 'r';
-      p += svn__i64toa(p, id->rev_item.revision);
-      *(p++) = '/';
-      p += svn__i64toa(p, id->rev_item.number);
-    }
+  char *p = part_unparse(string, &id->node_id);
+  *(p++) = '.';
+  p = part_unparse(p, &id->copy_id);
+  *(p++) = '.';
+  p = part_unparse(p, &id->noderev_id);
 
   return svn_string_ncreate(string, p - string, pool);
 }
@@ -255,8 +260,7 @@ svn_fs_x__id_eq(const svn_fs_id_t *a,
   if (a == b)
     return TRUE;
 
-  return id_a->txn_id == id_b->txn_id
-      && memcmp(&id_a->node_id, &id_b->node_id,
+  return memcmp(&id_a->node_id, &id_b->node_id,
                 3 * sizeof(svn_fs_x__id_part_t)) == 0;
 }
 
@@ -271,12 +275,13 @@ svn_fs_x__id_check_related(const svn_fs_
   if (a == b)
     return TRUE;
 
-  /* If both node_ids start with _ and they have differing transaction
-     IDs, then it is impossible for them to be related. */
-  if (id_a->node_id.revision == SVN_INVALID_REVNUM)
-    if (id_a->txn_id != id_b->txn_id || !svn_fs_x__id_txn_used(id_a->txn_id))
-      return FALSE;
+  /* Items from different txns are unrelated. */
+  if (   svn_fs_x__is_txn(id_a->noderev_id.change_set)
+      && svn_fs_x__is_txn(id_b->noderev_id.change_set)
+      && id_a->noderev_id.change_set != id_a->noderev_id.change_set)
+    return FALSE;
 
+  /* related if they trace back to the same node creation */
   return svn_fs_x__id_part_eq(&id_a->node_id, &id_b->node_id);
 }
 
@@ -294,9 +299,9 @@ int
 svn_fs_x__id_part_compare(const svn_fs_x__id_part_t *a,
                           const svn_fs_x__id_part_t *b)
 {
-  if (a->revision < b->revision)
+  if (a->change_set < b->change_set)
     return -1;
-  if (a->revision > b->revision)
+  if (a->change_set > b->change_set)
     return 1;
 
   return a->number < b->number ? -1 : a->number == b->number ? 0 : 1;
@@ -319,8 +324,8 @@ svn_fs_x__id_txn_create_root(svn_fs_x__t
 
   /* node ID and copy ID are "0" */
 
-  id->txn_id = txn_id;
-  id->rev_item.revision = SVN_INVALID_REVNUM;
+  id->noderev_id.change_set = svn_fs_x__change_set_by_txn(txn_id);
+  id->noderev_id.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
 
   id->generic_id.vtable = &id_vtable;
   id->generic_id.fsap_data = id;
@@ -334,9 +339,10 @@ svn_fs_id_t *svn_fs_x__id_create_root(co
 {
   fs_x__id_t *id = apr_pcalloc(pool, sizeof(*id));
 
-  id->txn_id = SVN_FS_X__INVALID_TXN_ID;
-  id->rev_item.revision = revision;
-  id->rev_item.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
+  /* node ID and copy ID are "0" */
+
+  id->noderev_id.change_set = svn_fs_x__change_set_by_rev(revision);
+  id->noderev_id.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
 
   id->generic_id.vtable = &id_vtable;
   id->generic_id.fsap_data = id;
@@ -355,8 +361,8 @@ svn_fs_x__id_txn_create(const svn_fs_x__
 
   id->node_id = *node_id;
   id->copy_id = *copy_id;
-  id->txn_id = txn_id;
-  id->rev_item.revision = SVN_INVALID_REVNUM;
+
+  id->noderev_id.change_set = svn_fs_x__change_set_by_txn(txn_id);
 
   id->generic_id.vtable = &id_vtable;
   id->generic_id.fsap_data = id;
@@ -376,8 +382,7 @@ svn_fs_x__id_rev_create(const svn_fs_x__
 
   id->node_id = *node_id;
   id->copy_id = *copy_id;
-  id->txn_id = SVN_FS_X__INVALID_TXN_ID;
-  id->rev_item = *rev_item;
+  id->noderev_id = *rev_item;
 
   id->generic_id.vtable = &id_vtable;
   id->generic_id.fsap_data = id;
@@ -438,43 +443,12 @@ svn_fs_x__id_parse(const char *data,
   if (! part_parse(&id->copy_id, str))
     return NULL;
 
-  /* Txn/Rev Id */
+  /* NodeRev Id */
   str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
 
-  if (str[0] == 'r')
-    {
-      apr_int64_t val;
-      svn_error_t *err;
-
-      /* This is a revision type ID */
-      id->txn_id = SVN_FS_X__INVALID_TXN_ID;
-
-      data_copy = str + 1;
-      str = svn_cstring_tokenize("/", &data_copy);
-      if (str == NULL)
-        return NULL;
-      id->rev_item.revision = SVN_STR_TO_REV(str);
-
-      err = svn_cstring_atoi64(&val, data_copy);
-      if (err)
-        {
-          svn_error_clear(err);
-          return NULL;
-        }
-      id->rev_item.number = (apr_uint64_t)val;
-    }
-  else if (str[0] == 't')
-    {
-      /* This is a transaction type ID */
-      id->rev_item.revision = SVN_INVALID_REVNUM;
-      id->rev_item.number = 0;
-
-      if (! txn_id_parse(&id->txn_id, str + 1))
-        return NULL;
-    }
-  else
+  if (! part_parse(&id->noderev_id, str))
     return NULL;
 
   return (svn_fs_id_t *)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=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/id.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/id.h Sat Feb 15 21:31:04 2014
@@ -35,18 +35,44 @@ typedef apr_int64_t svn_fs_x__txn_id_t;
 /* svn_fs_x__txn_id_t value for everything that is not a transaction. */
 #define SVN_FS_X__INVALID_TXN_ID ((svn_fs_x__txn_id_t)(-1))
 
+/* Change set is the umbrella term for transaction and revision in FSX.
+ * Revision numbers (>=0) map 1:1 onto change sets while txns are mapped
+ * onto the negatve value range. */
+typedef apr_int64_t svn_fs_x__change_set_t;
+
+/* Invalid / unused change set number. */
+#define SVN_FS_X__INVALID_CHANGE_SET  ((svn_fs_x__change_set_t)(-1))
+
+/* Return TRUE iff the CHANGE_SET refers to a revision
+   (will return FALSE for SVN_INVALID_REVNUM). */
+svn_boolean_t svn_fs_x__is_revision(svn_fs_x__change_set_t change_set);
+
+/* Return TRUE iff the CHANGE_SET refers to a transaction
+   (will return FALSE for SVN_FS_X__INVALID_TXN_ID). */
+svn_boolean_t svn_fs_x__is_txn(svn_fs_x__change_set_t change_set);
+
+/* Return the revision number that corresponds to CHANGE_SET.
+   Will SVN_INVALID_REVNUM for transactions. */
+svn_revnum_t svn_fs_x__get_revnum(svn_fs_x__change_set_t change_set);
+
+/* Return the transaction ID that corresponds to CHANGE_SET.
+   Will SVN_FS_X__INVALID_TXN_ID for revisions. */
+apr_int64_t svn_fs_x__get_txn_id(svn_fs_x__change_set_t change_set);
+
+/* Convert REVNUM into a change set number */
+svn_fs_x__change_set_t svn_fs_x__change_set_by_rev(svn_revnum_t revnum);
+
+/* Convert TXN_ID into a change set number */
+svn_fs_x__change_set_t svn_fs_x__change_set_by_txn(apr_int64_t txn_id);
+
 /* A rev node ID in FSX consists of a 3 of sub-IDs ("parts") that consist
- * of a creation REVISION number and some revision-local counter value
- * (NUMBER).  Old-style ID parts use global counter values.
+ * of a creation CHANGE_SET number and some revision-local counter value
+ * (NUMBER).
  */
 typedef struct svn_fs_x__id_part_t
 {
-  /* SVN_INVALID_REVNUM for txns -> not a txn, COUNTER must be 0.
-     SVN_INVALID_REVNUM for others -> not assigned to a revision, yet.
-     0                  for others -> old-style ID or the root in rev 0. */
-  svn_revnum_t revision;
+  svn_fs_x__change_set_t change_set;
 
-  /* some numerical value. */
   apr_uint64_t number;
 } svn_fs_x__id_part_t;
 

Modified: subversion/trunk/subversion/libsvn_fs_x/index.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/index.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/index.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/index.c Sat Feb 15 21:31:04 2014
@@ -1763,8 +1763,9 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs,
         }
 
       for (sub_item = 0; sub_item < entry.item_count; ++sub_item)
-        if (entry.items[sub_item].revision == SVN_INVALID_REVNUM)
-          entry.items[sub_item].revision = revision;
+        if (entry.items[sub_item].change_set == SVN_FS_X__INVALID_CHANGE_SET)
+          entry.items[sub_item].change_set
+            = svn_fs_x__change_set_by_rev(revision);
 
       /* end pages if entry is extending beyond their boundaries */
       entry_end = entry.offset + entry.size;
@@ -1800,11 +1801,13 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs,
       /* container contents (only one for non-container items) */
       for (sub_item = 0; sub_item < entry.item_count; ++sub_item)
         {
-          apr_int64_t diff = entry.items[sub_item].revision - last_revision;
+          svn_revnum_t item_rev
+            = svn_fs_x__get_revnum(entry.items[sub_item].change_set);
+          apr_int64_t diff = item_rev - last_revision;
           SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
                                       encode_int(encoded, diff),
                                       iter_pool));
-          last_revision = entry.items[sub_item].revision;
+          last_revision = item_rev;
         }
 
       for (sub_item = 0; sub_item < entry.item_count; ++sub_item)
@@ -2109,7 +2112,8 @@ read_entry(packed_number_stream_t *strea
         {
           SVN_ERR(packed_stream_get(&value, stream));
           revision += (svn_revnum_t)(value % 2 ? -1 - value / 2 : value / 2);
-          entry.items[sub_item].revision = revision;
+          entry.items[sub_item].change_set
+            = svn_fs_x__change_set_by_rev(revision);
         }
 
       for (sub_item = 0; sub_item < entry.item_count; ++sub_item)

Modified: subversion/trunk/subversion/libsvn_fs_x/noderevs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/noderevs.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/noderevs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/noderevs.c Sat Feb 15 21:31:04 2014
@@ -602,11 +602,11 @@ svn_fs_x__write_noderevs_container(svn_s
     {
       binary_id_t *id = &APR_ARRAY_IDX(container->ids, i, binary_id_t);
 
-      svn_packed__add_int(ids_stream, id->node_id.revision);
+      svn_packed__add_int(ids_stream, id->node_id.change_set);
       svn_packed__add_uint(ids_stream, id->node_id.number);
-      svn_packed__add_int(ids_stream, id->copy_id.revision);
+      svn_packed__add_int(ids_stream, id->copy_id.change_set);
       svn_packed__add_uint(ids_stream, id->copy_id.number);
-      svn_packed__add_int(ids_stream, id->rev_id.revision);
+      svn_packed__add_int(ids_stream, id->rev_id.change_set);
       svn_packed__add_uint(ids_stream, id->rev_id.number);
     }
 
@@ -751,11 +751,11 @@ svn_fs_x__read_noderevs_container(svn_fs
     {
       binary_id_t id;
 
-      id.node_id.revision = (svn_revnum_t)svn_packed__get_int(ids_stream);
+      id.node_id.change_set = (svn_revnum_t)svn_packed__get_int(ids_stream);
       id.node_id.number = svn_packed__get_uint(ids_stream);
-      id.copy_id.revision = (svn_revnum_t)svn_packed__get_int(ids_stream);
+      id.copy_id.change_set = (svn_revnum_t)svn_packed__get_int(ids_stream);
       id.copy_id.number = svn_packed__get_uint(ids_stream);
-      id.rev_id.revision = (svn_revnum_t)svn_packed__get_int(ids_stream);
+      id.rev_id.change_set = (svn_revnum_t)svn_packed__get_int(ids_stream);
       id.rev_id.number = svn_packed__get_uint(ids_stream);
 
       APR_ARRAY_PUSH(noderevs->ids, binary_id_t) = id;

Modified: subversion/trunk/subversion/libsvn_fs_x/pack.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/pack.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/pack.c Sat Feb 15 21:31:04 2014
@@ -498,7 +498,7 @@ add_item_rep_mapping(pack_context_t *con
 
   /* index of INFO */
   idx = get_item_array_index(context,
-                             entry->items[0].revision,
+                             entry->items[0].change_set,
                              entry->items[0].number);
 
   /* make sure the index exists in the array */
@@ -521,9 +521,10 @@ get_item(pack_context_t *context,
          svn_boolean_t reset)
 {
   svn_fs_x__p2l_entry_t *result = NULL;
-  if (id->number && id->revision >= context->start_rev)
+  svn_revnum_t revision = svn_fs_x__get_revnum(id->change_set);
+  if (id->number && revision >= context->start_rev)
     {
-      int idx = get_item_array_index(context, id->revision, id->number);
+      int idx = get_item_array_index(context, revision, id->number);
       if (context->reps->nelts > idx)
         {
           result = APR_ARRAY_IDX(context->reps, idx, void *);
@@ -569,7 +570,8 @@ copy_rep_to_temp(pack_context_t *context
       reference_t *reference = apr_pcalloc(context->info_pool,
                                            sizeof(*reference));
       reference->from = entry->items[0];
-      reference->to.revision = rep_header->base_revision;
+      reference->to.change_set
+        = svn_fs_x__change_set_by_rev(rep_header->base_revision);
       reference->to.number = rep_header->base_item_index;
       APR_ARRAY_PUSH(context->references, reference_t *) = reference;
     }
@@ -664,7 +666,8 @@ copy_node_to_temp(pack_context_t *contex
       reference_t *reference = apr_pcalloc(context->info_pool,
                                            sizeof(*reference));
       reference->from = entry->items[0];
-      reference->to.revision = noderev->data_rep->revision;
+      reference->to.change_set
+        = svn_fs_x__change_set_by_rev(noderev->data_rep->revision);
       reference->to.number = noderev->data_rep->item_index;
       APR_ARRAY_PUSH(context->references, reference_t *) = reference;
 
@@ -694,10 +697,10 @@ compare_p2l_info(const svn_fs_x__p2l_ent
   if ((*lhs)->item_count == 0)
     return 1;
   
-  if ((*lhs)->items[0].revision == (*rhs)->items[0].revision)
+  if ((*lhs)->items[0].change_set == (*rhs)->items[0].change_set)
     return (*lhs)->items[0].number > (*rhs)->items[0].number ? -1 : 1;
 
-  return (*lhs)->items[0].revision > (*rhs)->items[0].revision ? -1 : 1;
+  return (*lhs)->items[0].change_set > (*rhs)->items[0].change_set ? -1 : 1;
 }
 
 /* Sort svn_fs_x__p2l_entry_t * array ENTRIES by age.  Place the latest
@@ -730,9 +733,9 @@ static int
 compare_sub_items(const svn_fs_x__id_part_t * const * lhs,
                   const svn_fs_x__id_part_t * const * rhs)
 {
-  return (*lhs)->revision < (*rhs)->revision
+  return (*lhs)->change_set < (*rhs)->change_set
        ? 1
-       : ((*lhs)->revision > (*rhs)->revision ? -1 : 0);
+       : ((*lhs)->change_set > (*rhs)->change_set ? -1 : 0);
 }
 
 /* implements compare_fn_t. Place LHS before RHS, if the latter belongs to
@@ -756,10 +759,10 @@ compare_p2l_info_rev(const sub_item_orde
   rhs_part = rhs->order ? rhs->order[rhs->entry->item_count - 1]
                         : &rhs->entry->items[0];
 
-  if (lhs_part->revision == rhs_part->revision)
+  if (lhs_part->change_set == rhs_part->change_set)
     return 0;
 
-  return lhs_part->revision < rhs_part->revision ? -1 : 1;
+  return lhs_part->change_set < rhs_part->change_set ? -1 : 1;
 }
 
 /* implements compare_fn_t.  Sort descending by PATH, NODE_ID and REVISION.
@@ -1253,7 +1256,8 @@ write_reps_containers(pack_context_t *co
         }
 
       assert(entry->item_count == 1);
-      representation.revision = entry->items[0].revision;
+      representation.revision
+        = svn_fs_x__get_revnum(entry->items[0].change_set);
       representation.item_index = entry->items[0].number;
       svn_fs_x__id_txn_reset(&representation.txn_id);
 
@@ -1714,9 +1718,9 @@ write_l2p_index(pack_context_t *context,
                    : &ordered->entry->items[0];
 
           /* next revision? */
-          if (prev_rev != sub_item->revision)
+          if (prev_rev != svn_fs_x__get_revnum(sub_item->change_set))
             {
-              prev_rev = sub_item->revision;
+              prev_rev = svn_fs_x__get_revnum(sub_item->change_set);
               SVN_ERR(svn_fs_x__l2p_proto_index_add_revision
                           (context->proto_l2p_index, iterpool));
             }

Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.c Sat Feb 15 21:31:04 2014
@@ -1310,7 +1310,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->revision = SVN_INVALID_REVNUM;
+  node_id_p->change_set = SVN_FS_X__INVALID_CHANGE_SET;
   node_id_p->number = node_id;
 
   SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, pool));
@@ -1329,7 +1329,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->revision = SVN_INVALID_REVNUM;
+  copy_id_p->change_set = SVN_FS_X__INVALID_CHANGE_SET;
   copy_id_p->number = copy_id;
 
   SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, pool));
@@ -2089,16 +2089,16 @@ rep_write_contents_close(void *baton)
   if (!old_rep)
     {
       svn_fs_x__p2l_entry_t entry;
-      svn_fs_x__id_part_t rev_item;
-      rev_item.revision = SVN_INVALID_REVNUM;
-      rev_item.number = rep->item_index;
+      svn_fs_x__id_part_t noderev_id;
+      noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
+      noderev_id.number = rep->item_index;
 
       entry.offset = b->rep_offset;
       SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->pool));
       entry.size = offset - b->rep_offset;
       entry.type = SVN_FS_X__ITEM_TYPE_FILE_REP;
       entry.item_count = 1;
-      entry.items = &rev_item;
+      entry.items = &noderev_id;
 
       SVN_ERR(store_sha1_rep_mapping(b->fs, b->noderev, b->pool));
       SVN_ERR(store_p2l_index_entry(b->fs, rep->txn_id, &entry, b->pool));
@@ -2346,7 +2346,7 @@ write_hash_delta_rep(representation_t *r
   else
     {
       svn_fs_x__p2l_entry_t entry;
-      svn_fs_x__id_part_t rev_item;
+      svn_fs_x__id_part_t noderev_id;
 
       /* Write out our cosmetic end marker. */
       SVN_ERR(svn_fs_x__get_file_offset(&rep_end, file, pool));
@@ -2355,15 +2355,15 @@ write_hash_delta_rep(representation_t *r
       SVN_ERR(allocate_item_index(&rep->item_index, fs, txn_id, offset,
                                   pool));
 
-      rev_item.revision = SVN_INVALID_REVNUM;
-      rev_item.number = rep->item_index;
+      noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
+      noderev_id.number = rep->item_index;
 
       entry.offset = offset;
       SVN_ERR(svn_fs_x__get_file_offset(&offset, file, pool));
       entry.size = offset - entry.offset;
       entry.type = item_type;
       entry.item_count = 1;
-      entry.items = &rev_item;
+      entry.items = &noderev_id;
 
       SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
 
@@ -2446,8 +2446,8 @@ get_final_id(svn_fs_x__id_part_t *part,
              apr_uint64_t start_id,
              int format)
 {
-  if (part->revision == SVN_INVALID_REVNUM)
-    part->revision = revision;
+  if (part->change_set == SVN_FS_X__INVALID_CHANGE_SET)
+    part->change_set = svn_fs_x__change_set_by_rev(revision);
 }
 
 /* Copy a node-revision specified by id ID in fileystem FS from a
@@ -2494,10 +2494,11 @@ write_final_rev(const svn_fs_id_t **new_
   node_revision_t *noderev;
   apr_off_t my_offset;
   const svn_fs_id_t *new_id;
-  svn_fs_x__id_part_t node_id, copy_id, rev_item;
+  svn_fs_x__id_part_t node_id, copy_id, noderev_id;
   fs_x_data_t *ffd = fs->fsap_data;
   svn_fs_x__txn_id_t txn_id = svn_fs_x__id_txn_id(id);
   svn_fs_x__p2l_entry_t entry;
+  svn_fs_x__change_set_t change_set = svn_fs_x__change_set_by_rev(rev);
 
   *new_id_p = NULL;
 
@@ -2599,16 +2600,16 @@ write_final_rev(const svn_fs_id_t **new_
   if (at_root)
     {
       /* reference the root noderev from the log-to-phys index */
-      rev_item.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
-      SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, rev_item.number,
+      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(&rev_item.number, fs, txn_id, my_offset,
+    SVN_ERR(allocate_item_index(&noderev_id.number, fs, txn_id, my_offset,
                                 pool));
 
-  rev_item.revision = rev;
-  new_id = svn_fs_x__id_rev_create(&node_id, &copy_id, &rev_item, pool);
+  noderev_id.change_set = change_set;
+  new_id = svn_fs_x__id_rev_create(&node_id, &copy_id, &noderev_id, pool);
 
   noderev->id = new_id;
 
@@ -2658,14 +2659,14 @@ write_final_rev(const svn_fs_id_t **new_
                                   noderev, ffd->format, pool));
 
   /* reference the root noderev from the log-to-phys index */
-  rev_item.revision = SVN_INVALID_REVNUM;
+  noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
 
   entry.offset = my_offset;
   SVN_ERR(svn_fs_x__get_file_offset(&my_offset, file, pool));
   entry.size = my_offset - entry.offset;
   entry.type = SVN_FS_X__ITEM_TYPE_NODEREV;
   entry.item_count = 1;
-  entry.items = &rev_item;
+  entry.items = &noderev_id;
 
   SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
 

Modified: subversion/trunk/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/tree.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/tree.c Sat Feb 15 21:31:04 2014
@@ -3532,7 +3532,7 @@ x_node_origin_rev(svn_revnum_t *revision
 
   SVN_ERR(svn_fs_x__node_id(&given_noderev_id, root, path, pool));
   node_id = svn_fs_x__id_node_id(given_noderev_id);
-  *revision = node_id->revision;
+  *revision = svn_fs_x__get_revnum(node_id->change_set);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/verify.c?rev=1568684&r1=1568683&r2=1568684&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/verify.c Sat Feb 15 21:31:04 2014
@@ -186,8 +186,12 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
         {
           apr_off_t offset;
           apr_uint32_t sub_item;
+          svn_fs_x__id_part_t l2p_item;
           svn_fs_x__id_part_t *p2l_item;
 
+          l2p_item.change_set = svn_fs_x__change_set_by_rev(revision);
+          l2p_item.number = k;
+
           /* get L2P entry.  Ignore unused entries. */
           SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs,
                                         revision, SVN_FS_X__INVALID_TXN_ID,
@@ -208,13 +212,13 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
                                      apr_off_t_toa(pool, offset),
                                      (long)sub_item, revision, (long)k);
 
-          if (p2l_item->number != k || p2l_item->revision != revision)
+          if (!svn_fs_x__id_part_eq(&l2p_item, p2l_item))
             return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT,
                                      NULL,
                                      _("p2l index info LOG r%ld:i%ld"
                                        " does not match "
                                        "l2p index for LOG r%ld:i%ld"),
-                                     p2l_item->revision,
+                                     svn_fs_x__get_revnum(p2l_item->change_set),
                                      (long)p2l_item->number, revision,
                                      (long)k);
 
@@ -288,9 +292,11 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
               apr_off_t l2p_offset;
               apr_uint32_t sub_item;
               svn_fs_x__id_part_t *p2l_item = &entry->items[k];
+              svn_revnum_t revision
+                = svn_fs_x__get_revnum(p2l_item->change_set);
 
               SVN_ERR(svn_fs_x__item_offset(&l2p_offset, &sub_item, fs,
-                                            p2l_item->revision,
+                                            revision,
                                             SVN_FS_X__INVALID_TXN_ID,
                                             p2l_item->number, iterpool));
 
@@ -302,7 +308,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
                                            "LOG r%ld:i%ld for PHYS o%s:s%ld"),
                                          apr_off_t_toa(pool, l2p_offset),
                                          (long)sub_item,
-                                         p2l_item->revision,
+                                         revision,
                                          (long)p2l_item->number,
                                          apr_off_t_toa(pool, entry->offset),
                                          (long)k);



Re: svn commit: r1568684 - in /subversion/trunk/subversion/libsvn_fs_x: cached_data.c changes.c fs_x.c id.c id.h index.c noderevs.c pack.c transaction.c tree.c verify.c

Posted by Stefan Fuhrmann <st...@wandisco.com>.
On Thu, Aug 21, 2014 at 11:43 AM, Evgeny Kotkov <evgeny.kotkov@visualsvn.com
> wrote:

> > Author: stefan2
> > Date: Sat Feb 15 21:31:04 2014
> > New Revision: 1568684
> >
> > URL: http://svn.apache.org/r1568684
> > Log:
> > In FSX, unifify the concept of revision and transaction numbers and
> > call it a "change set".
> >
> > The mapping is trivial (revs == non-neg change sets, txns are negative
> > change set numbers) and a few conversion functions are being provided.
> > As a first step, we use it in fs_x__id_t to represent the noderev_id
> > unifying txn_id and rev_item.  The API is kept unchanged but the textual
> > representation changes.
>
> [...]
>
> > -  /* If both node_ids start with _ and they have differing transaction
> > -     IDs, then it is impossible for them to be related. */
> > -  if (id_a->node_id.revision == SVN_INVALID_REVNUM)
> > -    if (id_a->txn_id != id_b->txn_id ||
> !svn_fs_x__id_txn_used(id_a->txn_id))
> > -      return FALSE;
> > +  /* Items from different txns are unrelated. */
> > +  if (   svn_fs_x__is_txn(id_a->noderev_id.change_set)
> > +      && svn_fs_x__is_txn(id_b->noderev_id.change_set)
> > +      && id_a->noderev_id.change_set != id_a->noderev_id.change_set)
> > +    return FALSE;
>
> This looks like a typo, because the third condition is always false.
>

Yep, it is. Fixed in r1619416.

Thanks!

-- Stefan^2.

Re: svn commit: r1568684 - in /subversion/trunk/subversion/libsvn_fs_x: cached_data.c changes.c fs_x.c id.c id.h index.c noderevs.c pack.c transaction.c tree.c verify.c

Posted by Stefan Fuhrmann <st...@wandisco.com>.
On Thu, Aug 21, 2014 at 11:43 AM, Evgeny Kotkov <evgeny.kotkov@visualsvn.com
> wrote:

> > Author: stefan2
> > Date: Sat Feb 15 21:31:04 2014
> > New Revision: 1568684
> >
> > URL: http://svn.apache.org/r1568684
> > Log:
> > In FSX, unifify the concept of revision and transaction numbers and
> > call it a "change set".
> >
> > The mapping is trivial (revs == non-neg change sets, txns are negative
> > change set numbers) and a few conversion functions are being provided.
> > As a first step, we use it in fs_x__id_t to represent the noderev_id
> > unifying txn_id and rev_item.  The API is kept unchanged but the textual
> > representation changes.
>
> [...]
>
> > -  /* If both node_ids start with _ and they have differing transaction
> > -     IDs, then it is impossible for them to be related. */
> > -  if (id_a->node_id.revision == SVN_INVALID_REVNUM)
> > -    if (id_a->txn_id != id_b->txn_id ||
> !svn_fs_x__id_txn_used(id_a->txn_id))
> > -      return FALSE;
> > +  /* Items from different txns are unrelated. */
> > +  if (   svn_fs_x__is_txn(id_a->noderev_id.change_set)
> > +      && svn_fs_x__is_txn(id_b->noderev_id.change_set)
> > +      && id_a->noderev_id.change_set != id_a->noderev_id.change_set)
> > +    return FALSE;
>
> This looks like a typo, because the third condition is always false.
>

Yep, it is. Fixed in r1619416.

Thanks!

-- Stefan^2.

Re: svn commit: r1568684 - in /subversion/trunk/subversion/libsvn_fs_x: cached_data.c changes.c fs_x.c id.c id.h index.c noderevs.c pack.c transaction.c tree.c verify.c

Posted by Evgeny Kotkov <ev...@visualsvn.com>.
> Author: stefan2
> Date: Sat Feb 15 21:31:04 2014
> New Revision: 1568684
>
> URL: http://svn.apache.org/r1568684
> Log:
> In FSX, unifify the concept of revision and transaction numbers and
> call it a "change set".
>
> The mapping is trivial (revs == non-neg change sets, txns are negative
> change set numbers) and a few conversion functions are being provided.
> As a first step, we use it in fs_x__id_t to represent the noderev_id
> unifying txn_id and rev_item.  The API is kept unchanged but the textual
> representation changes.

[...]

> -  /* If both node_ids start with _ and they have differing transaction
> -     IDs, then it is impossible for them to be related. */
> -  if (id_a->node_id.revision == SVN_INVALID_REVNUM)
> -    if (id_a->txn_id != id_b->txn_id || !svn_fs_x__id_txn_used(id_a->txn_id))
> -      return FALSE;
> +  /* Items from different txns are unrelated. */
> +  if (   svn_fs_x__is_txn(id_a->noderev_id.change_set)
> +      && svn_fs_x__is_txn(id_b->noderev_id.change_set)
> +      && id_a->noderev_id.change_set != id_a->noderev_id.change_set)
> +    return FALSE;

This looks like a typo, because the third condition is always false.


Regards,
Evgeny Kotkov

Re: svn commit: r1568684 - in /subversion/trunk/subversion/libsvn_fs_x: cached_data.c changes.c fs_x.c id.c id.h index.c noderevs.c pack.c transaction.c tree.c verify.c

Posted by Evgeny Kotkov <ev...@visualsvn.com>.
> Author: stefan2
> Date: Sat Feb 15 21:31:04 2014
> New Revision: 1568684
>
> URL: http://svn.apache.org/r1568684
> Log:
> In FSX, unifify the concept of revision and transaction numbers and
> call it a "change set".
>
> The mapping is trivial (revs == non-neg change sets, txns are negative
> change set numbers) and a few conversion functions are being provided.
> As a first step, we use it in fs_x__id_t to represent the noderev_id
> unifying txn_id and rev_item.  The API is kept unchanged but the textual
> representation changes.

[...]

> -  /* If both node_ids start with _ and they have differing transaction
> -     IDs, then it is impossible for them to be related. */
> -  if (id_a->node_id.revision == SVN_INVALID_REVNUM)
> -    if (id_a->txn_id != id_b->txn_id || !svn_fs_x__id_txn_used(id_a->txn_id))
> -      return FALSE;
> +  /* Items from different txns are unrelated. */
> +  if (   svn_fs_x__is_txn(id_a->noderev_id.change_set)
> +      && svn_fs_x__is_txn(id_b->noderev_id.change_set)
> +      && id_a->noderev_id.change_set != id_a->noderev_id.change_set)
> +    return FALSE;

This looks like a typo, because the third condition is always false.


Regards,
Evgeny Kotkov