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 2015/01/02 13:43:43 UTC

svn commit: r1649012 [3/3] - in /subversion/trunk: ./ subversion/libsvn_fs_x/

Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.c?rev=1649012&r1=1649011&r2=1649012&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.c Fri Jan  2 12:43:42 2015
@@ -746,16 +746,16 @@ purge_shared_txn(svn_fs_t *fs,
 
 svn_error_t *
 svn_fs_x__put_node_revision(svn_fs_t *fs,
-                            const svn_fs_id_t *id,
                             node_revision_t *noderev,
                             svn_boolean_t fresh_txn_root,
                             apr_pool_t *pool)
 {
   apr_file_t *noderev_file;
+  const svn_fs_x__id_t *id = &noderev->noderev_id;
 
   noderev->is_fresh_txn_root = fresh_txn_root;
 
-  if (! svn_fs_x__id_is_txn(id))
+  if (! svn_fs_x__is_txn(id->change_set))
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Attempted to write to non-transaction '%s'"),
                              svn_fs_x__id_unparse(id, pool)->data);
@@ -817,7 +817,7 @@ store_sha1_rep_mapping(svn_fs_t *fs,
 }
 
 static svn_error_t *
-unparse_dir_entry(svn_fs_dirent_t *dirent,
+unparse_dir_entry(dirent_t *dirent,
                   svn_stream_t *stream,
                   apr_pool_t *pool)
 {
@@ -825,7 +825,7 @@ unparse_dir_entry(svn_fs_dirent_t *diren
     = apr_psprintf(pool, "%s %s",
                    (dirent->kind == svn_node_file) ? SVN_FS_X__KIND_FILE
                                                    : SVN_FS_X__KIND_DIR,
-                   svn_fs_x__id_unparse(dirent->id, pool)->data);
+                   svn_fs_x__id_unparse(&dirent->id, pool)->data);
 
   SVN_ERR(svn_stream_printf(stream, pool, "K %" APR_SIZE_T_FMT "\n%s\n"
                             "V %" APR_SIZE_T_FMT "\n%s\n",
@@ -845,10 +845,10 @@ unparse_dir_entries(apr_array_header_t *
   int i;
   for (i = 0; i < entries->nelts; ++i)
     {
-      svn_fs_dirent_t *dirent;
+      dirent_t *dirent;
 
       svn_pool_clear(iterpool);
-      dirent = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
+      dirent = APR_ARRAY_IDX(entries, i, dirent_t *);
       SVN_ERR(unparse_dir_entry(dirent, stream, iterpool));
     }
 
@@ -860,13 +860,13 @@ unparse_dir_entries(apr_array_header_t *
 
 /* Return a deep copy of SOURCE and allocate it in RESULT_POOL.
  */
-static svn_fs_path_change2_t *
-path_change_dup(const svn_fs_path_change2_t *source,
+static change_t *
+path_change_dup(const change_t *source,
                 apr_pool_t *result_pool)
 {
-  svn_fs_path_change2_t *result = apr_pmemdup(result_pool, source,
-                                              sizeof(*source));
-  result->node_rev_id = svn_fs_x__id_copy(source->node_rev_id, result_pool);
+  change_t *result = apr_pmemdup(result_pool, source, sizeof(*source));
+  result->path.data = apr_pstrmemdup(result_pool, source->path.data,
+                                     source->path.len);
   if (source->copyfrom_path)
     result->copyfrom_path = apr_pstrdup(result_pool, source->copyfrom_path);
 
@@ -874,9 +874,9 @@ path_change_dup(const svn_fs_path_change
 }
 
 /* Merge the internal-use-only CHANGE into a hash of public-FS
-   svn_fs_path_change2_t CHANGED_PATHS, collapsing multiple changes into a
+   change_t CHANGED_PATHS, collapsing multiple changes into a
    single summarical (is that real word?) change per path.  DELETIONS is
-   also a path->svn_fs_path_change2_t hash and contains all the deletions
+   also a path->change_t hash and contains all the deletions
    that got turned into a replacement. */
 static svn_error_t *
 fold_change(apr_hash_t *changed_paths,
@@ -884,19 +884,18 @@ fold_change(apr_hash_t *changed_paths,
             const change_t *change)
 {
   apr_pool_t *pool = apr_hash_pool_get(changed_paths);
-  svn_fs_path_change2_t *old_change, *new_change;
+  change_t *old_change, *new_change;
   const svn_string_t *path = &change->path;
-  const svn_fs_path_change2_t *info = &change->info;
 
   if ((old_change = apr_hash_get(changed_paths, path->data, path->len)))
     {
       /* This path already exists in the hash, so we have to merge
          this change into the already existing one. */
 
-      /* Sanity check:  only allow NULL node revision ID in the
+      /* Sanity check:  only allow unused node revision IDs in the
          `reset' case. */
-      if ((! info->node_rev_id)
-           && (info->change_kind != svn_fs_path_change_reset))
+      if ((! svn_fs_x__id_used(&change->noderev_id))
+           && (change->change_kind != svn_fs_path_change_reset))
         return svn_error_create
           (SVN_ERR_FS_CORRUPT, NULL,
            _("Missing required node revision ID"));
@@ -904,8 +903,8 @@ fold_change(apr_hash_t *changed_paths,
       /* Sanity check: we should be talking about the same node
          revision ID as our last change except where the last change
          was a deletion. */
-      if (info->node_rev_id
-          && (! svn_fs_x__id_eq(old_change->node_rev_id, info->node_rev_id))
+      if (svn_fs_x__id_used(&change->noderev_id)
+          && (!svn_fs_x__id_eq(&old_change->noderev_id, &change->noderev_id))
           && (old_change->change_kind != svn_fs_path_change_delete))
         return svn_error_create
           (SVN_ERR_FS_CORRUPT, NULL,
@@ -915,16 +914,16 @@ fold_change(apr_hash_t *changed_paths,
       /* Sanity check: an add, replacement, or reset must be the first
          thing to follow a deletion. */
       if ((old_change->change_kind == svn_fs_path_change_delete)
-          && (! ((info->change_kind == svn_fs_path_change_replace)
-                 || (info->change_kind == svn_fs_path_change_reset)
-                 || (info->change_kind == svn_fs_path_change_add))))
+          && (! ((change->change_kind == svn_fs_path_change_replace)
+                 || (change->change_kind == svn_fs_path_change_reset)
+                 || (change->change_kind == svn_fs_path_change_add))))
         return svn_error_create
           (SVN_ERR_FS_CORRUPT, NULL,
            _("Invalid change ordering: non-add change on deleted path"));
 
       /* Sanity check: an add can't follow anything except
          a delete or reset.  */
-      if ((info->change_kind == svn_fs_path_change_add)
+      if ((change->change_kind == svn_fs_path_change_add)
           && (old_change->change_kind != svn_fs_path_change_delete)
           && (old_change->change_kind != svn_fs_path_change_reset))
         return svn_error_create
@@ -932,7 +931,7 @@ fold_change(apr_hash_t *changed_paths,
            _("Invalid change ordering: add change on preexisting path"));
 
       /* Now, merge that change in. */
-      switch (info->change_kind)
+      switch (change->change_kind)
         {
         case svn_fs_path_change_reset:
           /* A reset here will simply remove the path change from the
@@ -958,7 +957,7 @@ fold_change(apr_hash_t *changed_paths,
           else
             {
               /* A deletion overrules a previous change (modify). */
-              new_change = path_change_dup(info, pool);
+              new_change = path_change_dup(change, pool);
               apr_hash_set(changed_paths, path->data, path->len, new_change);
             }
           break;
@@ -969,7 +968,7 @@ fold_change(apr_hash_t *changed_paths,
              so treat it just like a replace.  Remember the original
              deletion such that we are able to delete this path again
              (the replacement may have changed node kind and id). */
-          new_change = path_change_dup(info, pool);
+          new_change = path_change_dup(change, pool);
           new_change->change_kind = svn_fs_path_change_replace;
 
           apr_hash_set(changed_paths, path->data, path->len, new_change);
@@ -987,11 +986,11 @@ fold_change(apr_hash_t *changed_paths,
           /* If the new change modifies some attribute of the node, set
              the corresponding flag, whether it already was set or not.
              Note: We do not reset a flag to FALSE if a change is undone. */
-          if (info->text_mod)
+          if (change->text_mod)
             old_change->text_mod = TRUE;
-          if (info->prop_mod)
+          if (change->prop_mod)
             old_change->prop_mod = TRUE;
-          if (info->mergeinfo_mod == svn_tristate_true)
+          if (change->mergeinfo_mod == svn_tristate_true)
             old_change->mergeinfo_mod = svn_tristate_true;
           break;
         }
@@ -1001,9 +1000,9 @@ fold_change(apr_hash_t *changed_paths,
       /* Add this path.  The API makes no guarantees that this (new) key
          will not be retained.  Thus, we copy the key into the target pool
          to ensure a proper lifetime.  */
-      apr_hash_set(changed_paths,
-                   apr_pstrmemdup(pool, path->data, path->len), path->len,
-                   path_change_dup(info, pool));
+      new_change = path_change_dup(change, pool);
+      apr_hash_set(changed_paths, new_change->path.data,
+                   new_change->path.len, new_change);
     }
 
   return SVN_NO_ERROR;
@@ -1042,8 +1041,8 @@ process_changes(void *baton_p,
      is already a temporary subpool.
   */
 
-  if ((change->info.change_kind == svn_fs_path_change_delete)
-       || (change->info.change_kind == svn_fs_path_change_replace))
+  if ((change->change_kind == svn_fs_path_change_delete)
+       || (change->change_kind == svn_fs_path_change_replace))
     {
       apr_hash_index_t *hi;
 
@@ -1121,63 +1120,35 @@ svn_fs_x__txn_changes_fetch(apr_hash_t *
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_fs_x__paths_changed(apr_hash_t **changed_paths_p,
-                        svn_fs_t *fs,
-                        svn_revnum_t rev,
-                        apr_pool_t *pool)
-{
-  apr_hash_t *changed_paths;
-  apr_array_header_t *changes;
-  int i;
-
-  SVN_ERR(svn_fs_x__get_changes(&changes, fs, rev, pool));
-
-  changed_paths = svn_hash__make(pool);
-  for (i = 0; i < changes->nelts; ++i)
-    {
-      change_t *change = APR_ARRAY_IDX(changes, i, change_t *);
-      apr_hash_set(changed_paths, change->path.data, change->path.len,
-                   &change->info);
-    }
-
-  *changed_paths_p = changed_paths;
-
-  return SVN_NO_ERROR;
-}
-
 /* Copy a revision node-rev SRC into the current transaction TXN_ID in
    the filesystem FS.  This is only used to create the root of a transaction.
    Allocations are from POOL.  */
 static svn_error_t *
 create_new_txn_noderev_from_rev(svn_fs_t *fs,
                                 svn_fs_x__txn_id_t txn_id,
-                                svn_fs_id_t *src,
+                                svn_fs_x__id_t *src,
                                 apr_pool_t *pool)
 {
   node_revision_t *noderev;
-
   SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, src, pool, pool));
 
   /* This must be a root node. */
-  SVN_ERR_ASSERT(   svn_fs_x__id_node_id(noderev->id)->number == 0
-                 && svn_fs_x__id_copy_id(noderev->id)->number == 0);
+  SVN_ERR_ASSERT(   noderev->node_id.number == 0
+                 && noderev->copy_id.number == 0);
 
-  if (svn_fs_x__id_is_txn(noderev->id))
+  if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Copying from transactions not allowed"));
 
-  noderev->predecessor_id = noderev->id;
+  noderev->predecessor_id = noderev->noderev_id;
   noderev->predecessor_count++;
   noderev->copyfrom_path = NULL;
   noderev->copyfrom_rev = SVN_INVALID_REVNUM;
 
   /* For the transaction root, the copyroot never changes. */
+  svn_fs_x__init_txn_root(&noderev->noderev_id, txn_id);
 
-  noderev->id = svn_fs_x__id_txn_create_root(txn_id, pool);
-
-  return svn_fs_x__put_node_revision(fs, noderev->id, noderev, TRUE, pool);
+  return svn_fs_x__put_node_revision(fs, noderev, TRUE, pool);
 }
 
 /* A structure used by get_and_increment_txn_key_body(). */
@@ -1255,7 +1226,7 @@ svn_fs_x__create_txn(svn_fs_txn_t **txn_
 {
   svn_fs_txn_t *txn;
   fs_txn_data_t *ftd;
-  svn_fs_id_t *root_id;
+  svn_fs_x__id_t root_id;
 
   txn = apr_pcalloc(pool, sizeof(*txn));
   ftd = apr_pcalloc(pool, sizeof(*ftd));
@@ -1271,8 +1242,8 @@ svn_fs_x__create_txn(svn_fs_txn_t **txn_
   *txn_p = txn;
 
   /* Create a new root node for this transaction. */
-  SVN_ERR(svn_fs_x__rev_get_root(&root_id, fs, rev, pool, pool));
-  SVN_ERR(create_new_txn_noderev_from_rev(fs, ftd->txn_id, root_id, pool));
+  SVN_ERR(svn_fs_x__rev_get_root(&root_id, fs, rev, pool));
+  SVN_ERR(create_new_txn_noderev_from_rev(fs, ftd->txn_id, &root_id, pool));
 
   /* Create an empty rev file. */
   SVN_ERR(svn_io_file_create_empty(
@@ -1414,18 +1385,17 @@ svn_fs_x__get_txn(transaction_t **txn_p,
 {
   transaction_t *txn;
   node_revision_t *noderev;
-  svn_fs_id_t *root_id;
+  svn_fs_x__id_t root_id;
 
   txn = apr_pcalloc(pool, sizeof(*txn));
   txn->proplist = apr_hash_make(pool);
 
   SVN_ERR(get_txn_proplist(txn->proplist, fs, txn_id, pool));
-  root_id = svn_fs_x__id_txn_create_root(txn_id, pool);
+  svn_fs_x__init_txn_root(&root_id, txn_id);
 
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, root_id, pool, pool));
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, &root_id, pool, pool));
 
-  txn->root_id = svn_fs_x__id_copy(noderev->id, pool);
-  txn->base_id = svn_fs_x__id_copy(noderev->predecessor_id, pool);
+  txn->base_rev = svn_fs_x__get_revnum(noderev->predecessor_id.change_set);
   txn->copies = NULL;
 
   *txn_p = txn;
@@ -1583,7 +1553,7 @@ read_next_ids(apr_uint64_t *node_id,
    Node-ids are guaranteed to be unique to this transction, but may
    not necessarily be sequential.  Perform all allocations in POOL. */
 static svn_error_t *
-get_new_txn_node_id(svn_fs_x__id_part_t *node_id_p,
+get_new_txn_node_id(svn_fs_x__id_t *node_id_p,
                     svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
                     apr_pool_t *pool)
@@ -1602,7 +1572,7 @@ get_new_txn_node_id(svn_fs_x__id_part_t
 }
 
 svn_error_t *
-svn_fs_x__reserve_copy_id(svn_fs_x__id_part_t *copy_id_p,
+svn_fs_x__reserve_copy_id(svn_fs_x__id_t *copy_id_p,
                           svn_fs_t *fs,
                           svn_fs_x__txn_id_t txn_id,
                           apr_pool_t *pool)
@@ -1621,30 +1591,24 @@ svn_fs_x__reserve_copy_id(svn_fs_x__id_p
 }
 
 svn_error_t *
-svn_fs_x__create_node(const svn_fs_id_t **id_p,
-                      svn_fs_t *fs,
+svn_fs_x__create_node(svn_fs_t *fs,
                       node_revision_t *noderev,
-                      const svn_fs_x__id_part_t *copy_id,
+                      const svn_fs_x__id_t *copy_id,
                       svn_fs_x__txn_id_t txn_id,
                       apr_pool_t *pool)
 {
-  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));
+  SVN_ERR(get_new_txn_node_id(&noderev->node_id, fs, txn_id, pool));
 
-  /* Item number within this change set. */
-  SVN_ERR(allocate_item_index(&number, fs, txn_id, pool));
+  /* Assign copy-id. */
+  noderev->copy_id = *copy_id;
 
-  /* 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;
+  /* Noderev-id = Change set and item number within this change set. */
+  noderev->noderev_id.change_set = svn_fs_x__change_set_by_txn(txn_id);
+  SVN_ERR(allocate_item_index(&noderev->noderev_id.number, fs, txn_id,
+                              pool));
 
-  SVN_ERR(svn_fs_x__put_node_revision(fs, noderev->id, noderev, FALSE, pool));
-
-  *id_p = id;
+  SVN_ERR(svn_fs_x__put_node_revision(fs, noderev, FALSE, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1697,13 +1661,13 @@ svn_fs_x__set_entry(svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
                     node_revision_t *parent_noderev,
                     const char *name,
-                    const svn_fs_id_t *id,
+                    const svn_fs_x__id_t *id,
                     svn_node_kind_t kind,
                     apr_pool_t *pool)
 {
   representation_t *rep = parent_noderev->data_rep;
   const char *filename
-    = svn_fs_x__path_txn_node_children(fs, parent_noderev->id, pool);
+    = svn_fs_x__path_txn_node_children(fs, &parent_noderev->noderev_id, pool);
   apr_file_t *file;
   svn_stream_t *out;
   fs_x_data_t *ffd = fs->fsap_data;
@@ -1730,8 +1694,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
       rep->id.change_set = svn_fs_x__change_set_by_txn(txn_id);
       rep->id.number = SVN_FS_X__ITEM_INDEX_UNUSED;
       parent_noderev->data_rep = rep;
-      SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev->id,
-                                          parent_noderev, FALSE, pool));
+      SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev, FALSE, pool));
     }
   else
     {
@@ -1744,8 +1707,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
   /* update directory cache */
     {
       /* build parameters: (name, new entry) pair */
-      const svn_fs_x__id_part_t *key
-        = svn_fs_x__id_noderev_id(parent_noderev->id);
+      const svn_fs_x__id_t *key = &(parent_noderev->noderev_id);
       replace_baton_t baton;
 
       baton.name = name;
@@ -1756,7 +1718,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
           baton.new_entry = apr_pcalloc(subpool, sizeof(*baton.new_entry));
           baton.new_entry->name = name;
           baton.new_entry->kind = kind;
-          baton.new_entry->id = id;
+          baton.new_entry->id = *id;
         }
 
       /* actually update the cached directory (if cached) */
@@ -1769,9 +1731,9 @@ svn_fs_x__set_entry(svn_fs_t *fs,
   /* Append an incremental hash entry for the entry change. */
   if (id)
     {
-      svn_fs_dirent_t entry;
+      dirent_t entry;
       entry.name = name;
-      entry.id = id;
+      entry.id = *id;
       entry.kind = kind;
 
       SVN_ERR(unparse_dir_entry(&entry, out, subpool));
@@ -1791,7 +1753,7 @@ svn_error_t *
 svn_fs_x__add_change(svn_fs_t *fs,
                      svn_fs_x__txn_id_t txn_id,
                      const char *path,
-                     const svn_fs_id_t *id,
+                     const svn_fs_x__id_t *id,
                      svn_fs_path_change_kind_t change_kind,
                      svn_boolean_t text_mod,
                      svn_boolean_t prop_mod,
@@ -1802,7 +1764,7 @@ svn_fs_x__add_change(svn_fs_t *fs,
                      apr_pool_t *pool)
 {
   apr_file_t *file;
-  svn_fs_path_change2_t *change;
+  change_t change;
   apr_hash_t *changes = apr_hash_make(pool);
 
   /* Not using APR_BUFFERED to append change in one atomic write operation. */
@@ -1811,19 +1773,21 @@ svn_fs_x__add_change(svn_fs_t *fs,
                            APR_APPEND | APR_WRITE | APR_CREATE,
                            APR_OS_DEFAULT, pool));
 
-  change = svn_fs__path_change_create_internal(id, change_kind, pool);
-  change->text_mod = text_mod;
-  change->prop_mod = prop_mod;
-  change->mergeinfo_mod = mergeinfo_mod
-                        ? svn_tristate_true
-                        : svn_tristate_false;
-  change->node_kind = node_kind;
-  change->copyfrom_known = TRUE;
-  change->copyfrom_rev = copyfrom_rev;
+  change.path.data = path;
+  change.path.len = strlen(path);
+  change.noderev_id = *id;
+  change.change_kind = change_kind;
+  change.text_mod = text_mod;
+  change.prop_mod = prop_mod;
+  change.mergeinfo_mod = mergeinfo_mod ? svn_tristate_true
+                                       : svn_tristate_false;
+  change.node_kind = node_kind;
+  change.copyfrom_known = TRUE;
+  change.copyfrom_rev = copyfrom_rev;
   if (copyfrom_path)
-    change->copyfrom_path = apr_pstrdup(pool, copyfrom_path);
+    change.copyfrom_path = apr_pstrdup(pool, copyfrom_path);
 
-  svn_hash_sets(changes, path, change);
+  svn_hash_sets(changes, path, &change);
   SVN_ERR(svn_fs_x__write_changes(svn_stream_from_aprfile2(file, TRUE, pool),
                                   fs, changes, FALSE, pool));
 
@@ -1912,11 +1876,11 @@ shards_spanned(int *spanned,
   iterpool = svn_pool_create(pool);
   while (walk-- && noderev->predecessor_count)
     {
+      svn_fs_x__id_t id = noderev->predecessor_id;
+
       svn_pool_clear(iterpool);
-      SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs,
-                                          noderev->predecessor_id, pool,
-                                          iterpool));
-      shard = svn_fs_x__id_rev(noderev->id) / shard_size;
+      SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, &id, pool, iterpool));
+      shard = svn_fs_x__get_revnum(id.change_set) / shard_size;
       if (shard != last_shard)
         {
           ++count;
@@ -2000,10 +1964,9 @@ choose_delta_base(representation_t **rep
   iterpool = svn_pool_create(pool);
   while ((count++) < noderev->predecessor_count)
     {
+      svn_fs_x__id_t id = noderev->predecessor_id;
       svn_pool_clear(iterpool);
-      SVN_ERR(svn_fs_x__get_node_revision(&base, fs,
-                                          base->predecessor_id, pool,
-                                          iterpool));
+      SVN_ERR(svn_fs_x__get_node_revision(&base, fs, &id, pool, iterpool));
     }
   svn_pool_destroy(iterpool);
 
@@ -2061,6 +2024,8 @@ rep_write_cleanup(void *data)
 {
   svn_error_t *err;
   struct rep_write_baton *b = data;
+  svn_fs_x__txn_id_t txn_id
+    = svn_fs_x__get_txn_id(b->noderev->noderev_id.change_set);
 
   /* Truncate and close the protorevfile. */
   err = svn_io_file_trunc(b->file, b->rep_offset, b->scratch_pool);
@@ -2072,9 +2037,9 @@ rep_write_cleanup(void *data)
      file lock which will be removed no matter what since the pool is
      going away. */
   err = svn_error_compose_create(err,
-                                 unlock_proto_rev(b->fs,
-                                     svn_fs_x__id_txn_id(b->noderev->id),
-                                     b->lockcookie, b->scratch_pool));
+                                 unlock_proto_rev(b->fs, txn_id,
+                                                  b->lockcookie,
+                                                  b->scratch_pool));
   if (err)
     {
       apr_status_t rc = err->apr_err;
@@ -2104,6 +2069,8 @@ rep_write_get_baton(struct rep_write_bat
   void *whb;
   int diff_version = 1;
   svn_fs_x__rep_header_t header = { 0 };
+  svn_fs_x__txn_id_t txn_id
+    = svn_fs_x__get_txn_id(noderev->noderev_id.change_set);
 
   b = apr_pcalloc(pool, sizeof(*b));
 
@@ -2117,8 +2084,7 @@ rep_write_get_baton(struct rep_write_bat
   b->noderev = noderev;
 
   /* Open the prototype rev file and seek to its end. */
-  SVN_ERR(get_writable_proto_rev(&file, &b->lockcookie,
-                                 fs, svn_fs_x__id_txn_id(noderev->id),
+  SVN_ERR(get_writable_proto_rev(&file, &b->lockcookie, fs, txn_id,
                                  b->scratch_pool));
 
   b->file = file;
@@ -2324,7 +2290,7 @@ rep_write_contents_close(void *baton)
 
   /* Fill in the rest of the representation field. */
   rep->expanded_size = b->rep_size;
-  txn_id = svn_fs_x__id_txn_id(b->noderev->id);
+  txn_id = svn_fs_x__get_txn_id(b->noderev->noderev_id.change_set);
   rep->id.change_set = svn_fs_x__change_set_by_txn(txn_id);
 
   /* Finalize the checksum. */
@@ -2362,12 +2328,12 @@ rep_write_contents_close(void *baton)
   apr_pool_cleanup_kill(b->scratch_pool, b, rep_write_cleanup);
 
   /* Write out the new node-rev information. */
-  SVN_ERR(svn_fs_x__put_node_revision(b->fs, b->noderev->id, b->noderev,
-                                      FALSE, b->scratch_pool));
+  SVN_ERR(svn_fs_x__put_node_revision(b->fs, b->noderev, FALSE,
+                                      b->scratch_pool));
   if (!old_rep)
     {
       svn_fs_x__p2l_entry_t entry;
-      svn_fs_x__id_part_t noderev_id;
+      svn_fs_x__id_t noderev_id;
       noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
       noderev_id.number = rep->id.number;
 
@@ -2403,10 +2369,11 @@ set_representation(svn_stream_t **conten
 {
   struct rep_write_baton *wb;
 
-  if (! svn_fs_x__id_is_txn(noderev->id))
+  if (! svn_fs_x__is_txn(noderev->noderev_id.change_set))
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Attempted to write to non-transaction '%s'"),
-                             svn_fs_x__id_unparse(noderev->id, pool)->data);
+                             svn_fs_x__id_unparse(&noderev->noderev_id,
+                                                  pool)->data);
 
   SVN_ERR(rep_write_get_baton(&wb, fs, noderev, pool));
 
@@ -2431,37 +2398,26 @@ svn_fs_x__set_contents(svn_stream_t **st
 }
 
 svn_error_t *
-svn_fs_x__create_successor(const svn_fs_id_t **new_id_p,
-                           svn_fs_t *fs,
-                           const svn_fs_id_t *old_idp,
+svn_fs_x__create_successor(svn_fs_t *fs,
                            node_revision_t *new_noderev,
-                           const svn_fs_x__id_part_t *copy_id,
+                           const svn_fs_x__id_t *copy_id,
                            svn_fs_x__txn_id_t txn_id,
                            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, number, pool);
-
-  new_noderev->id = id;
+  new_noderev->copy_id = *copy_id;
+  new_noderev->noderev_id.change_set = svn_fs_x__change_set_by_txn(txn_id);
+  SVN_ERR(allocate_item_index(&new_noderev->noderev_id.number, fs, txn_id,
+                              pool));
 
   if (! new_noderev->copyroot_path)
     {
-      new_noderev->copyroot_path = apr_pstrdup(pool,
-                                               new_noderev->created_path);
-      new_noderev->copyroot_rev = svn_fs_x__id_rev(new_noderev->id);
+      new_noderev->copyroot_path
+        = apr_pstrdup(pool, new_noderev->created_path);
+      new_noderev->copyroot_rev
+        = svn_fs_x__get_revnum(new_noderev->noderev_id.change_set);
     }
 
-  SVN_ERR(svn_fs_x__put_node_revision(fs, new_noderev->id, new_noderev, FALSE,
-                                      pool));
-
-  *new_id_p = id;
+  SVN_ERR(svn_fs_x__put_node_revision(fs, new_noderev, FALSE, pool));
 
   return SVN_NO_ERROR;
 }
@@ -2472,8 +2428,8 @@ svn_fs_x__set_proplist(svn_fs_t *fs,
                        apr_hash_t *proplist,
                        apr_pool_t *pool)
 {
-  const char *filename
-    = svn_fs_x__path_txn_node_props(fs, noderev->id, pool);
+  const svn_fs_x__id_t *id = &noderev->noderev_id;
+  const char *filename = svn_fs_x__path_txn_node_props(fs, id, pool);
   apr_file_t *file;
   svn_stream_t *out;
 
@@ -2489,13 +2445,13 @@ svn_fs_x__set_proplist(svn_fs_t *fs,
   if (!noderev->prop_rep
       || svn_fs_x__is_revision(noderev->prop_rep->id.change_set))
     {
+      svn_fs_x__txn_id_t txn_id
+        = svn_fs_x__get_txn_id(noderev->noderev_id.change_set);
       noderev->prop_rep = apr_pcalloc(pool, sizeof(*noderev->prop_rep));
-      noderev->prop_rep->id.change_set
-        = svn_fs_x__id_noderev_id(noderev->id)->change_set;
+      noderev->prop_rep->id.change_set = 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));
+                                  txn_id, pool));
+      SVN_ERR(svn_fs_x__put_node_revision(fs, noderev, FALSE, pool));
     }
 
   return SVN_NO_ERROR;
@@ -2548,7 +2504,7 @@ write_hash_to_stream(svn_stream_t *strea
   return SVN_NO_ERROR;
 }
 
-/* Implement collection_writer_t writing the svn_fs_dirent_t* array given
+/* Implement collection_writer_t writing the dirent_t* array given
    as BATON. */
 static svn_error_t *
 write_directory_to_stream(svn_stream_t *stream,
@@ -2680,7 +2636,7 @@ write_container_delta_rep(representation
     }
   else
     {
-      svn_fs_x__id_part_t noderev_id;
+      svn_fs_x__id_t noderev_id;
 
       /* Write out our cosmetic end marker. */
       SVN_ERR(svn_fs_x__get_file_offset(&rep_end, file, scratch_pool));
@@ -2731,15 +2687,13 @@ validate_root_noderev(svn_fs_t *fs,
 
   /* Compute HEAD_PREDECESSOR_COUNT. */
   {
-    svn_fs_root_t *head_revision;
-    const svn_fs_id_t *head_root_id;
+    svn_fs_x__id_t head_root_id;
     node_revision_t *head_root_noderev;
 
     /* Get /@HEAD's noderev. */
-    SVN_ERR(svn_fs_x__revision_root(&head_revision, fs, head_revnum, pool));
-    SVN_ERR(svn_fs_x__node_id(&head_root_id, head_revision, "/", pool));
-    SVN_ERR(svn_fs_x__get_node_revision(&head_root_noderev, fs, head_root_id,
-                                        pool, pool));
+    svn_fs_x__init_rev_root(&head_root_id, head_revnum);
+    SVN_ERR(svn_fs_x__get_node_revision(&head_root_noderev, fs,
+                                        &head_root_id, pool, pool));
 
     head_predecessor_count = head_root_noderev->predecessor_count;
   }
@@ -2777,7 +2731,7 @@ validate_root_noderev(svn_fs_t *fs,
  * based on the REVISION.
  */
 static void
-get_final_id(svn_fs_x__id_part_t *part,
+get_final_id(svn_fs_x__id_t *part,
              svn_revnum_t revision)
 {
   if (!svn_fs_x__is_revision(part->change_set))
@@ -2786,8 +2740,8 @@ get_final_id(svn_fs_x__id_part_t *part,
 
 /* Copy a node-revision specified by id ID in fileystem FS from a
    transaction into the proto-rev-file FILE.  Set *NEW_ID_P to a
-   pointer to the new node-id which will be allocated in POOL.
-   If this is a directory, copy all children as well.
+   pointer to the new noderev-id.  If this is a directory, copy all
+   children as well.
 
    START_NODE_ID and START_COPY_ID are
    the first available node and copy ids for this filesystem, for older
@@ -2811,11 +2765,11 @@ get_final_id(svn_fs_x__id_part_t *part,
 
    Temporary allocations are also from POOL. */
 static svn_error_t *
-write_final_rev(const svn_fs_id_t **new_id_p,
+write_final_rev(svn_fs_x__id_t *new_id_p,
                 apr_file_t *file,
                 svn_revnum_t rev,
                 svn_fs_t *fs,
-                const svn_fs_id_t *id,
+                const svn_fs_x__id_t *id,
                 apr_off_t initial_offset,
                 apr_array_header_t *reps_to_cache,
                 apr_hash_t *reps_hash,
@@ -2825,20 +2779,21 @@ 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, noderev_id;
+  svn_fs_x__id_t new_id;
+  svn_fs_x__id_t 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__txn_id_t txn_id = svn_fs_x__get_txn_id(id->change_set);
   svn_fs_x__p2l_entry_t entry;
   svn_fs_x__change_set_t change_set = svn_fs_x__change_set_by_rev(rev);
   svn_stream_t *file_stream;
   apr_pool_t *subpool;
 
-  *new_id_p = NULL;
-
   /* Check to see if this is a transaction node. */
-  if (! svn_fs_x__id_is_txn(id))
-    return SVN_NO_ERROR;
+  if (txn_id == SVN_FS_X__INVALID_TXN_ID)
+    {
+      svn_fs_x__id_reset(new_id_p);
+      return SVN_NO_ERROR;
+    }
 
   subpool = svn_pool_create(pool);
   SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool, subpool));
@@ -2854,15 +2809,15 @@ write_final_rev(const svn_fs_id_t **new_
                                          subpool));
       for (i = 0; i < entries->nelts; ++i)
         {
-          svn_fs_dirent_t *dirent
-            = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
+          dirent_t *dirent = APR_ARRAY_IDX(entries, i, dirent_t *);
 
           svn_pool_clear(subpool);
-          SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
+          SVN_ERR(write_final_rev(&new_id, file, rev, fs, &dirent->id,
                                   initial_offset, reps_to_cache, reps_hash,
                                   reps_pool, FALSE, subpool));
-          if (new_id && (svn_fs_x__id_rev(new_id) == rev))
-            dirent->id = svn_fs_x__id_copy(new_id, pool);
+          if (   svn_fs_x__id_used(&new_id)
+              && (svn_fs_x__get_revnum(new_id.change_set) == rev))
+            dirent->id = new_id;
         }
 
       if (noderev->data_rep
@@ -2912,22 +2867,18 @@ write_final_rev(const svn_fs_id_t **new_
     }
 
   /* Convert our temporary ID into a permanent revision one. */
-  node_id = *svn_fs_x__id_node_id(noderev->id);
-  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);
+  get_final_id(&noderev->node_id, rev);
+  get_final_id(&noderev->copy_id, rev);
+  get_final_id(&noderev->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));
 
-  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;
+  SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset,
+                                noderev->noderev_id.number, pool));
+  new_id = noderev->noderev_id;
 
   if (ffd->rep_sharing_allowed)
     {
@@ -2980,6 +2931,7 @@ write_final_rev(const svn_fs_id_t **new_
   SVN_ERR(svn_stream_close(file_stream));
 
   /* reference the root noderev from the log-to-phys index */
+  noderev_id = noderev->noderev_id;
   noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
 
   entry.offset = my_offset;
@@ -2992,7 +2944,7 @@ write_final_rev(const svn_fs_id_t **new_
   SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
 
   /* Return our ID that references the revision file. */
-  *new_id_p = noderev->id;
+  *new_id_p = new_id;
 
   return SVN_NO_ERROR;
 }
@@ -3014,7 +2966,7 @@ write_final_changed_path_info(apr_off_t
   apr_off_t offset;
   svn_stream_t *stream;
   svn_fs_x__p2l_entry_t entry;
-  svn_fs_x__id_part_t rev_item
+  svn_fs_x__id_t rev_item
     = {SVN_INVALID_REVNUM, SVN_FS_X__ITEM_INDEX_CHANGES};
 
   SVN_ERR(svn_fs_x__get_file_offset(&offset, file, pool));
@@ -3121,7 +3073,7 @@ verify_locks(svn_fs_t *fs,
   for (i = 0; i < changed_paths_sorted->nelts; i++)
     {
       const char *path;
-      svn_fs_path_change2_t *change;
+      change_t *change;
       svn_boolean_t recurse = TRUE;
 
       svn_pool_clear(subpool);
@@ -3285,7 +3237,7 @@ commit_body(void *baton, apr_pool_t *poo
   fs_x_data_t *ffd = cb->fs->fsap_data;
   const char *old_rev_filename, *rev_filename, *proto_filename;
   const char *revprop_filename, *final_revprop;
-  const svn_fs_id_t *root_id, *new_root_id;
+  svn_fs_x__id_t root_id, new_root_id;
   svn_revnum_t old_rev, new_rev;
   apr_file_t *proto_file;
   void *proto_file_lockcookie;
@@ -3338,8 +3290,8 @@ commit_body(void *baton, apr_pool_t *poo
   SVN_ERR(svn_fs_x__get_file_offset(&initial_offset, proto_file, pool));
 
   /* Write out all the node-revisions and directory contents. */
-  root_id = svn_fs_x__id_txn_create_root(txn_id, pool);
-  SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, root_id,
+  svn_fs_x__init_txn_root(&root_id, txn_id);
+  SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, &root_id,
                           initial_offset, cb->reps_to_cache, cb->reps_hash,
                           cb->reps_pool, TRUE, pool));
 
@@ -3588,7 +3540,7 @@ svn_fs_x__open_txn(svn_fs_txn_t **txn_p,
 
   SVN_ERR(svn_fs_x__get_txn(&local_txn, fs, txn_id, pool));
 
-  txn->base_rev = svn_fs_x__id_rev(local_txn->base_id);
+  txn->base_rev = local_txn->base_rev;
 
   txn->vtable = &txn_vtable;
   txn->fsap_data = ftd;
@@ -3612,11 +3564,10 @@ svn_fs_x__txn_proplist(apr_hash_t **tabl
 
 svn_error_t *
 svn_fs_x__delete_node_revision(svn_fs_t *fs,
-                               const svn_fs_id_t *id,
+                               const svn_fs_x__id_t *id,
                                apr_pool_t *pool)
 {
   node_revision_t *noderev;
-
   SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool, pool));
 
   /* Delete any mutable property representation. */
@@ -3631,7 +3582,7 @@ svn_fs_x__delete_node_revision(svn_fs_t
       && noderev->kind == svn_node_dir)
     {
       fs_x_data_t *ffd = fs->fsap_data;
-      const svn_fs_x__id_part_t *key = svn_fs_x__id_noderev_id(id);
+      const svn_fs_x__id_t *key = id;
 
       SVN_ERR(svn_io_remove_file2(svn_fs_x__path_txn_node_children(fs, id,
                                                                    pool),
@@ -3650,16 +3601,15 @@ svn_fs_x__delete_node_revision(svn_fs_t
 /*** Transactions ***/
 
 svn_error_t *
-svn_fs_x__get_txn_ids(const svn_fs_id_t **root_id_p,
-                      const svn_fs_id_t **base_root_id_p,
-                      svn_fs_t *fs,
-                      svn_fs_x__txn_id_t txn_id,
-                      apr_pool_t *pool)
+svn_fs_x__get_base_rev(svn_revnum_t *revnum,
+                       svn_fs_t *fs,
+                       svn_fs_x__txn_id_t txn_id,
+                       apr_pool_t *pool)
 {
   transaction_t *txn;
   SVN_ERR(svn_fs_x__get_txn(&txn, fs, txn_id, pool));
-  *root_id_p = txn->root_id;
-  *base_root_id_p = txn->base_id;
+  *revnum = txn->base_rev;
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.h?rev=1649012&r1=1649011&r2=1649012&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.h Fri Jan  2 12:43:42 2015
@@ -72,12 +72,11 @@ svn_fs_x__with_all_locks(svn_fs_t *fs,
                          void *baton,
                          apr_pool_t *pool);
 
-/* Store NODEREV as the node-revision for the node whose id is ID in
-   FS, after setting its is_fresh_txn_root to FRESH_TXN_ROOT.  Do any
-   necessary temporary allocation in POOL. */
+/* Store NODEREV as the node-revision in the transaction defined by NODEREV's
+   ID within FS, after setting its is_fresh_txn_root to FRESH_TXN_ROOT.  Do
+   any necessary temporary allocation in POOL. */
 svn_error_t *
 svn_fs_x__put_node_revision(svn_fs_t *fs,
-                            const svn_fs_id_t *id,
                             node_revision_t *noderev,
                             svn_boolean_t fresh_txn_root,
                             apr_pool_t *pool);
@@ -91,15 +90,6 @@ svn_fs_x__txn_changes_fetch(apr_hash_t *
                             svn_fs_x__txn_id_t txn_id,
                             apr_pool_t *pool);
 
-/* Find the paths which were changed in revision REV of filesystem FS
-   and store them in *CHANGED_PATHS_P.  Get any temporary allocations
-   from POOL. */
-svn_error_t *
-svn_fs_x__paths_changed(apr_hash_t **changed_paths_p,
-                        svn_fs_t *fs,
-                        svn_revnum_t rev,
-                        apr_pool_t *pool);
-
 /* Create a new transaction in filesystem FS, based on revision REV,
    and store it in *TXN_P.  Allocate all necessary variables from
    POOL. */
@@ -135,21 +125,19 @@ svn_fs_x__get_txn(transaction_t **txn_p,
 /* Return the next available copy_id in *COPY_ID for the transaction
    TXN_ID in filesystem FS.  Allocate space in POOL. */
 svn_error_t *
-svn_fs_x__reserve_copy_id(svn_fs_x__id_part_t *copy_id_p,
+svn_fs_x__reserve_copy_id(svn_fs_x__id_t *copy_id_p,
                           svn_fs_t *fs,
                           svn_fs_x__txn_id_t txn_id,
                           apr_pool_t *pool);
 
 /* Create an entirely new mutable node in the filesystem FS, whose
-   node-revision is NODEREV.  Set *ID_P to the new node revision's ID.
-   Use POOL for any temporary allocation.  COPY_ID is the copy_id to
-   use in the node revision ID.  TXN_ID is the Subversion transaction
-   under which this occurs. */
+   node-revision is NODEREV.  COPY_ID is the copy_id to use in the
+   node revision ID.  TXN_ID is the Subversion transaction  under
+   which this occurs. */
 svn_error_t *
-svn_fs_x__create_node(const svn_fs_id_t **id_p,
-                      svn_fs_t *fs,
+svn_fs_x__create_node(svn_fs_t *fs,
                       node_revision_t *noderev,
-                      const svn_fs_x__id_part_t *copy_id,
+                      const svn_fs_x__id_t *copy_id,
                       svn_fs_x__txn_id_t txn_id,
                       apr_pool_t *pool);
 
@@ -174,12 +162,12 @@ svn_fs_x__set_entry(svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
                     node_revision_t *parent_noderev,
                     const char *name,
-                    const svn_fs_id_t *id,
+                    const svn_fs_x__id_t *id,
                     svn_node_kind_t kind,
                     apr_pool_t *pool);
 
 /* Add a change to the changes record for filesystem FS in transaction
-   TXN_ID.  Mark path PATH, having node-id ID, as changed according to
+   TXN_ID.  Mark path PATH, having noderev-id ID, as changed according to
    the type in CHANGE_KIND.  If the text representation was changed set
    TEXT_MOD to TRUE, and likewise for PROP_MOD as well as MERGEINFO_MOD.
    If this change was the result of a copy, set COPYFROM_REV and
@@ -190,7 +178,7 @@ svn_error_t *
 svn_fs_x__add_change(svn_fs_t *fs,
                      svn_fs_x__txn_id_t txn_id,
                      const char *path,
-                     const svn_fs_id_t *id,
+                     const svn_fs_x__id_t *id,
                      svn_fs_path_change_kind_t change_kind,
                      svn_boolean_t text_mod,
                      svn_boolean_t prop_mod,
@@ -210,13 +198,11 @@ svn_fs_x__set_contents(svn_stream_t **st
                        apr_pool_t *pool);
 
 /* Create a node revision in FS which is an immediate successor of
-   OLD_ID, whose contents are NEW_NR.  Set *NEW_ID_P to the new node
-   revision's ID.  Use POOL for any temporary allocation.
+   NEW_NODEREV's predecessor.  Use POOL for any temporary allocation.
 
-   COPY_ID, if non-NULL, is a key into the `copies' table, and
+   COPY_ID, is a key into the `copies' table, and
    indicates that this new node is being created as the result of a
-   copy operation, and specifically which operation that was.  If
-   COPY_ID is NULL, then re-use the copy ID from the predecessor node.
+   copy operation, and specifically which operation that was.
 
    TXN_ID is the Subversion transaction under which this occurs.
 
@@ -224,11 +210,9 @@ svn_fs_x__set_contents(svn_stream_t **st
    contents will change frequently, and will avoid representing other
    nodes as deltas against this node's contents.  */
 svn_error_t *
-svn_fs_x__create_successor(const svn_fs_id_t **new_id_p,
-                           svn_fs_t *fs,
-                           const svn_fs_id_t *old_idp,
+svn_fs_x__create_successor(svn_fs_t *fs,
                            node_revision_t *new_noderev,
-                           const svn_fs_x__id_part_t *copy_id,
+                           const svn_fs_x__id_t *copy_id,
                            svn_fs_x__txn_id_t txn_id,
                            apr_pool_t *pool);
 
@@ -291,12 +275,11 @@ svn_fs_x__txn_proplist(apr_hash_t **tabl
    temporary allocations in POOL. */
 svn_error_t *
 svn_fs_x__delete_node_revision(svn_fs_t *fs,
-                               const svn_fs_id_t *id,
+                               const svn_fs_x__id_t *id,
                                apr_pool_t *pool);
 
 /* Retrieve information about the Subversion transaction SVN_TXN from
    the `transactions' table of FS, allocating from POOL.  Set
-   *ROOT_ID_P to the ID of the transaction's root directory.  Set
    *BASE_ROOT_ID_P to the ID of the root directory of the
    transaction's base revision.
 
@@ -308,11 +291,10 @@ svn_fs_x__delete_node_revision(svn_fs_t
 
    Allocate *ROOT_ID_P and *BASE_ROOT_ID_P in POOL.  */
 svn_error_t *
-svn_fs_x__get_txn_ids(const svn_fs_id_t **root_id_p,
-                      const svn_fs_id_t **base_root_id_p,
-                      svn_fs_t *fs,
-                      svn_fs_x__txn_id_t txn_id,
-                      apr_pool_t *pool);
+svn_fs_x__get_base_rev(svn_revnum_t *revnum,
+                       svn_fs_t *fs,
+                       svn_fs_x__txn_id_t txn_id,
+                       apr_pool_t *pool);
 
 /* Find the value of the property named PROPNAME in transaction TXN.
    Return the contents in *VALUE_P.  The contents will be allocated

Modified: subversion/trunk/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/tree.c?rev=1649012&r1=1649011&r2=1649012&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/tree.c Fri Jan  2 12:43:42 2015
@@ -56,7 +56,7 @@
 #include "lock.h"
 #include "tree.h"
 #include "fs_x.h"
-#include "id.h"
+#include "fs_id.h"
 #include "temp_serializer.h"
 #include "cached_data.h"
 #include "transaction.h"
@@ -815,8 +815,8 @@ get_copy_inheritance(copy_id_inherit_t *
                      parent_path_t *child,
                      apr_pool_t *pool)
 {
-  const svn_fs_id_t *child_id, *parent_id, *copyroot_id;
-  const svn_fs_x__id_part_t *child_copy_id, *parent_copy_id;
+  svn_fs_x__id_t child_copy_id, parent_copy_id;
+  svn_boolean_t related;
   const char *id_path = NULL;
   svn_fs_root_t *copyroot_root;
   dag_node_t *copyroot_node;
@@ -826,13 +826,11 @@ get_copy_inheritance(copy_id_inherit_t *
   SVN_ERR_ASSERT(child && child->parent);
 
   /* Initialize some convenience variables. */
-  child_id = svn_fs_x__dag_get_id(child->node);
-  parent_id = svn_fs_x__dag_get_id(child->parent->node);
-  child_copy_id = svn_fs_x__id_copy_id(child_id);
-  parent_copy_id = svn_fs_x__id_copy_id(parent_id);
+  SVN_ERR(svn_fs_x__dag_get_copy_id(&child_copy_id, child->node));
+  SVN_ERR(svn_fs_x__dag_get_copy_id(&parent_copy_id, child->parent->node));
 
   /* If this child is already mutable, we have nothing to do. */
-  if (svn_fs_x__id_is_txn(child_id))
+  if (svn_fs_x__dag_check_mutable(child->node))
     {
       *inherit_p = copy_id_inherit_self;
       *copy_src_path = NULL;
@@ -846,14 +844,14 @@ get_copy_inheritance(copy_id_inherit_t *
 
   /* Special case: if the child's copy ID is '0', use the parent's
      copy ID. */
-  if (svn_fs_x__id_part_is_root(child_copy_id))
+  if (svn_fs_x__id_is_root(&child_copy_id))
     return SVN_NO_ERROR;
 
   /* Compare the copy IDs of the child and its parent.  If they are
      the same, then the child is already on the same branch as the
      parent, and should use the same mutability copy ID that the
      parent will use. */
-  if (svn_fs_x__id_part_eq(child_copy_id, parent_copy_id))
+  if (svn_fs_x__id_eq(&child_copy_id, &parent_copy_id))
     return SVN_NO_ERROR;
 
   /* If the child is on the same branch that the parent is on, the
@@ -864,12 +862,12 @@ get_copy_inheritance(copy_id_inherit_t *
      or if it is a branch point that we are accessing via its original
      copy destination path. */
   SVN_ERR(svn_fs_x__dag_get_copyroot(&copyroot_rev, &copyroot_path,
-                                      child->node));
+                                     child->node));
   SVN_ERR(svn_fs_x__revision_root(&copyroot_root, fs, copyroot_rev, pool));
   SVN_ERR(get_dag(&copyroot_node, copyroot_root, copyroot_path, FALSE, pool));
-  copyroot_id = svn_fs_x__dag_get_id(copyroot_node);
 
-  if (svn_fs_x__id_compare(copyroot_id, child_id) == svn_fs_node_unrelated)
+  SVN_ERR(svn_fs_x__dag_related_node(&related, copyroot_node, child->node));
+  if (!related)
     return SVN_NO_ERROR;
 
   /* Determine if we are looking at the child via its original path or
@@ -962,8 +960,7 @@ try_match_last_node(dag_node_t **node_p,
          the right lookup result irrespective of how we found it. */
       const char *created_path
         = svn_fs_x__dag_get_created_path(node);
-      svn_revnum_t revision;
-      SVN_ERR(svn_fs_x__dag_get_revision(&revision, node, scratch_pool));
+      svn_revnum_t revision = svn_fs_x__dag_get_revision(node);
 
       /* Is it an exact match? */
       if (revision == root->rev && strcmp(created_path, path) == 0)
@@ -1237,15 +1234,15 @@ make_path_mutable(svn_fs_root_t *root,
   /* Are we trying to clone the root, or somebody's child node?  */
   if (parent_path->parent)
     {
-      const svn_fs_id_t *parent_id, *child_id, *copyroot_id;
-      svn_fs_x__id_part_t copy_id = { SVN_INVALID_REVNUM, 0 };
-      svn_fs_x__id_part_t *copy_id_ptr = &copy_id;
+      svn_fs_x__id_t copy_id = { SVN_INVALID_REVNUM, 0 };
+      svn_fs_x__id_t *copy_id_ptr = &copy_id;
       copy_id_inherit_t inherit = parent_path->copy_inherit;
       const char *clone_path, *copyroot_path;
       svn_revnum_t copyroot_rev;
       svn_boolean_t is_parent_copyroot = FALSE;
       svn_fs_root_t *copyroot_root;
       dag_node_t *copyroot_node;
+      svn_boolean_t related;
 
       /* We're trying to clone somebody's child.  Make sure our parent
          is mutable.  */
@@ -1255,8 +1252,8 @@ make_path_mutable(svn_fs_root_t *root,
       switch (inherit)
         {
         case copy_id_inherit_parent:
-          parent_id = svn_fs_x__dag_get_id(parent_path->parent->node);
-          copy_id = *svn_fs_x__id_copy_id(parent_id);
+          SVN_ERR(svn_fs_x__dag_get_copy_id(&copy_id,
+                                            parent_path->parent->node));
           break;
 
         case copy_id_inherit_new:
@@ -1282,10 +1279,9 @@ make_path_mutable(svn_fs_root_t *root,
       SVN_ERR(get_dag(&copyroot_node, copyroot_root, copyroot_path,
                       FALSE, pool));
 
-      child_id = svn_fs_x__dag_get_id(parent_path->node);
-      copyroot_id = svn_fs_x__dag_get_id(copyroot_node);
-      if (!svn_fs_x__id_part_eq(svn_fs_x__id_node_id(child_id),
-                                svn_fs_x__id_node_id(copyroot_id)))
+      SVN_ERR(svn_fs_x__dag_related_node(&related, copyroot_node,
+                                         parent_path->node));
+      if (!related)
         is_parent_copyroot = TRUE;
 
       /* Now make this node mutable.  */
@@ -1381,7 +1377,7 @@ static svn_error_t *
 add_change(svn_fs_t *fs,
            svn_fs_x__txn_id_t txn_id,
            const char *path,
-           const svn_fs_id_t *noderev_id,
+           const svn_fs_x__id_t *noderev_id,
            svn_fs_path_change_kind_t change_kind,
            svn_boolean_t text_mod,
            svn_boolean_t prop_mod,
@@ -1405,12 +1401,14 @@ add_change(svn_fs_t *fs,
 
 /* Get the id of a node referenced by path PATH in ROOT.  Return the
    id in *ID_P allocated in POOL. */
-svn_error_t *
-svn_fs_x__node_id(const svn_fs_id_t **id_p,
-                  svn_fs_root_t *root,
-                  const char *path,
-                  apr_pool_t *pool)
+static svn_error_t *
+x_node_id(const svn_fs_id_t **id_p,
+          svn_fs_root_t *root,
+          const char *path,
+          apr_pool_t *pool)
 {
+  const svn_fs_x__id_t *noderev_id;
+
   if ((! root->is_txn_root)
       && (path[0] == '\0' || ((path[0] == '/') && (path[1] == '\0'))))
     {
@@ -1419,15 +1417,19 @@ svn_fs_x__node_id(const svn_fs_id_t **id
          svn_fs_root_t object, and never changes when it's a revision
          root, so we can just reach in and grab it directly. */
       dag_node_t *root_dir = root->fsap_data;
-      *id_p = svn_fs_x__id_copy(svn_fs_x__dag_get_id(root_dir), pool);
+      noderev_id = svn_fs_x__dag_get_id(root_dir);
     }
   else
     {
       dag_node_t *node;
 
       SVN_ERR(get_dag(&node, root, path, FALSE, pool));
-      *id_p = svn_fs_x__id_copy(svn_fs_x__dag_get_id(node), pool);
+      noderev_id = svn_fs_x__dag_get_id(node);
     }
+
+  *id_p = svn_fs_x__id_create(svn_fs_x__id_create_context(root->fs, pool),
+                              noderev_id, pool);
+
   return SVN_NO_ERROR;
 }
 
@@ -1438,8 +1440,7 @@ x_node_relation(svn_fs_node_relation_t *
                 apr_pool_t *pool)
 {
   dag_node_t *node;
-  const svn_fs_id_t *id;
-  svn_fs_x__id_part_t noderev_id_a, noderev_id_b, node_id_a, node_id_b;
+  svn_fs_x__id_t noderev_id_a, noderev_id_b, node_id_a, node_id_b;
 
   /* Root paths are a common special case. */
   svn_boolean_t a_is_root_dir
@@ -1475,18 +1476,16 @@ x_node_relation(svn_fs_node_relation_t *
   /* We checked for all separations between ID spaces (repos, txn).
    * Now, we can simply test for the ID values themselves. */
   SVN_ERR(get_dag(&node, root_a, path_a, FALSE, pool));
-  id = svn_fs_x__dag_get_id(node);
-  noderev_id_a = *svn_fs_x__id_noderev_id(id);
-  node_id_a = *svn_fs_x__id_node_id(id);
+  noderev_id_a = *svn_fs_x__dag_get_id(node);
+  SVN_ERR(svn_fs_x__dag_get_node_id(&node_id_a, node));
 
   SVN_ERR(get_dag(&node, root_b, path_b, FALSE, pool));
-  id = svn_fs_x__dag_get_id(node);
-  noderev_id_b = *svn_fs_x__id_noderev_id(id);
-  node_id_b = *svn_fs_x__id_node_id(id);
+  noderev_id_b = *svn_fs_x__dag_get_id(node);
+  SVN_ERR(svn_fs_x__dag_get_node_id(&node_id_b, node));
 
-  if (svn_fs_x__id_part_eq(&noderev_id_a, &noderev_id_b))
+  if (svn_fs_x__id_eq(&noderev_id_a, &noderev_id_b))
     *relation = svn_fs_node_same;
-  else if (svn_fs_x__id_part_eq(&node_id_a, &node_id_b))
+  else if (svn_fs_x__id_eq(&node_id_a, &node_id_b))
     *relation = svn_fs_node_common_ancestor;
   else
     *relation = svn_fs_node_unrelated;
@@ -1503,7 +1502,9 @@ svn_fs_x__node_created_rev(svn_revnum_t
   dag_node_t *node;
 
   SVN_ERR(get_dag(&node, root, path, FALSE, pool));
-  return svn_fs_x__dag_get_revision(revision, node, pool);
+  *revision = svn_fs_x__dag_get_revision(node);
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -1532,14 +1533,12 @@ node_kind(svn_node_kind_t *kind_p,
           const char *path,
           apr_pool_t *pool)
 {
-  const svn_fs_id_t *node_id;
   dag_node_t *node;
 
   /* Get the node id. */
-  SVN_ERR(svn_fs_x__node_id(&node_id, root, path, pool));
+  SVN_ERR(get_dag(&node, root, path, FALSE, pool));
 
   /* Use the node id to get the real kind. */
-  SVN_ERR(svn_fs_x__dag_get_node(&node, root->fs, node_id, pool));
   *kind_p = svn_fs_x__dag_node_kind(node);
 
   return SVN_NO_ERROR;
@@ -1755,12 +1754,13 @@ conflict_err(svn_stringbuf_t *conflict_p
                            _("Conflict at '%s'"), path);
 }
 
-/* Compare the directory representations at nodes LHS and RHS and set
+/* Compare the directory representations at nodes LHS and RHS in FS and set
  * *CHANGED to TRUE, if at least one entry has been added or removed them.
  * Use POOL for temporary allocations.
  */
 static svn_error_t *
 compare_dir_structure(svn_boolean_t *changed,
+                      svn_fs_t *fs,
                       dag_node_t *lhs,
                       dag_node_t *rhs,
                       apr_pool_t *pool)
@@ -1768,6 +1768,7 @@ compare_dir_structure(svn_boolean_t *cha
   apr_array_header_t *lhs_entries;
   apr_array_header_t *rhs_entries;
   int i;
+  apr_pool_t *iterpool = svn_pool_create(pool);
 
   SVN_ERR(svn_fs_x__dag_dir_entries(&lhs_entries, lhs, pool));
   SVN_ERR(svn_fs_x__dag_dir_entries(&rhs_entries, rhs, pool));
@@ -1776,23 +1777,40 @@ compare_dir_structure(svn_boolean_t *cha
      entries one-by-one without binary lookup etc. */
   for (i = 0; i < lhs_entries->nelts; ++i)
     {
-      svn_fs_dirent_t *lhs_entry
-        = APR_ARRAY_IDX(lhs_entries, i, svn_fs_dirent_t *);
-      svn_fs_dirent_t *rhs_entry
-        = APR_ARRAY_IDX(rhs_entries, i, svn_fs_dirent_t *);
-
-      if (strcmp(lhs_entry->name, rhs_entry->name)
-          || !svn_fs_x__id_part_eq(svn_fs_x__id_node_id(lhs_entry->id),
-                                   svn_fs_x__id_node_id(rhs_entry->id))
-          || !svn_fs_x__id_part_eq(svn_fs_x__id_copy_id(lhs_entry->id),
-                                   svn_fs_x__id_copy_id(rhs_entry->id)))
+      dirent_t *lhs_entry = APR_ARRAY_IDX(lhs_entries, i, dirent_t *);
+      dirent_t *rhs_entry = APR_ARRAY_IDX(rhs_entries, i, dirent_t *);
+
+      if (strcmp(lhs_entry->name, rhs_entry->name) == 0)
         {
-          *changed = TRUE;
-          return SVN_NO_ERROR;
+          svn_boolean_t same_history;
+          dag_node_t *lhs_node, *rhs_node;
+
+          /* Unchanged entry? */
+          if (!svn_fs_x__id_eq(&lhs_entry->id, &rhs_entry->id))
+            continue;
+
+          /* We get here rarely. */
+          svn_pool_clear(iterpool);
+
+          /* Modified but not copied / replaced or anything? */
+          SVN_ERR(svn_fs_x__dag_get_node(&lhs_node, fs, &lhs_entry->id, 
+                                         iterpool));
+          SVN_ERR(svn_fs_x__dag_get_node(&rhs_node, fs, &rhs_entry->id, 
+                                         iterpool));
+          SVN_ERR(svn_fs_x__dag_same_line_of_history(&same_history,
+                                                     lhs_node, rhs_node));
+          if (same_history)
+            continue;
         }
+
+      /* This is a different entry. */
+      *changed = TRUE;
+      break;
     }
 
+  svn_pool_destroy(iterpool);
   *changed = FALSE;
+
   return SVN_NO_ERROR;
 }
 
@@ -1828,7 +1846,7 @@ merge(svn_stringbuf_t *conflict_p,
       apr_int64_t *mergeinfo_increment_out,
       apr_pool_t *pool)
 {
-  const svn_fs_id_t *source_id, *target_id, *ancestor_id;
+  const svn_fs_x__id_t *source_id, *target_id, *ancestor_id;
   apr_array_header_t *s_entries, *t_entries, *a_entries;
   int i, s_idx = -1, t_idx = -1;
   svn_fs_t *fs;
@@ -1961,14 +1979,14 @@ merge(svn_stringbuf_t *conflict_p,
 
     /* Get node revisions for our id's. */
     scratch_pool = svn_pool_create(pool);
-    SVN_ERR(svn_fs_x__get_node_revision(&tgt_nr, fs, target_id, pool,
-                                        scratch_pool));
+    SVN_ERR(svn_fs_x__get_node_revision(&tgt_nr, fs, target_id,
+                                        pool, scratch_pool));
     svn_pool_clear(scratch_pool);
-    SVN_ERR(svn_fs_x__get_node_revision(&anc_nr, fs, ancestor_id, pool,
-                                        scratch_pool));
+    SVN_ERR(svn_fs_x__get_node_revision(&anc_nr, fs, ancestor_id,
+                                        pool, scratch_pool));
     svn_pool_clear(scratch_pool);
-    SVN_ERR(svn_fs_x__get_node_revision(&src_nr, fs, source_id, pool,
-                                        scratch_pool));
+    SVN_ERR(svn_fs_x__get_node_revision(&src_nr, fs, source_id,
+                                        pool, scratch_pool));
     svn_pool_destroy(scratch_pool);
 
     /* Now compare the prop-keys of the skels.  Note that just because
@@ -1988,7 +2006,7 @@ merge(svn_stringbuf_t *conflict_p,
            to its entries, i.e. there were no additions or removals.
            Those could cause update problems to the working copy. */
         svn_boolean_t changed;
-        SVN_ERR(compare_dir_structure(&changed, source, ancestor, pool));
+        SVN_ERR(compare_dir_structure(&changed, fs, source, ancestor, pool));
 
         if (changed)
           return conflict_err(conflict_p, target_path);
@@ -2006,44 +2024,44 @@ merge(svn_stringbuf_t *conflict_p,
   iterpool = svn_pool_create(pool);
   for (i = 0; i < a_entries->nelts; ++i)
     {
-      svn_fs_dirent_t *s_entry, *t_entry, *a_entry;
+      dirent_t *s_entry, *t_entry, *a_entry;
       svn_pool_clear(iterpool);
 
-      a_entry = APR_ARRAY_IDX(a_entries, i, svn_fs_dirent_t *);
+      a_entry = APR_ARRAY_IDX(a_entries, i, dirent_t *);
       s_entry = svn_fs_x__find_dir_entry(s_entries, a_entry->name, &s_idx);
       t_entry = svn_fs_x__find_dir_entry(t_entries, a_entry->name, &t_idx);
 
       /* No changes were made to this entry while the transaction was
          in progress, so do nothing to the target. */
-      if (s_entry && svn_fs_x__id_eq(a_entry->id, s_entry->id))
+      if (s_entry && svn_fs_x__id_eq(&a_entry->id, &s_entry->id))
         continue;
 
       /* A change was made to this entry while the transaction was in
          process, but the transaction did not touch this entry. */
-      else if (t_entry && svn_fs_x__id_eq(a_entry->id, t_entry->id))
+      else if (t_entry && svn_fs_x__id_eq(&a_entry->id, &t_entry->id))
         {
           apr_int64_t mergeinfo_start;
           apr_int64_t mergeinfo_end;
 
           dag_node_t *t_ent_node;
-          SVN_ERR(svn_fs_x__dag_get_node(&t_ent_node, fs,
-                                         t_entry->id, iterpool));
+          SVN_ERR(svn_fs_x__dag_get_node(&t_ent_node, fs, &t_entry->id,
+                                         iterpool));
           SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&mergeinfo_start,
-                                                      t_ent_node));
+                                                    t_ent_node));
           mergeinfo_increment -= mergeinfo_start;
 
           if (s_entry)
             {
               dag_node_t *s_ent_node;
-              SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs,
-                                             s_entry->id, iterpool));
+              SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs, &s_entry->id,
+                                             iterpool));
 
               SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&mergeinfo_end,
                                                         s_ent_node));
               mergeinfo_increment += mergeinfo_end;
 
               SVN_ERR(svn_fs_x__dag_set_entry(target, a_entry->name,
-                                              s_entry->id,
+                                              &s_entry->id,
                                               s_entry->kind,
                                               txn_id,
                                               iterpool));
@@ -2063,6 +2081,7 @@ merge(svn_stringbuf_t *conflict_p,
           dag_node_t *s_ent_node, *t_ent_node, *a_ent_node;
           const char *new_tpath;
           apr_int64_t sub_mergeinfo_increment;
+          svn_boolean_t s_a_same, t_a_same;
 
           /* If SOURCE-ENTRY and TARGET-ENTRY are both null, that's a
              double delete; if one of them is null, that's a delete versus
@@ -2082,16 +2101,21 @@ merge(svn_stringbuf_t *conflict_p,
                                                  a_entry->name,
                                                  iterpool));
 
+          /* Fetch DAG nodes to efficiently access ID parts. */
+          SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs, &s_entry->id,
+                                         iterpool));
+          SVN_ERR(svn_fs_x__dag_get_node(&t_ent_node, fs, &t_entry->id,
+                                         iterpool));
+          SVN_ERR(svn_fs_x__dag_get_node(&a_ent_node, fs, &a_entry->id,
+                                         iterpool));
+
           /* If either SOURCE-ENTRY or TARGET-ENTRY is not a direct
              modification of ANCESTOR-ENTRY, declare a conflict. */
-          if (!svn_fs_x__id_part_eq(svn_fs_x__id_node_id(s_entry->id),
-                                    svn_fs_x__id_node_id(a_entry->id))
-              || !svn_fs_x__id_part_eq(svn_fs_x__id_copy_id(s_entry->id),
-                                       svn_fs_x__id_copy_id(a_entry->id))
-              || !svn_fs_x__id_part_eq(svn_fs_x__id_node_id(t_entry->id),
-                                       svn_fs_x__id_node_id(a_entry->id))
-              || !svn_fs_x__id_part_eq(svn_fs_x__id_copy_id(t_entry->id),
-                                       svn_fs_x__id_copy_id(a_entry->id)))
+          SVN_ERR(svn_fs_x__dag_same_line_of_history(&s_a_same, s_ent_node,
+                                                     a_ent_node));
+          SVN_ERR(svn_fs_x__dag_same_line_of_history(&t_a_same, t_ent_node,
+                                                     a_ent_node));
+          if (!s_a_same || !t_a_same)
             return conflict_err(conflict_p,
                                 svn_fspath__join(target_path,
                                                  a_entry->name,
@@ -2100,12 +2124,6 @@ merge(svn_stringbuf_t *conflict_p,
           /* Direct modifications were made to the directory
              ANCESTOR-ENTRY in both SOURCE and TARGET.  Recursively
              merge these modifications. */
-          SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs,
-                                         s_entry->id, iterpool));
-          SVN_ERR(svn_fs_x__dag_get_node(&t_ent_node, fs,
-                                         t_entry->id, iterpool));
-          SVN_ERR(svn_fs_x__dag_get_node(&a_ent_node, fs,
-                                         a_entry->id, iterpool));
           new_tpath = svn_fspath__join(target_path, t_entry->name, iterpool);
           SVN_ERR(merge(conflict_p, new_tpath,
                         t_ent_node, s_ent_node, a_ent_node,
@@ -2119,13 +2137,13 @@ merge(svn_stringbuf_t *conflict_p,
   /* For each entry E in source but not in ancestor */
   for (i = 0; i < s_entries->nelts; ++i)
     {
-      svn_fs_dirent_t *a_entry, *s_entry, *t_entry;
+      dirent_t *a_entry, *s_entry, *t_entry;
       dag_node_t *s_ent_node;
       apr_int64_t mergeinfo_s;
 
       svn_pool_clear(iterpool);
 
-      s_entry = APR_ARRAY_IDX(s_entries, i, svn_fs_dirent_t *);
+      s_entry = APR_ARRAY_IDX(s_entries, i, dirent_t *);
       a_entry = svn_fs_x__find_dir_entry(a_entries, s_entry->name, &s_idx);
       t_entry = svn_fs_x__find_dir_entry(t_entries, s_entry->name, &t_idx);
 
@@ -2140,13 +2158,13 @@ merge(svn_stringbuf_t *conflict_p,
                                              t_entry->name,
                                              iterpool));
 
-      SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs,
-                                     s_entry->id, iterpool));
+      SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs, &s_entry->id,
+                                     iterpool));
       SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&mergeinfo_s, s_ent_node));
       mergeinfo_increment += mergeinfo_s;
 
       SVN_ERR(svn_fs_x__dag_set_entry
-              (target, s_entry->name, s_entry->id, s_entry->kind,
+              (target, s_entry->name, &s_entry->id, s_entry->kind,
                txn_id, iterpool));
     }
   svn_pool_destroy(iterpool);
@@ -2183,6 +2201,7 @@ merge_changes(dag_node_t *ancestor_node,
   dag_node_t *txn_root_node;
   svn_fs_t *fs = txn->fs;
   svn_fs_x__txn_id_t txn_id = svn_fs_x__txn_get_id(txn);
+  svn_boolean_t related;
   
   SVN_ERR(svn_fs_x__dag_txn_root(&txn_root_node, fs, txn_id, pool));
 
@@ -2192,8 +2211,8 @@ merge_changes(dag_node_t *ancestor_node,
                                           txn_id, pool));
     }
 
-  if (svn_fs_x__id_eq(svn_fs_x__dag_get_id(ancestor_node),
-                      svn_fs_x__dag_get_id(txn_root_node)))
+  SVN_ERR(svn_fs_x__dag_related_node(&related, ancestor_node, txn_root_node));
+  if (!related)
     {
       /* If no changes have been made in TXN since its current base,
          then it can't conflict with any changes since that base.
@@ -2444,16 +2463,26 @@ x_dir_entries(apr_hash_t **table_p,
   apr_hash_t *hash = svn_hash__make(pool);
   apr_array_header_t *table;
   int i;
+  svn_fs_x__id_context_t *context = NULL;
 
   /* Get the entries for this path in the caller's pool. */
   SVN_ERR(get_dag(&node, root, path, FALSE, pool));
   SVN_ERR(svn_fs_x__dag_dir_entries(&table, node, pool));
 
+  if (table->nelts)
+    context = svn_fs_x__id_create_context(root->fs, pool);
+
   /* Convert directory array to hash. */
   for (i = 0; i < table->nelts; ++i)
     {
-      svn_fs_dirent_t *entry = APR_ARRAY_IDX(table, i, svn_fs_dirent_t *);
-      svn_hash_sets(hash, entry->name, entry);
+      dirent_t *entry = APR_ARRAY_IDX(table, i, dirent_t *);
+
+      svn_fs_dirent_t *api_dirent = apr_pcalloc(pool, sizeof(*api_dirent));
+      api_dirent->name = entry->name;
+      api_dirent->kind = entry->kind;
+      api_dirent->id = svn_fs_x__id_create(context, &entry->id, pool);
+
+      svn_hash_sets(hash, api_dirent->name, api_dirent);
     }
 
   *table_p = hash;
@@ -3269,6 +3298,35 @@ x_get_file_delta_stream(svn_txdelta_stre
 
 /* Finding Changes */
 
+/* Copy CHANGE into a FS API object allocated in RESULT_POOL and return
+   it in *RESULT_P.  Pass CONTEXT to the ID API object being created. */
+static svn_error_t *
+construct_fs_path_change(svn_fs_path_change2_t **result_p,
+                         svn_fs_x__id_context_t *context,
+                         change_t *change,
+                         apr_pool_t *result_pool)
+{
+  const svn_fs_id_t *id
+    = svn_fs_x__id_create(context, &change->noderev_id, result_pool);
+  svn_fs_path_change2_t *result
+    = svn_fs__path_change_create_internal(id, change->change_kind,
+                                          result_pool);
+
+  result->text_mod = change->text_mod;
+  result->prop_mod = change->prop_mod;
+  result->node_kind = change->node_kind;
+
+  result->copyfrom_known = change->copyfrom_known;
+  result->copyfrom_rev = change->copyfrom_rev;
+  result->copyfrom_path = change->copyfrom_path;
+
+  result->mergeinfo_mod = change->mergeinfo_mod;
+
+  *result_p = result;
+
+  return SVN_NO_ERROR;
+}
+
 /* Set *CHANGED_PATHS_P to a newly allocated hash containing
    descriptions of the paths changed under ROOT.  The hash is keyed
    with const char * paths and has svn_fs_path_change2_t * values.  Use
@@ -3278,12 +3336,49 @@ x_paths_changed(apr_hash_t **changed_pat
                 svn_fs_root_t *root,
                 apr_pool_t *pool)
 {
+  apr_hash_t *changed_paths;
+  svn_fs_path_change2_t *path_change;
+  svn_fs_x__id_context_t *context
+    = svn_fs_x__id_create_context(root->fs, pool);
+
   if (root->is_txn_root)
-    return svn_fs_x__txn_changes_fetch(changed_paths_p, root->fs,
-                                       root_txn_id(root), pool);
+    {
+      apr_hash_index_t *hi;
+      SVN_ERR(svn_fs_x__txn_changes_fetch(&changed_paths, root->fs,
+                                          root_txn_id(root), pool));
+      for (hi = apr_hash_first(pool, changed_paths);
+           hi;
+           hi = apr_hash_next(hi))
+        {
+          change_t *change = apr_hash_this_val(hi);
+          SVN_ERR(construct_fs_path_change(&path_change, context, change,
+                                           pool));
+          apr_hash_set(changed_paths,
+                       apr_hash_this_key(hi), apr_hash_this_key_len(hi),
+                       path_change);
+        }
+    }
   else
-    return svn_fs_x__paths_changed(changed_paths_p, root->fs, root->rev,
-                                   pool);
+    {
+      apr_array_header_t *changes;
+      int i;
+
+      SVN_ERR(svn_fs_x__get_changes(&changes, root->fs, root->rev, pool));
+
+      changed_paths = svn_hash__make(pool);
+      for (i = 0; i < changes->nelts; ++i)
+        {
+          change_t *change = APR_ARRAY_IDX(changes, i, change_t *);
+          SVN_ERR(construct_fs_path_change(&path_change, context, change,
+                                           pool));
+          apr_hash_set(changed_paths, change->path.data, change->path.len,
+                       path_change);
+        }
+    }
+
+  *changed_paths_p = changed_paths;
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -3398,6 +3493,7 @@ svn_error_t *x_closest_copy(svn_fs_root_
   const char *copy_dst_path;
   svn_fs_root_t *copy_dst_root;
   dag_node_t *copy_dst_node;
+  svn_boolean_t related;
 
   /* Initialize return values. */
   *root_p = NULL;
@@ -3424,8 +3520,9 @@ svn_error_t *x_closest_copy(svn_fs_root_
     return SVN_NO_ERROR;
 
   copy_dst_node = copy_dst_parent_path->node;
-  if (! svn_fs_x__id_check_related(svn_fs_x__dag_get_id(copy_dst_node),
-                                   svn_fs_x__dag_get_id(parent_path->node)))
+  SVN_ERR(svn_fs_x__dag_related_node(&related, copy_dst_node,
+                                     parent_path->node));
+  if (!related)
     return SVN_NO_ERROR;
 
   /* One final check must be done here.  If you copy a directory and
@@ -3442,12 +3539,12 @@ svn_error_t *x_closest_copy(svn_fs_root_
      created-rev is COPY_DST_REV, and that node-revision has no
      predecessors, then there is no relevant closest copy.
   */
-  SVN_ERR(svn_fs_x__dag_get_revision(&created_rev, copy_dst_node, pool));
+  created_rev = svn_fs_x__dag_get_revision(copy_dst_node);
   if (created_rev == copy_dst_rev)
     {
-      const svn_fs_id_t *pred;
+      svn_fs_x__id_t pred;
       SVN_ERR(svn_fs_x__dag_get_predecessor_id(&pred, copy_dst_node));
-      if (! pred)
+      if (!svn_fs_x__id_used(&pred))
         return SVN_NO_ERROR;
     }
 
@@ -3464,14 +3561,15 @@ x_node_origin_rev(svn_revnum_t *revision
                   const char *path,
                   apr_pool_t *pool)
 {
-  const svn_fs_id_t *given_noderev_id;
-  const svn_fs_x__id_part_t *node_id;
+  svn_fs_x__id_t node_id;
+  dag_node_t *node;
 
   path = svn_fs__canonicalize_abspath(path, pool);
 
-  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 = svn_fs_x__get_revnum(node_id->change_set);
+  SVN_ERR(get_dag(&node, root, path, FALSE, pool));
+  SVN_ERR(svn_fs_x__dag_get_node_id(&node_id, node));
+
+  *revision = svn_fs_x__get_revnum(node_id.change_set);
 
   return SVN_NO_ERROR;
 }
@@ -3520,7 +3618,7 @@ history_prev(svn_fs_history_t **prev_his
   SVN_ERR(open_path(&parent_path, root, path, 0, FALSE, scratch_pool));
   node = parent_path->node;
   commit_path = svn_fs_x__dag_get_created_path(node);
-  SVN_ERR(svn_fs_x__dag_get_revision(&commit_rev, node, scratch_pool));
+  commit_rev = svn_fs_x__dag_get_revision(node);
 
   /* The Subversion filesystem is written in such a way that a given
      line of history may have at most one interesting history point
@@ -3545,17 +3643,17 @@ history_prev(svn_fs_history_t **prev_his
           /* ... or we *have* reported on this revision, and must now
              progress toward this node's predecessor (unless there is
              no predecessor, in which case we're all done!). */
-          const svn_fs_id_t *pred_id;
+          svn_fs_x__id_t pred_id;
 
           SVN_ERR(svn_fs_x__dag_get_predecessor_id(&pred_id, node));
-          if (! pred_id)
+          if (!svn_fs_x__id_used(&pred_id))
             return SVN_NO_ERROR;
 
           /* Replace NODE and friends with the information from its
              predecessor. */
-          SVN_ERR(svn_fs_x__dag_get_node(&node, fs, pred_id, scratch_pool));
+          SVN_ERR(svn_fs_x__dag_get_node(&node, fs, &pred_id, scratch_pool));
           commit_path = svn_fs_x__dag_get_created_path(node);
-          SVN_ERR(svn_fs_x__dag_get_revision(&commit_rev, node, scratch_pool));
+          commit_rev = svn_fs_x__dag_get_revision(node);
         }
     }
 
@@ -3759,7 +3857,7 @@ crawl_directory_dag_for_mergeinfo(svn_fs
   SVN_ERR(svn_fs_x__dag_dir_entries(&entries, dir_dag, scratch_pool));
   for (i = 0; i < entries->nelts; ++i)
     {
-      svn_fs_dirent_t *dirent = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
+      dirent_t *dirent = APR_ARRAY_IDX(entries, i, dirent_t *);
       const char *kid_path;
       dag_node_t *kid_dag;
       svn_boolean_t has_mergeinfo, go_down;
@@ -3784,7 +3882,8 @@ crawl_directory_dag_for_mergeinfo(svn_fs
           mergeinfo_string = svn_hash_gets(proplist, SVN_PROP_MERGEINFO);
           if (!mergeinfo_string)
             {
-              svn_string_t *idstr = svn_fs_x__id_unparse(dirent->id, iterpool);
+              svn_string_t *idstr
+                = svn_fs_x__id_unparse(&dirent->id, iterpool);
               return svn_error_createf
                 (SVN_ERR_FS_CORRUPT, NULL,
                  _("Node-revision #'%s' claims to have mergeinfo but doesn't"),
@@ -4111,7 +4210,7 @@ static root_vtable_t root_vtable = {
   x_paths_changed,
   svn_fs_x__check_path,
   x_node_history,
-  svn_fs_x__node_id,
+  x_node_id,
   x_node_relation,
   svn_fs_x__node_created_rev,
   x_node_origin_rev,
@@ -4237,7 +4336,7 @@ verify_node(dag_node_t *node,
 {
   svn_boolean_t has_mergeinfo;
   apr_int64_t mergeinfo_count;
-  const svn_fs_id_t *pred_id;
+  svn_fs_x__id_t pred_id;
   svn_fs_t *fs = svn_fs_x__dag_get_fs(node);
   int pred_count;
   svn_node_kind_t kind;
@@ -4270,11 +4369,11 @@ verify_node(dag_node_t *node,
                              mergeinfo_count, stringify_node(node, iterpool));
 
   /* Issue #4129. (This check will explicitly catch non-root instances too.) */
-  if (pred_id)
+  if (svn_fs_x__id_used(&pred_id))
     {
       dag_node_t *pred;
       int pred_pred_count;
-      SVN_ERR(svn_fs_x__dag_get_node(&pred, fs, pred_id, iterpool));
+      SVN_ERR(svn_fs_x__dag_get_node(&pred, fs, &pred_id, iterpool));
       SVN_ERR(svn_fs_x__dag_get_predecessor_count(&pred_pred_count, pred));
       if (pred_pred_count+1 != pred_count)
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
@@ -4313,17 +4412,16 @@ verify_node(dag_node_t *node,
       /* Compute CHILDREN_MERGEINFO. */
       for (i = 0; i < entries->nelts; ++i)
         {
-          svn_fs_dirent_t *dirent
-            = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
+          dirent_t *dirent = APR_ARRAY_IDX(entries, i, dirent_t *);
           dag_node_t *child;
           apr_int64_t child_mergeinfo;
 
           svn_pool_clear(iterpool);
 
           /* Compute CHILD_REV. */
-          if (svn_fs_x__id_rev(dirent->id) == rev)
+          if (svn_fs_x__get_revnum(dirent->id.change_set) == rev)
             {
-              SVN_ERR(svn_fs_x__dag_get_node(&child, fs, dirent->id,
+              SVN_ERR(svn_fs_x__dag_get_node(&child, fs, &dirent->id,
                                              iterpool));
               SVN_ERR(verify_node(child, rev, parent_nodes, iterpool));
               SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&child_mergeinfo,
@@ -4332,7 +4430,7 @@ verify_node(dag_node_t *node,
           else
             {
               SVN_ERR(svn_fs_x__get_mergeinfo_count(&child_mergeinfo, fs,
-                                                    dirent->id, iterpool));
+                                                    &dirent->id, iterpool));
             }
 
           children_mergeinfo += child_mergeinfo;
@@ -4392,28 +4490,30 @@ svn_fs_x__verify_root(svn_fs_root_t *roo
 
   /* Verify explicitly the predecessor of the root. */
   {
-    const svn_fs_id_t *pred_id;
+    svn_fs_x__id_t pred_id;
+    svn_boolean_t has_predecessor;
 
     /* Only r0 should have no predecessor. */
     SVN_ERR(svn_fs_x__dag_get_predecessor_id(&pred_id, root_dir));
-    if (! root->is_txn_root && !!pred_id != !!root->rev)
+    has_predecessor = svn_fs_x__id_used(&pred_id);
+    if (!root->is_txn_root && has_predecessor != !!root->rev)
       return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                "r%ld's root node's predecessor is "
                                "unexpectedly '%s'",
                                root->rev,
-                               (pred_id
-                                ? svn_fs_x__id_unparse(pred_id, pool)->data
-                                : "(null)"));
-    if (root->is_txn_root && !pred_id)
+                               (has_predecessor
+                                 ? svn_fs_x__id_unparse(&pred_id, pool)->data
+                                 : "(null)"));
+    if (root->is_txn_root && !has_predecessor)
       return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                "Transaction '%s''s root node's predecessor is "
                                "unexpectedly NULL",
                                root->txn);
 
     /* Check the predecessor's revision. */
-    if (pred_id)
+    if (has_predecessor)
       {
-        svn_revnum_t pred_rev = svn_fs_x__id_rev(pred_id);
+        svn_revnum_t pred_rev = svn_fs_x__get_revnum(pred_id.change_set);
         if (! root->is_txn_root && pred_rev+1 != root->rev)
           /* Issue #4129. */
           return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,

Modified: subversion/trunk/subversion/libsvn_fs_x/tree.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/tree.h?rev=1649012&r1=1649011&r2=1649012&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/tree.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/tree.h Fri Jan  2 12:43:42 2015
@@ -67,13 +67,6 @@ svn_fs_x__check_path(svn_node_kind_t *ki
                      const char *path,
                      apr_pool_t *pool);
 
-/* Implement root_vtable_t.node_id(). */
-svn_error_t *
-svn_fs_x__node_id(const svn_fs_id_t **id_p,
-                  svn_fs_root_t *root,
-                  const char *path,
-                  apr_pool_t *pool);
-
 /* Set *REVISION to the revision in which PATH under ROOT was created.
    Use POOL for any temporary allocations.  If PATH is in an
    uncommitted transaction, *REVISION will be set to

Modified: subversion/trunk/subversion/libsvn_fs_x/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/util.c?rev=1649012&r1=1649011&r2=1649012&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/util.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/util.c Fri Jan  2 12:43:42 2015
@@ -388,22 +388,20 @@ svn_fs_x__path_txn_proto_rev_lock(svn_fs
 
 const char *
 svn_fs_x__path_txn_node_rev(svn_fs_t *fs,
-                            const svn_fs_id_t *id,
+                            const svn_fs_x__id_t *id,
                             apr_pool_t *pool)
 {
-  char *filename = (char *)svn_fs_x__id_unparse(id, pool)->data;
-  *strrchr(filename, '.') = '\0';
+  const char *filename = svn_fs_x__id_unparse(id, pool)->data;
+  apr_int64_t txn_id = svn_fs_x__get_txn_id(id->change_set);
 
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, svn_fs_x__id_txn_id(id),
-                                                pool),
-                         apr_psprintf(pool, PATH_PREFIX_NODE "%s",
-                                      filename),
+  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
+                         apr_psprintf(pool, PATH_PREFIX_NODE "%s", filename),
                          pool);
 }
 
 const char *
 svn_fs_x__path_txn_node_props(svn_fs_t *fs,
-                              const svn_fs_id_t *id,
+                              const svn_fs_x__id_t *id,
                               apr_pool_t *pool)
 {
   return apr_pstrcat(pool, svn_fs_x__path_txn_node_rev(fs, id, pool),
@@ -411,7 +409,9 @@ svn_fs_x__path_txn_node_props(svn_fs_t *
 }
 
 const char *
-svn_fs_x__path_txn_node_children(svn_fs_t *fs, const svn_fs_id_t *id, apr_pool_t *pool)
+svn_fs_x__path_txn_node_children(svn_fs_t *fs,
+                                 const svn_fs_x__id_t *id,
+                                 apr_pool_t *pool)
 {
   return apr_pstrcat(pool, svn_fs_x__path_txn_node_rev(fs, id, pool),
                      PATH_EXT_CHILDREN, SVN_VA_NULL);

Modified: subversion/trunk/subversion/libsvn_fs_x/util.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/util.h?rev=1649012&r1=1649011&r2=1649012&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/util.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/util.h Fri Jan  2 12:43:42 2015
@@ -245,17 +245,17 @@ svn_fs_x__path_txn_proto_rev_lock(svn_fs
 
 const char *
 svn_fs_x__path_txn_node_rev(svn_fs_t *fs,
-                            const svn_fs_id_t *id,
+                            const svn_fs_x__id_t *id,
                             apr_pool_t *pool);
 
 const char *
 svn_fs_x__path_txn_node_props(svn_fs_t *fs,
-                              const svn_fs_id_t *id,
+                              const svn_fs_x__id_t *id,
                               apr_pool_t *pool);
 
 const char *
 svn_fs_x__path_txn_node_children(svn_fs_t *fs,
-                                 const svn_fs_id_t *id,
+                                 const svn_fs_x__id_t *id,
                                  apr_pool_t *pool);
 
 /* Check that BUF, a nul-terminated buffer of text from file PATH,

Modified: subversion/trunk/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/verify.c?rev=1649012&r1=1649011&r2=1649012&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/verify.c Fri Jan  2 12:43:42 2015
@@ -258,8 +258,8 @@ 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;
+          svn_fs_x__id_t l2p_item;
+          svn_fs_x__id_t *p2l_item;
 
           l2p_item.change_set = svn_fs_x__change_set_by_rev(revision);
           l2p_item.number = k;
@@ -284,7 +284,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
                                      apr_off_t_toa(pool, offset),
                                      (long)sub_item, revision, (long)k);
 
-          if (!svn_fs_x__id_part_eq(&l2p_item, p2l_item))
+          if (!svn_fs_x__id_eq(&l2p_item, p2l_item))
             return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT,
                                      NULL,
                                      _("p2l index info LOG r%ld:i%ld"
@@ -373,7 +373,7 @@ 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_fs_x__id_t *p2l_item = &entry->items[k];
               svn_revnum_t revision
                 = svn_fs_x__get_revnum(p2l_item->change_set);