You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2015/01/03 15:00:44 UTC

svn commit: r1649205 [10/30] - in /subversion/branches/authzperf: ./ build/ build/ac-macros/ notes/ subversion/bindings/ctypes-python/ subversion/bindings/cxxhl/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/bindings/swig/ s...

Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/cached_data.h?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_x/cached_data.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_x/cached_data.h Sat Jan  3 14:00:41 2015
@@ -34,44 +34,45 @@
 /* Set *NODEREV_P to the node-revision for the node ID in FS.  Do any
    allocations in POOL. */
 svn_error_t *
-svn_fs_x__get_node_revision(node_revision_t **noderev_p,
+svn_fs_x__get_node_revision(svn_fs_x__noderev_t **noderev_p,
                             svn_fs_t *fs,
-                            const svn_fs_id_t *id,
-                            apr_pool_t *pool);
+                            const svn_fs_x__id_t *id,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
 
 /* Set *COUNT to the value of the mergeinfo_count member of the node-
    revision for the node ID in FS.  Do any allocations in POOL. */
 svn_error_t *
 svn_fs_x__get_mergeinfo_count(apr_int64_t *count,
                               svn_fs_t *fs,
-                              const svn_fs_id_t *id,
+                              const svn_fs_x__id_t *id,
                               apr_pool_t *pool);
 
-/* Set *ROOT_ID to the node-id for the root of revision REV in
-   filesystem FS.  Do any allocations in POOL. */
+/* Set *ROOT_ID to the noderev ID for the root of revision REV in
+   filesystem FS.  Do temporary allocations in SCRATCH_POOL. */
 svn_error_t *
-svn_fs_x__rev_get_root(svn_fs_id_t **root_id,
+svn_fs_x__rev_get_root(svn_fs_x__id_t *root_id,
                        svn_fs_t *fs,
                        svn_revnum_t rev,
-                       apr_pool_t *pool);
+                       apr_pool_t *scratch_pool);
 
 /* Verify that representation REP in FS can be accessed.
-   Do any allocations in POOL. */
+   Do any allocations in SCRATCH_POOL. */
 svn_error_t *
-svn_fs_x__check_rep(representation_t *rep,
+svn_fs_x__check_rep(svn_fs_x__representation_t *rep,
                     svn_fs_t *fs,
-                    apr_pool_t *pool);
+                    apr_pool_t *scratch_pool);
 
 /* Follow the representation delta chain in FS starting with REP.  The
    number of reps (including REP) in the chain will be returned in
    *CHAIN_LENGTH.  *SHARD_COUNT will be set to the number of shards
-   accessed.  Do any allocations in POOL. */
+   accessed.  Do any allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__rep_chain_length(int *chain_length,
                            int *shard_count,
-                           representation_t *rep,
+                           svn_fs_x__representation_t *rep,
                            svn_fs_t *fs,
-                           apr_pool_t *pool);
+                           apr_pool_t *scratch_pool);
 
 /* Set *CONTENTS to be a readable svn_stream_t that receives the text
    representation REP as seen in filesystem FS.  If CACHE_FULLTEXT is
@@ -81,7 +82,7 @@ svn_fs_x__rep_chain_length(int *chain_le
 svn_error_t *
 svn_fs_x__get_contents(svn_stream_t **contents_p,
                        svn_fs_t *fs,
-                       representation_t *rep,
+                       svn_fs_x__representation_t *rep,
                        svn_boolean_t cache_fulltext,
                        apr_pool_t *pool);
 
@@ -95,8 +96,7 @@ svn_error_t *
 svn_fs_x__get_representation_length(svn_filesize_t *packed_len,
                                     svn_filesize_t *expanded_len,
                                     svn_fs_t *fs,
-                                    apr_file_t *file,
-                                    svn_stream_t *stream,
+                                    svn_fs_x__revision_file_t *rev_file,
                                     svn_fs_x__p2l_entry_t* entry,
                                     apr_pool_t *pool);
 
@@ -109,7 +109,7 @@ svn_fs_x__get_representation_length(svn_
 svn_error_t *
 svn_fs_x__try_process_file_contents(svn_boolean_t *success,
                                     svn_fs_t *fs,
-                                    node_revision_t *noderev,
+                                    svn_fs_x__noderev_t *noderev,
                                     svn_fs_process_contents_func_t processor,
                                     void* baton,
                                     apr_pool_t *pool);
@@ -120,8 +120,8 @@ svn_fs_x__try_process_file_contents(svn_
 svn_error_t *
 svn_fs_x__get_file_delta_stream(svn_txdelta_stream_t **stream_p,
                                 svn_fs_t *fs,
-                                node_revision_t *source,
-                                node_revision_t *target,
+                                svn_fs_x__noderev_t *source,
+                                svn_fs_x__noderev_t *target,
                                 apr_pool_t *pool);
 
 /* Set *ENTRIES to an apr_array_header_t of dirent structs that contain
@@ -131,7 +131,7 @@ svn_fs_x__get_file_delta_stream(svn_txde
 svn_error_t *
 svn_fs_x__rep_contents_dir(apr_array_header_t **entries_p,
                            svn_fs_t *fs,
-                           node_revision_t *noderev,
+                           svn_fs_x__noderev_t *noderev,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool);
 
@@ -139,7 +139,7 @@ svn_fs_x__rep_contents_dir(apr_array_hea
    entry exists, return NULL.  If HINT is not NULL, set *HINT to the array
    index of the entry returned.  Successive calls in a linear scan scenario
    will be faster called with the same HINT variable. */
-svn_fs_dirent_t *
+svn_fs_x__dirent_t *
 svn_fs_x__find_dir_entry(apr_array_header_t *entries,
                          const char *name,
                          int *hint);
@@ -149,9 +149,9 @@ svn_fs_x__find_dir_entry(apr_array_heade
    be NULL. The returned object is allocated in RESULT_POOL; SCRATCH_POOL
    used for temporary allocations. */
 svn_error_t *
-svn_fs_x__rep_contents_dir_entry(svn_fs_dirent_t **dirent,
+svn_fs_x__rep_contents_dir_entry(svn_fs_x__dirent_t **dirent,
                                  svn_fs_t *fs,
-                                 node_revision_t *noderev,
+                                 svn_fs_x__noderev_t *noderev,
                                  const char *name,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool);
@@ -162,7 +162,7 @@ svn_fs_x__rep_contents_dir_entry(svn_fs_
 svn_error_t *
 svn_fs_x__get_proplist(apr_hash_t **proplist,
                        svn_fs_t *fs,
-                       node_revision_t *noderev,
+                       svn_fs_x__noderev_t *noderev,
                        apr_pool_t *pool);
 
 /* Fetch the list of change in revision REV in FS and return it in *CHANGES.

Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/caching.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_x/caching.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_x/caching.c Sat Jan  3 14:00:41 2015
@@ -126,19 +126,17 @@ read_config(const char **cache_namespace
    * Revprop caching significantly speeds up operations like
    * svn ls -v. However, it requires synchronization that may
    * not be available or efficient in the current server setup.
-   *
-   * If the caller chose option "2", enable revprop caching if
-   * the required API support is there to make it efficient.
+   * Option "2" is equivalent to "1".
    */
   if (strcmp(svn_hash__get_cstring(fs->config,
                                    SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                                    ""), "2"))
     *cache_revprops
       = svn_hash__get_bool(fs->config,
-                           SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
-                           FALSE);
+                          SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
+                          FALSE);
   else
-    *cache_revprops = svn_named_atomic__is_efficient();
+    *cache_revprops = TRUE;
 
   return SVN_NO_ERROR;
 }
@@ -361,7 +359,7 @@ svn_error_t *
 svn_fs_x__initialize_caches(svn_fs_t *fs,
                             apr_pool_t *pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
   const char *prefix = apr_pstrcat(pool,
                                    "fsx:", fs->uuid,
                                    "/", normalize_key_part(fs->path, pool),
@@ -407,27 +405,6 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                               apr_pool_cleanup_null);
 #endif
 
-  /* Make the cache for revision roots.  For the vast majority of
-   * commands, this is only going to contain a few entries (svnadmin
-   * dump/verify is an exception here), so to reduce overhead let's
-   * try to keep it to just one page.  I estimate each entry has about
-   * 72 bytes of overhead (svn_revnum_t key, svn_fs_id_t +
-   * id_private_t + 3 strings for value, and the cache_entry); the
-   * default pool size is 8192, so about a hundred should fit
-   * comfortably. */
-  SVN_ERR(create_cache(&(ffd->rev_root_id_cache),
-                       NULL,
-                       membuffer,
-                       1, 100,
-                       svn_fs_x__serialize_id,
-                       svn_fs_x__deserialize_id,
-                       sizeof(svn_revnum_t),
-                       apr_pstrcat(pool, prefix, "RRI", SVN_VA_NULL),
-                       0,
-                       fs,
-                       no_handler,
-                       fs->pool, pool));
-
   /* Rough estimate: revision DAG nodes have size around 320 bytes, so
    * let's put 16 on a page. */
   SVN_ERR(create_cache(&(ffd->rev_node_cache),
@@ -453,7 +430,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        1024, 8,
                        svn_fs_x__serialize_dir_entries,
                        svn_fs_x__deserialize_dir_entries,
-                       sizeof(svn_fs_x__id_part_t),
+                       sizeof(svn_fs_x__id_t),
                        apr_pstrcat(pool, prefix, "DIR", SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
                        fs,
@@ -483,7 +460,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        32, 32, /* ~200 byte / entry; 1k entries total */
                        svn_fs_x__serialize_node_revision,
                        svn_fs_x__deserialize_node_revision,
-                       sizeof(pair_cache_key_t),
+                       sizeof(svn_fs_x__pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "NODEREVS", SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
                        fs,
@@ -497,7 +474,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        1, 1000, /* ~8 bytes / entry; 1k entries total */
                        svn_fs_x__serialize_rep_header,
                        svn_fs_x__deserialize_rep_header,
-                       sizeof(representation_cache_key_t),
+                       sizeof(svn_fs_x__representation_cache_key_t),
                        apr_pstrcat(pool, prefix, "REPHEADER", SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
                        fs,
@@ -527,7 +504,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                            0, 0, /* Do not use inprocess cache */
                            /* Values are svn_stringbuf_t */
                            NULL, NULL,
-                           sizeof(pair_cache_key_t),
+                           sizeof(svn_fs_x__pair_cache_key_t),
                            apr_pstrcat(pool, prefix, "TEXT", SVN_VA_NULL),
                            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
                            fs,
@@ -540,7 +517,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                            0, 0, /* Do not use inprocess cache */
                            svn_fs_x__serialize_properties,
                            svn_fs_x__deserialize_properties,
-                           sizeof(pair_cache_key_t),
+                           sizeof(svn_fs_x__pair_cache_key_t),
                            apr_pstrcat(pool, prefix, "PROP",
                                        SVN_VA_NULL),
                            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
@@ -593,7 +570,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                            0, 0, /* Do not use inprocess cache */
                            svn_fs_x__serialize_properties,
                            svn_fs_x__deserialize_properties,
-                           sizeof(pair_cache_key_t),
+                           sizeof(svn_fs_x__pair_cache_key_t),
                            apr_pstrcat(pool, prefix, "REVPROP",
                                        SVN_VA_NULL),
                            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
@@ -615,7 +592,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                            0, 0, /* Do not use inprocess cache */
                            svn_fs_x__serialize_txdelta_window,
                            svn_fs_x__deserialize_txdelta_window,
-                           sizeof(window_cache_key_t),
+                           sizeof(svn_fs_x__window_cache_key_t),
                            apr_pstrcat(pool, prefix, "TXDELTA_WINDOW",
                                        SVN_VA_NULL),
                            SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
@@ -629,7 +606,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                            0, 0, /* Do not use inprocess cache */
                            /* Values are svn_stringbuf_t */
                            NULL, NULL,
-                           sizeof(window_cache_key_t),
+                           sizeof(svn_fs_x__window_cache_key_t),
                            apr_pstrcat(pool, prefix, "COMBINED_WINDOW",
                                        SVN_VA_NULL),
                            SVN_CACHE__MEMBUFFER_LOW_PRIORITY,
@@ -649,7 +626,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        16, 4, /* Important, largish objects */
                        svn_fs_x__serialize_noderevs_container,
                        svn_fs_x__deserialize_noderevs_container,
-                       sizeof(pair_cache_key_t),
+                       sizeof(svn_fs_x__pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "NODEREVSCNT",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
@@ -662,7 +639,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        0, 0, /* Do not use inprocess cache */
                        svn_fs_x__serialize_changes_container,
                        svn_fs_x__deserialize_changes_container,
-                       sizeof(pair_cache_key_t),
+                       sizeof(svn_fs_x__pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "CHANGESCNT",
                                    SVN_VA_NULL),
                        0,
@@ -675,7 +652,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        0, 0, /* Do not use inprocess cache */
                        svn_fs_x__serialize_reps_container,
                        svn_fs_x__deserialize_reps_container,
-                       sizeof(pair_cache_key_t),
+                       sizeof(svn_fs_x__pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "REPSCNT",
                                    SVN_VA_NULL),
                        0,
@@ -690,7 +667,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                                   a reasonable number of revisions (1k) */
                        svn_fs_x__serialize_l2p_header,
                        svn_fs_x__deserialize_l2p_header,
-                       sizeof(pair_cache_key_t),
+                       sizeof(svn_fs_x__pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "L2P_HEADER",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
@@ -717,7 +694,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
                        4, 1, /* Large entries. Rarely used. */
                        svn_fs_x__serialize_p2l_header,
                        svn_fs_x__deserialize_p2l_header,
-                       sizeof(pair_cache_key_t),
+                       sizeof(svn_fs_x__pair_cache_key_t),
                        apr_pstrcat(pool, prefix, "P2L_HEADER",
                                    SVN_VA_NULL),
                        SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,

Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/changes.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/changes.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_x/changes.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_x/changes.c Sat Jan  3 14:00:41 2015
@@ -79,9 +79,7 @@ typedef struct binary_change_t
 
   /* Relevant parts of the node revision ID of the change.
    * 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 noderev_id;
+  svn_fs_x__id_t noderev_id;
 
 } binary_change_t;
 
@@ -136,24 +134,25 @@ svn_fs_x__changes_create(apr_size_t init
  */
 static svn_error_t *
 append_change(svn_fs_x__changes_t *changes,
-              change_t *change)
+              svn_fs_x__change_t *change)
 {
   binary_change_t binary_change = { 0 };
   svn_boolean_t is_txn_id;
-  svn_fs_path_change2_t *info;
 
   /* CHANGE must be sufficiently complete */
   SVN_ERR_ASSERT(change);
   SVN_ERR_ASSERT(change->path.data);
 
+  /* Relevant parts of the revision ID of the change. */
+  binary_change.noderev_id = change->noderev_id;
+
   /* define the kind of change and what specific information is present */
-  info = &change->info;
-  is_txn_id = info->node_rev_id && svn_fs_x__id_is_txn(info->node_rev_id);
-  binary_change.flags = (info->text_mod ? CHANGE_TEXT_MOD : 0)
-                      | (info->prop_mod ? CHANGE_PROP_MOD : 0)
+  is_txn_id = svn_fs_x__is_txn(binary_change.noderev_id.change_set);
+  binary_change.flags = (change->text_mod ? CHANGE_TEXT_MOD : 0)
+                      | (change->prop_mod ? CHANGE_PROP_MOD : 0)
                       | (is_txn_id ? CHANGE_TXN_NODE : 0)
-                      | ((int)info->change_kind << CHANGE_KIND_SHIFT)
-                      | ((int)info->node_kind << CHANGE_NODE_SHIFT);
+                      | ((int)change->change_kind << CHANGE_KIND_SHIFT)
+                      | ((int)change->node_kind << CHANGE_NODE_SHIFT);
 
   /* Path of the change. */
   binary_change.path
@@ -162,12 +161,12 @@ append_change(svn_fs_x__changes_t *chang
                                          change->path.len);
 
   /* copy-from information, if presence is indicated by FLAGS */
-  if (SVN_IS_VALID_REVNUM(info->copyfrom_rev))
+  if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
     {
-      binary_change.copyfrom_rev = info->copyfrom_rev;
+      binary_change.copyfrom_rev = change->copyfrom_rev;
       binary_change.copyfrom_path
         = svn_fs_x__string_table_builder_add(changes->builder,
-                                             info->copyfrom_path,
+                                             change->copyfrom_path,
                                              0);
     }
   else
@@ -176,19 +175,6 @@ append_change(svn_fs_x__changes_t *chang
       binary_change.copyfrom_path = 0;
     }
 
-  /* Relevant parts of the revision ID of the change. */
-  if (info->node_rev_id)
-    {
-      binary_change.node_id = *svn_fs_x__id_node_id(info->node_rev_id);
-      binary_change.copy_id = *svn_fs_x__id_copy_id(info->node_rev_id);
-      binary_change.noderev_id = *svn_fs_x__id_noderev_id(info->node_rev_id);
-    }
-  else
-    {
-      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;
 
   return SVN_NO_ERROR;
@@ -207,7 +193,7 @@ svn_fs_x__changes_append_list(apr_size_t
 
   /* simply append the list and all changes */
   for (i = 0; i < list->nelts; ++i)
-    append_change(changes, APR_ARRAY_IDX(list, i, change_t *));
+    append_change(changes, APR_ARRAY_IDX(list, i, svn_fs_x__change_t *));
 
   /* terminate the list by storing the next changes offset */
   APR_ARRAY_PUSH(changes->offsets, int) = changes->changes->nelts;
@@ -259,44 +245,40 @@ svn_fs_x__changes_get_list(apr_array_hea
   last = APR_ARRAY_IDX(changes->offsets, (int)idx + 1, int);
 
   /* construct result */
-  *list = apr_array_make(pool, last - first, sizeof(change_t*));
+  *list = apr_array_make(pool, last - first, sizeof(svn_fs_x__change_t*));
   for (i = first; i < last; ++i)
     {
       const binary_change_t *binary_change
         = &APR_ARRAY_IDX(changes->changes, i, binary_change_t);
 
-      /* convert BINARY_CHANGE into a standard FSX change_t */
-      change_t *change = apr_pcalloc(pool, sizeof(*change));
-      svn_fs_path_change2_t *info = &change->info;
+      /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */
+      svn_fs_x__change_t *change = apr_pcalloc(pool, sizeof(*change));
       change->path.data = svn_fs_x__string_table_get(changes->paths,
                                                      binary_change->path,
                                                      &change->path.len,
                                                      pool);
 
       if (binary_change->noderev_id.change_set != SVN_FS_X__INVALID_CHANGE_SET)
-        info->node_rev_id = svn_fs_x__id_create(&binary_change->node_id,
-                                                &binary_change->copy_id,
-                                                &binary_change->noderev_id,
-                                                pool);
+        change->noderev_id = binary_change->noderev_id;
 
-      info->change_kind = (svn_fs_path_change_kind_t)
+      change->change_kind = (svn_fs_path_change_kind_t)
         ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
-      info->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
-      info->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
-      info->node_kind = (svn_node_kind_t)
+      change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
+      change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
+      change->node_kind = (svn_node_kind_t)
         ((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT);
 
-      info->copyfrom_rev = binary_change->copyfrom_rev;
-      info->copyfrom_known = TRUE;
+      change->copyfrom_rev = binary_change->copyfrom_rev;
+      change->copyfrom_known = TRUE;
       if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev))
-        info->copyfrom_path 
+        change->copyfrom_path 
           = svn_fs_x__string_table_get(changes->paths,
                                         binary_change->copyfrom_path,
                                         NULL,
                                         pool);
 
       /* add it to the result */
-      APR_ARRAY_PUSH(*list, change_t*) = change;
+      APR_ARRAY_PUSH(*list, svn_fs_x__change_t*) = change;
     }
 
   return SVN_NO_ERROR;
@@ -330,11 +312,7 @@ svn_fs_x__write_changes_container(svn_st
   svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
   svn_packed__create_int_substream(changes_stream, TRUE, TRUE);
   svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
-  svn_packed__create_int_substream(changes_stream, TRUE, TRUE);
-  svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
-  svn_packed__create_int_substream(changes_stream, TRUE, TRUE);
-  svn_packed__create_int_substream(changes_stream, TRUE, FALSE);
-  
+
   /* serialize offsets array */
   for (i = 0; i < changes->offsets->nelts; ++i)
     svn_packed__add_uint(offsets_stream,
@@ -352,10 +330,6 @@ 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.change_set);
-      svn_packed__add_uint(changes_stream, change->node_id.number);
-      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->noderev_id.change_set);
       svn_packed__add_uint(changes_stream, change->noderev_id.number);
     }
@@ -412,10 +386,6 @@ 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.change_set = svn_packed__get_int(changes_stream);
-      change.node_id.number = svn_packed__get_uint(changes_stream);
-      change.copy_id.change_set = svn_packed__get_int(changes_stream);
-      change.copy_id.number = svn_packed__get_uint(changes_stream);
       change.noderev_id.change_set = svn_packed__get_int(changes_stream);
       change.noderev_id.number = svn_packed__get_uint(changes_stream);
 
@@ -525,43 +495,38 @@ svn_fs_x__changes_get_list_func(void **o
   last = offsets[idx+1];
 
   /* construct result */
-  list = apr_array_make(pool, last - first, sizeof(change_t*));
+  list = apr_array_make(pool, last - first, sizeof(svn_fs_x__change_t*));
 
   for (i = first; i < last; ++i)
     {
       const binary_change_t *binary_change = &changes[i];
 
-      /* convert BINARY_CHANGE into a standard FSX change_t */
-      change_t *change = apr_pcalloc(pool, sizeof(*change));
-      svn_fs_path_change2_t *info = &change->info;
+      /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */
+      svn_fs_x__change_t *change = apr_pcalloc(pool, sizeof(*change));
       change->path.data
         = svn_fs_x__string_table_get_func(paths, binary_change->path,
                                           &change->path.len, pool);
 
-      if (binary_change->noderev_id.change_set != SVN_FS_X__INVALID_CHANGE_SET)
-        info->node_rev_id = svn_fs_x__id_create(&binary_change->node_id,
-                                                &binary_change->copy_id,
-                                                &binary_change->noderev_id,
-                                                pool);
+      change->noderev_id = binary_change->noderev_id;
 
-      info->change_kind = (svn_fs_path_change_kind_t)
+      change->change_kind = (svn_fs_path_change_kind_t)
         ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
-      info->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
-      info->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
-      info->node_kind = (svn_node_kind_t)
+      change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
+      change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
+      change->node_kind = (svn_node_kind_t)
         ((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT);
 
-      info->copyfrom_rev = binary_change->copyfrom_rev;
-      info->copyfrom_known = TRUE;
+      change->copyfrom_rev = binary_change->copyfrom_rev;
+      change->copyfrom_known = TRUE;
       if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev))
-        info->copyfrom_path 
+        change->copyfrom_path 
           = svn_fs_x__string_table_get_func(paths,
                                             binary_change->copyfrom_path,
                                             NULL,
                                             pool);
 
       /* add it to the result */
-      APR_ARRAY_PUSH(list, change_t*) = change;
+      APR_ARRAY_PUSH(list, svn_fs_x__change_t*) = change;
     }
 
   *out = list;

Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/changes.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/changes.h?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_x/changes.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_x/changes.h Sat Jan  3 14:00:41 2015
@@ -32,21 +32,22 @@
  *
  * In its serialized form, the svn_fs_x__changes_t container extracts most
  * of that redundancy and the run-time representation is also much smaller
- * than sum of the respective change_t* arrays.
+ * than sum of the respective svn_fs_x__change_t* arrays.
  *
  * As with other containers, this one has two modes: 'construction', in
  * which you may add data to it, and 'getter' in which there is only r/o
  * access to the data.
  */
 
-/* An opaque collection of change lists (apr_array_header_t * of change_t*).
+/* An opaque collection of change lists (apr_array_header_t * of
+ * svn_fs_x__change_t *).
  */
 typedef struct svn_fs_x__changes_t svn_fs_x__changes_t;
 
 /* Create and populate changes containers. */
 
 /* Create and return a new changes container with an initial capacity of
- * INITIAL_COUNT change_t objects.  Allocate the result in POOL.
+ * INITIAL_COUNT svn_fs_x__change_t objects.  Allocate the result in POOL.
  */
 svn_fs_x__changes_t *
 svn_fs_x__changes_create(apr_size_t initial_count,

Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/dag.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_x/dag.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_x/dag.c Sat Jan  3 14:00:41 2015
@@ -31,7 +31,7 @@
 #include "dag.h"
 #include "fs.h"
 #include "fs_x.h"
-#include "id.h"
+#include "fs_id.h"
 #include "cached_data.h"
 #include "transaction.h"
 
@@ -50,14 +50,14 @@ struct dag_node_t
   /* The filesystem this dag node came from. */
   svn_fs_t *fs;
 
-  /* The node revision ID for this dag node, allocated in POOL.  */
-  svn_fs_id_t *id;
+  /* The node revision ID for this dag node.  */
+  svn_fs_x__id_t id;
 
   /* In the special case that this node is the root of a transaction
      that has not yet been modified, the node revision ID for this dag
      node's predecessor; otherwise NULL. (Used in
      svn_fs_node_created_rev.) */
-  const svn_fs_id_t *fresh_root_predecessor_id;
+  svn_fs_x__id_t fresh_root_predecessor_id;
 
   /* The node's type (file, dir, etc.) */
   svn_node_kind_t kind;
@@ -69,7 +69,7 @@ struct dag_node_t
      this yourself, but you're probably better off just calling
      `get_node_revision' and `set_node_revision', which take care of
      things for you.  */
-  node_revision_t *node_revision;
+  svn_fs_x__noderev_t *node_revision;
 
   /* The pool to allocate NODE_REVISION in. */
   apr_pool_t *node_pool;
@@ -86,11 +86,10 @@ svn_node_kind_t svn_fs_x__dag_node_kind(
   return node->kind;
 }
 
-
-const svn_fs_id_t *
+const svn_fs_x__id_t *
 svn_fs_x__dag_get_id(const dag_node_t *node)
 {
-  return node->id;
+  return &node->id;
 }
 
 
@@ -116,27 +115,22 @@ svn_fs_x__dag_set_fs(dag_node_t *node, s
 
 /* Dup NODEREV and all associated data into POOL.
    Leaves the id and is_fresh_txn_root fields as zero bytes. */
-static node_revision_t *
-copy_node_revision(node_revision_t *noderev,
+static svn_fs_x__noderev_t *
+copy_node_revision(svn_fs_x__noderev_t *noderev,
                    apr_pool_t *pool)
 {
-  node_revision_t *nr = apr_pcalloc(pool, sizeof(*nr));
-  nr->kind = noderev->kind;
-  if (noderev->predecessor_id)
-    nr->predecessor_id = svn_fs_x__id_copy(noderev->predecessor_id, pool);
-  nr->predecessor_count = noderev->predecessor_count;
+  svn_fs_x__noderev_t *nr = apr_pmemdup(pool, noderev, sizeof(*noderev));
+
   if (noderev->copyfrom_path)
     nr->copyfrom_path = apr_pstrdup(pool, noderev->copyfrom_path);
-  nr->copyfrom_rev = noderev->copyfrom_rev;
+
   nr->copyroot_path = apr_pstrdup(pool, noderev->copyroot_path);
-  nr->copyroot_rev = noderev->copyroot_rev;
   nr->data_rep = svn_fs_x__rep_copy(noderev->data_rep, pool);
   nr->prop_rep = svn_fs_x__rep_copy(noderev->prop_rep, pool);
-  nr->mergeinfo_count = noderev->mergeinfo_count;
-  nr->has_mergeinfo = noderev->has_mergeinfo;
 
   if (noderev->created_path)
     nr->created_path = apr_pstrdup(pool, noderev->created_path);
+
   return nr;
 }
 
@@ -153,17 +147,19 @@ copy_node_revision(node_revision_t *node
    changes that never got committed.  It's probably best not to change
    the structure at all.  */
 static svn_error_t *
-get_node_revision(node_revision_t **noderev_p,
+get_node_revision(svn_fs_x__noderev_t **noderev_p,
                   dag_node_t *node)
 {
   /* If we've already got a copy, there's no need to read it in.  */
   if (! node->node_revision)
     {
-      node_revision_t *noderev;
+      svn_fs_x__noderev_t *noderev;
+      apr_pool_t *scratch_pool = svn_pool_create(node->node_pool);
 
-      SVN_ERR(svn_fs_x__get_node_revision(&noderev, node->fs,
-                                          node->id, node->node_pool));
+      SVN_ERR(svn_fs_x__get_node_revision(&noderev, node->fs, &node->id,
+                                          node->node_pool, scratch_pool));
       node->node_revision = noderev;
+      svn_pool_destroy(scratch_pool);
     }
 
   /* Now NODE->node_revision is set.  */
@@ -171,26 +167,83 @@ get_node_revision(node_revision_t **node
   return SVN_NO_ERROR;
 }
 
+/* Return the node revision ID of NODE.  The value returned is shared
+   with NODE, and will be deallocated when NODE is.  */
+svn_error_t *
+svn_fs_x__dag_get_node_id(svn_fs_x__id_t *node_id,
+                          dag_node_t *node)
+{
+  svn_fs_x__noderev_t *noderev;
+  SVN_ERR(get_node_revision(&noderev, node));
+
+  *node_id = noderev->node_id;
+  return SVN_NO_ERROR;
+}
+
+/* Return the node revision ID of NODE.  The value returned is shared
+   with NODE, and will be deallocated when NODE is.  */
+svn_error_t *
+svn_fs_x__dag_get_copy_id(svn_fs_x__id_t *copy_id,
+                          dag_node_t *node)
+{
+  svn_fs_x__noderev_t *noderev;
+  SVN_ERR(get_node_revision(&noderev, node));
+
+  *copy_id = noderev->copy_id;
+  return SVN_NO_ERROR;
+}
+
+/* Return the node ID of NODE.  The value returned is shared with NODE,
+   and will be deallocated when NODE is.  */
+svn_error_t *
+svn_fs_x__dag_related_node(svn_boolean_t *same,
+                           dag_node_t *lhs,
+                           dag_node_t *rhs)
+{
+  svn_fs_x__id_t lhs_node, rhs_node;
+
+  SVN_ERR(svn_fs_x__dag_get_node_id(&lhs_node, lhs));
+  SVN_ERR(svn_fs_x__dag_get_node_id(&rhs_node, rhs));
+  *same = svn_fs_x__id_eq(&lhs_node, &rhs_node);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__dag_same_line_of_history(svn_boolean_t *same,
+                                   dag_node_t *lhs,
+                                   dag_node_t *rhs)
+{
+  svn_fs_x__noderev_t *lhs_noderev, *rhs_noderev;
+
+  SVN_ERR(get_node_revision(&lhs_noderev, lhs));
+  SVN_ERR(get_node_revision(&rhs_noderev, rhs));
+
+  *same = svn_fs_x__id_eq(&lhs_noderev->node_id, &rhs_noderev->node_id)
+       && svn_fs_x__id_eq(&lhs_noderev->copy_id, &rhs_noderev->copy_id);
+
+  return SVN_NO_ERROR;
+}
 
 svn_boolean_t svn_fs_x__dag_check_mutable(const dag_node_t *node)
 {
-  return svn_fs_x__id_is_txn(svn_fs_x__dag_get_id(node));
+  return svn_fs_x__is_txn(svn_fs_x__dag_get_id(node)->change_set);
 }
 
 
 svn_error_t *
 svn_fs_x__dag_get_node(dag_node_t **node,
                        svn_fs_t *fs,
-                       const svn_fs_id_t *id,
+                       const svn_fs_x__id_t *id,
                        apr_pool_t *pool)
 {
   dag_node_t *new_node;
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Construct the node. */
   new_node = apr_pcalloc(pool, sizeof(*new_node));
   new_node->fs = fs;
-  new_node->id = svn_fs_x__id_copy(id, pool);
+  new_node->id = *id;
 
   /* Grab the contents so we can inspect the node's kind and created path. */
   new_node->node_pool = pool;
@@ -203,7 +256,7 @@ svn_fs_x__dag_get_node(dag_node_t **node
   if (noderev->is_fresh_txn_root)
     new_node->fresh_root_predecessor_id = noderev->predecessor_id;
   else
-    new_node->fresh_root_predecessor_id = NULL;
+    svn_fs_x__id_reset(&new_node->fresh_root_predecessor_id);
 
   /* Return a fresh new node */
   *node = new_node;
@@ -211,32 +264,31 @@ svn_fs_x__dag_get_node(dag_node_t **node
 }
 
 
-svn_error_t *
-svn_fs_x__dag_get_revision(svn_revnum_t *rev,
-                           dag_node_t *node,
-                           apr_pool_t *pool)
+svn_revnum_t
+svn_fs_x__dag_get_revision(const dag_node_t *node)
 {
   /* In the special case that this is an unmodified transaction root,
      we need to actually get the revision of the noderev's predecessor
      (the revision root); see Issue #2608. */
-  const svn_fs_id_t *correct_id = node->fresh_root_predecessor_id
-    ? node->fresh_root_predecessor_id : node->id;
+  const svn_fs_x__id_t *correct_id
+    = svn_fs_x__id_used(&node->fresh_root_predecessor_id)
+        ? &node->fresh_root_predecessor_id
+        : &node->id;
 
   /* Look up the committed revision from the Node-ID. */
-  *rev = svn_fs_x__id_rev(correct_id);
-
-  return SVN_NO_ERROR;
+  return svn_fs_x__get_revnum(correct_id->change_set);
 }
 
 
 svn_error_t *
-svn_fs_x__dag_get_predecessor_id(const svn_fs_id_t **id_p,
+svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p,
                                  dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   SVN_ERR(get_node_revision(&noderev, node));
   *id_p = noderev->predecessor_id;
+
   return SVN_NO_ERROR;
 }
 
@@ -245,7 +297,7 @@ svn_error_t *
 svn_fs_x__dag_get_predecessor_count(int *count,
                                     dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   SVN_ERR(get_node_revision(&noderev, node));
   *count = noderev->predecessor_count;
@@ -256,7 +308,7 @@ svn_error_t *
 svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count,
                                   dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   SVN_ERR(get_node_revision(&noderev, node));
   *count = noderev->mergeinfo_count;
@@ -267,7 +319,7 @@ svn_error_t *
 svn_fs_x__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo,
                             dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   SVN_ERR(get_node_revision(&noderev, node));
   *has_mergeinfo = noderev->has_mergeinfo;
@@ -278,7 +330,7 @@ svn_error_t *
 svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they,
                                              dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   if (node->kind != svn_node_dir)
     {
@@ -301,21 +353,22 @@ svn_fs_x__dag_has_descendants_with_merge
 
 /* Some of these are helpers for functions outside this section. */
 
-/* Set *ID_P to the node-id for entry NAME in PARENT.  If no such
-   entry, set *ID_P to NULL but do not error.  The node-id is
-   allocated in POOL. */
+/* Set *ID_P to the noderev-id for entry NAME in PARENT.  If no such
+   entry, set *ID_P to NULL but do not error. */
 static svn_error_t *
-dir_entry_id_from_node(const svn_fs_id_t **id_p,
+dir_entry_id_from_node(svn_fs_x__id_t *id_p,
                        dag_node_t *parent,
                        const char *name,
-                       apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
 {
-  svn_fs_dirent_t *dirent;
+  svn_fs_x__dirent_t *dirent;
 
-  SVN_ERR(svn_fs_x__dag_dir_entry(&dirent, parent, name, result_pool,
+  SVN_ERR(svn_fs_x__dag_dir_entry(&dirent, parent, name, scratch_pool,
                                   scratch_pool));
-  *id_p = dirent ? dirent->id : NULL;
+  if (dirent)
+    *id_p = dirent->id;
+  else
+    svn_fs_x__id_reset(id_p);
 
   return SVN_NO_ERROR;
 }
@@ -332,12 +385,12 @@ dir_entry_id_from_node(const svn_fs_id_t
 static svn_error_t *
 set_entry(dag_node_t *parent,
           const char *name,
-          const svn_fs_id_t *id,
+          const svn_fs_x__id_t *id,
           svn_node_kind_t kind,
           svn_fs_x__txn_id_t txn_id,
           apr_pool_t *pool)
 {
-  node_revision_t *parent_noderev;
+  svn_fs_x__noderev_t *parent_noderev;
 
   /* Get the parent's node-revision. */
   SVN_ERR(get_node_revision(&parent_noderev, parent));
@@ -364,8 +417,7 @@ make_entry(dag_node_t **child_p,
            svn_fs_x__txn_id_t txn_id,
            apr_pool_t *pool)
 {
-  const svn_fs_id_t *new_node_id;
-  node_revision_t new_noderev, *parent_noderev;
+  svn_fs_x__noderev_t new_noderev, *parent_noderev;
 
   /* Make sure that NAME is a single path component. */
   if (! svn_path_is_single_path_component(name))
@@ -396,20 +448,20 @@ make_entry(dag_node_t **child_p,
   new_noderev.copyroot_rev = parent_noderev->copyroot_rev;
   new_noderev.copyfrom_rev = SVN_INVALID_REVNUM;
   new_noderev.copyfrom_path = NULL;
+  svn_fs_x__id_reset(&new_noderev.predecessor_id);
 
   SVN_ERR(svn_fs_x__create_node
-          (&new_node_id, svn_fs_x__dag_get_fs(parent), &new_noderev,
-           svn_fs_x__id_copy_id(svn_fs_x__dag_get_id(parent)),
-           txn_id, pool));
+          (svn_fs_x__dag_get_fs(parent), &new_noderev,
+           &parent_noderev->copy_id, txn_id, pool));
 
   /* Create a new dag_node_t for our new node */
   SVN_ERR(svn_fs_x__dag_get_node(child_p, svn_fs_x__dag_get_fs(parent),
-                                 new_node_id, pool));
+                                 &new_noderev.noderev_id, pool));
 
   /* We can safely call set_entry because we already know that
      PARENT is mutable, and we just created CHILD, so we know it has
      no ancestors (therefore, PARENT cannot be an ancestor of CHILD) */
-  return set_entry(parent, name, svn_fs_x__dag_get_id(*child_p),
+  return set_entry(parent, name, &new_noderev.noderev_id,
                    new_noderev.kind, txn_id, pool);
 }
 
@@ -419,7 +471,7 @@ svn_fs_x__dag_dir_entries(apr_array_head
                           dag_node_t *node,
                           apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   SVN_ERR(get_node_revision(&noderev, node));
 
@@ -431,13 +483,13 @@ svn_fs_x__dag_dir_entries(apr_array_head
 }
 
 svn_error_t *
-svn_fs_x__dag_dir_entry(svn_fs_dirent_t **dirent,
-                         dag_node_t *node,
-                         const char* name,
-                         apr_pool_t *result_pool,
-                         apr_pool_t *scratch_pool)
+svn_fs_x__dag_dir_entry(svn_fs_x__dirent_t **dirent,
+                        dag_node_t *node,
+                        const char* name,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
   SVN_ERR(get_node_revision(&noderev, node));
 
   if (noderev->kind != svn_node_dir)
@@ -453,7 +505,7 @@ svn_fs_x__dag_dir_entry(svn_fs_dirent_t
 svn_error_t *
 svn_fs_x__dag_set_entry(dag_node_t *node,
                         const char *entry_name,
-                        const svn_fs_id_t *id,
+                        const svn_fs_x__id_t *id,
                         svn_node_kind_t kind,
                         svn_fs_x__txn_id_t txn_id,
                         apr_pool_t *pool)
@@ -482,7 +534,7 @@ svn_fs_x__dag_get_proplist(apr_hash_t **
                            dag_node_t *node,
                            apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
   apr_hash_t *proplist = NULL;
 
   SVN_ERR(get_node_revision(&noderev, node));
@@ -500,12 +552,12 @@ svn_fs_x__dag_set_proplist(dag_node_t *n
                            apr_hash_t *proplist,
                            apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Sanity check: this node better be mutable! */
   if (! svn_fs_x__dag_check_mutable(node))
     {
-      svn_string_t *idstr = svn_fs_x__id_unparse(node->id, pool);
+      svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, pool);
       return svn_error_createf
         (SVN_ERR_FS_NOT_MUTABLE, NULL,
          "Can't set proplist on *immutable* node-revision %s",
@@ -525,12 +577,12 @@ svn_fs_x__dag_increment_mergeinfo_count(
                                         apr_int64_t increment,
                                         apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Sanity check: this node better be mutable! */
   if (! svn_fs_x__dag_check_mutable(node))
     {
-      svn_string_t *idstr = svn_fs_x__id_unparse(node->id, pool);
+      svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, pool);
       return svn_error_createf
         (SVN_ERR_FS_NOT_MUTABLE, NULL,
          "Can't increment mergeinfo count on *immutable* node-revision %s",
@@ -546,7 +598,7 @@ svn_fs_x__dag_increment_mergeinfo_count(
   noderev->mergeinfo_count += increment;
   if (noderev->mergeinfo_count < 0)
     {
-      svn_string_t *idstr = svn_fs_x__id_unparse(node->id, pool);
+      svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, pool);
       return svn_error_createf
         (SVN_ERR_FS_CORRUPT, NULL,
          apr_psprintf(pool,
@@ -557,7 +609,7 @@ svn_fs_x__dag_increment_mergeinfo_count(
     }
   if (noderev->mergeinfo_count > 1 && noderev->kind == svn_node_file)
     {
-      svn_string_t *idstr = svn_fs_x__id_unparse(node->id, pool);
+      svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, pool);
       return svn_error_createf
         (SVN_ERR_FS_CORRUPT, NULL,
          apr_psprintf(pool,
@@ -568,8 +620,7 @@ svn_fs_x__dag_increment_mergeinfo_count(
     }
 
   /* Flush it out. */
-  return svn_fs_x__put_node_revision(node->fs, noderev->id,
-                                     noderev, FALSE, pool);
+  return svn_fs_x__put_node_revision(node->fs, noderev, FALSE, pool);
 }
 
 svn_error_t *
@@ -577,12 +628,12 @@ svn_fs_x__dag_set_has_mergeinfo(dag_node
                                  svn_boolean_t has_mergeinfo,
                                  apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Sanity check: this node better be mutable! */
   if (! svn_fs_x__dag_check_mutable(node))
     {
-      svn_string_t *idstr = svn_fs_x__id_unparse(node->id, pool);
+      svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, pool);
       return svn_error_createf
         (SVN_ERR_FS_NOT_MUTABLE, NULL,
          "Can't set mergeinfo flag on *immutable* node-revision %s",
@@ -595,8 +646,7 @@ svn_fs_x__dag_set_has_mergeinfo(dag_node
   noderev->has_mergeinfo = has_mergeinfo;
 
   /* Flush it out. */
-  return svn_fs_x__put_node_revision(node->fs, noderev->id,
-                                     noderev, FALSE, pool);
+  return svn_fs_x__put_node_revision(node->fs, noderev, FALSE, pool);
 }
 
 
@@ -614,6 +664,7 @@ svn_fs_x__dag_revision_root(dag_node_t *
   new_node = apr_pcalloc(pool, sizeof(*new_node));
   new_node->fs = fs;
   SVN_ERR(svn_fs_x__rev_get_root(&new_node->id, fs, rev, pool));
+  svn_fs_x__id_reset(&new_node->fresh_root_predecessor_id);
 
   /* Grab the contents so we can inspect the node's kind and created path. */
   new_node->node_pool = pool;
@@ -621,7 +672,6 @@ svn_fs_x__dag_revision_root(dag_node_t *
   /* Initialize the KIND and CREATED_PATH attributes */
   new_node->kind = svn_node_dir;
   new_node->created_path = "/";
-  new_node->fresh_root_predecessor_id = NULL;
 
   /* Return a fresh new node */
   *node_p = new_node;
@@ -635,10 +685,10 @@ svn_fs_x__dag_txn_root(dag_node_t **node
                        svn_fs_x__txn_id_t txn_id,
                        apr_pool_t *pool)
 {
-  const svn_fs_id_t *root_id, *ignored;
+  svn_fs_x__id_t root_id;
 
-  SVN_ERR(svn_fs_x__get_txn_ids(&root_id, &ignored, fs, txn_id, pool));
-  return svn_fs_x__dag_get_node(node_p, fs, root_id, pool);
+  svn_fs_x__init_txn_root(&root_id, txn_id);
+  return svn_fs_x__dag_get_node(node_p, fs, &root_id, pool);
 }
 
 
@@ -648,10 +698,13 @@ svn_fs_x__dag_txn_base_root(dag_node_t *
                             svn_fs_x__txn_id_t txn_id,
                             apr_pool_t *pool)
 {
-  const svn_fs_id_t *base_root_id, *ignored;
+  svn_fs_x__id_t base_root_id;
+  svn_revnum_t base_rev;
+
+  SVN_ERR(svn_fs_x__get_base_rev(&base_rev, fs, txn_id, pool));
 
-  SVN_ERR(svn_fs_x__get_txn_ids(&ignored, &base_root_id, fs, txn_id, pool));
-  return svn_fs_x__dag_get_node(node_p, fs, base_root_id, pool);
+  svn_fs_x__init_rev_root(&base_root_id, base_rev);
+  return svn_fs_x__dag_get_node(node_p, fs, &base_root_id, pool);
 }
 
 
@@ -660,13 +713,13 @@ svn_fs_x__dag_clone_child(dag_node_t **c
                           dag_node_t *parent,
                           const char *parent_path,
                           const char *name,
-                          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,
                           svn_boolean_t is_parent_copyroot,
                           apr_pool_t *pool)
 {
   dag_node_t *cur_entry; /* parent's current entry named NAME */
-  const svn_fs_id_t *new_node_id; /* node id we'll put into NEW_NODE */
+  const svn_fs_x__id_t *new_node_id; /* node id we'll put into NEW_NODE */
   svn_fs_t *fs = svn_fs_x__dag_get_fs(parent);
   apr_pool_t *subpool = svn_pool_create(pool);
 
@@ -694,11 +747,11 @@ svn_fs_x__dag_clone_child(dag_node_t **c
   if (svn_fs_x__dag_check_mutable(cur_entry))
     {
       /* This has already been cloned */
-      new_node_id = cur_entry->id;
+      new_node_id = svn_fs_x__dag_get_id(cur_entry);
     }
   else
     {
-      node_revision_t *noderev, *parent_noderev;
+      svn_fs_x__noderev_t *noderev, *parent_noderev;
 
       /* Go get a fresh NODE-REVISION for current child node. */
       SVN_ERR(get_node_revision(&noderev, cur_entry));
@@ -714,13 +767,16 @@ svn_fs_x__dag_clone_child(dag_node_t **c
       noderev->copyfrom_path = NULL;
       noderev->copyfrom_rev = SVN_INVALID_REVNUM;
 
-      noderev->predecessor_id = svn_fs_x__id_copy(cur_entry->id, pool);
+      noderev->predecessor_id = noderev->noderev_id;
       if (noderev->predecessor_count != -1)
         noderev->predecessor_count++;
       noderev->created_path = svn_fspath__join(parent_path, name, pool);
 
-      SVN_ERR(svn_fs_x__create_successor(&new_node_id, fs, cur_entry->id,
-                                          noderev, copy_id, txn_id, pool));
+      if (copy_id == NULL)
+        copy_id = &noderev->copy_id;
+
+      SVN_ERR(svn_fs_x__create_successor(fs, noderev, copy_id, txn_id, pool));
+      new_node_id = &noderev->noderev_id;
 
       /* Replace the ID in the parent's ENTRY list with the ID which
          refers to the mutable clone of this child. */
@@ -741,24 +797,11 @@ svn_fs_x__dag_clone_root(dag_node_t **ro
                          svn_fs_x__txn_id_t txn_id,
                          apr_pool_t *pool)
 {
-  const svn_fs_id_t *base_root_id, *root_id;
-
-  /* Get the node ID's of the root directories of the transaction and
-     its base revision.  */
-  SVN_ERR(svn_fs_x__get_txn_ids(&root_id, &base_root_id, fs, txn_id, pool));
-
-  /* Oh, give me a clone...
-     (If they're the same, we haven't cloned the transaction's root
-     directory yet.)  */
-  SVN_ERR_ASSERT(!svn_fs_x__id_eq(root_id, base_root_id));
-
-  /*
-   * (Sung to the tune of "Home, Home on the Range", with thanks to
-   * Randall Garrett and Isaac Asimov.)
-   */
+  svn_fs_x__id_t root_id;
+  svn_fs_x__init_txn_root(&root_id, txn_id);
 
   /* One way or another, root_id now identifies a cloned root node. */
-  return svn_fs_x__dag_get_node(root_p, fs, root_id, pool);
+  return svn_fs_x__dag_get_node(root_p, fs, &root_id, pool);
 }
 
 
@@ -768,10 +811,9 @@ svn_fs_x__dag_delete(dag_node_t *parent,
                      svn_fs_x__txn_id_t txn_id,
                      apr_pool_t *pool)
 {
-  node_revision_t *parent_noderev;
+  svn_fs_x__noderev_t *parent_noderev;
   svn_fs_t *fs = parent->fs;
-  svn_fs_dirent_t *dirent;
-  svn_fs_id_t *id;
+  svn_fs_x__dirent_t *dirent;
   apr_pool_t *subpool;
 
   /* Make sure parent is a directory. */
@@ -809,13 +851,9 @@ svn_fs_x__dag_delete(dag_node_t *parent,
       (SVN_ERR_FS_NO_SUCH_ENTRY, NULL,
        "Delete failed--directory has no entry '%s'", name);
 
-  /* Copy the ID out of the subpool and release the rest of the
-     directory listing. */
-  id = svn_fs_x__id_copy(dirent->id, pool);
-  svn_pool_destroy(subpool);
-
   /* If mutable, remove it and any mutable children from db. */
-  SVN_ERR(svn_fs_x__dag_delete_if_mutable(parent->fs, id, pool));
+  SVN_ERR(svn_fs_x__dag_delete_if_mutable(parent->fs, &dirent->id, pool));
+  svn_pool_destroy(subpool);
 
   /* Remove this entry from its parent's entries list. */
   return svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name,
@@ -824,28 +862,8 @@ svn_fs_x__dag_delete(dag_node_t *parent,
 
 
 svn_error_t *
-svn_fs_x__dag_remove_node(svn_fs_t *fs,
-                          const svn_fs_id_t *id,
-                          apr_pool_t *pool)
-{
-  dag_node_t *node;
-
-  /* Fetch the node. */
-  SVN_ERR(svn_fs_x__dag_get_node(&node, fs, id, pool));
-
-  /* If immutable, do nothing and return immediately. */
-  if (! svn_fs_x__dag_check_mutable(node))
-    return svn_error_createf(SVN_ERR_FS_NOT_MUTABLE, NULL,
-                             "Attempted removal of immutable node");
-
-  /* Delete the node revision. */
-  return svn_fs_x__delete_node_revision(fs, id, pool);
-}
-
-
-svn_error_t *
 svn_fs_x__dag_delete_if_mutable(svn_fs_t *fs,
-                                const svn_fs_id_t *id,
+                                const svn_fs_x__id_t *id,
                                 apr_pool_t *pool)
 {
   dag_node_t *node;
@@ -862,19 +880,26 @@ svn_fs_x__dag_delete_if_mutable(svn_fs_t
     {
       apr_array_header_t *entries;
       int i;
+      apr_pool_t *iterpool = svn_pool_create(pool);
 
       /* Loop over directory entries */
       SVN_ERR(svn_fs_x__dag_dir_entries(&entries, node, pool));
       if (entries)
         for (i = 0; i < entries->nelts; ++i)
-          SVN_ERR(svn_fs_x__dag_delete_if_mutable(fs,
-                        APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *)->id,
-                        pool));
+          {
+            const svn_fs_x__id_t *noderev_id
+              = &APR_ARRAY_IDX(entries, i, svn_fs_x__dirent_t *)->id;
+
+            svn_pool_clear(iterpool);
+            SVN_ERR(svn_fs_x__dag_delete_if_mutable(fs, noderev_id, pool));
+          }
+
+      svn_pool_destroy(iterpool);
     }
 
   /* ... then delete the node itself, after deleting any mutable
      representations and strings it points to. */
-  return svn_fs_x__dag_remove_node(fs, id, pool);
+  return svn_fs_x__delete_node_revision(fs, id, pool);
 }
 
 svn_error_t *
@@ -908,7 +933,7 @@ svn_fs_x__dag_get_contents(svn_stream_t
                            dag_node_t *file,
                            apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
   svn_stream_t *contents;
 
   /* Make sure our node is a file. */
@@ -936,8 +961,8 @@ svn_fs_x__dag_get_file_delta_stream(svn_
                                     dag_node_t *target,
                                     apr_pool_t *pool)
 {
-  node_revision_t *src_noderev;
-  node_revision_t *tgt_noderev;
+  svn_fs_x__noderev_t *src_noderev;
+  svn_fs_x__noderev_t *tgt_noderev;
 
   /* Make sure our nodes are files. */
   if ((source && source->kind != svn_node_file)
@@ -966,7 +991,7 @@ svn_fs_x__dag_try_process_file_contents(
                                         void* baton,
                                         apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Go get fresh node-revisions for the nodes. */
   SVN_ERR(get_node_revision(&noderev, node));
@@ -982,7 +1007,7 @@ svn_fs_x__dag_file_length(svn_filesize_t
                           dag_node_t *file,
                           apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Make sure our node is a file. */
   if (file->kind != svn_node_file)
@@ -1003,7 +1028,7 @@ svn_fs_x__dag_file_checksum(svn_checksum
                             svn_checksum_kind_t kind,
                             apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   if (file->kind != svn_node_file)
     return svn_error_createf
@@ -1021,7 +1046,7 @@ svn_fs_x__dag_get_edit_stream(svn_stream
                               dag_node_t *file,
                               apr_pool_t *pool)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
   svn_stream_t *ws;
 
   /* Make sure our node is a file. */
@@ -1074,27 +1099,29 @@ svn_fs_x__dag_dup(const dag_node_t *node
                   apr_pool_t *pool)
 {
   /* Allocate our new node. */
-  dag_node_t *new_node = apr_pcalloc(pool, sizeof(*new_node));
-
-  new_node->fs = node->fs;
-  new_node->id = svn_fs_x__id_copy(node->id, pool);
-  new_node->kind = node->kind;
+  dag_node_t *new_node = apr_pmemdup(pool, node, sizeof(*new_node));
   new_node->created_path = apr_pstrdup(pool, node->created_path);
 
-  /* Only copy cached node_revision_t for immutable nodes. */
+  /* Only copy cached svn_fs_x__noderev_t for immutable nodes. */
   if (node->node_revision && !svn_fs_x__dag_check_mutable(node))
-    {
-      new_node->node_revision = copy_node_revision(node->node_revision, pool);
-      new_node->node_revision->id =
-          svn_fs_x__id_copy(node->node_revision->id, pool);
-      new_node->node_revision->is_fresh_txn_root =
-          node->node_revision->is_fresh_txn_root;
-    }
+    new_node->node_revision = copy_node_revision(node->node_revision, pool);
+  else
+    new_node->node_revision = NULL;
+
   new_node->node_pool = pool;
 
   return new_node;
 }
 
+dag_node_t *
+svn_fs_x__dag_copy_into_pool(dag_node_t *node,
+                             apr_pool_t *pool)
+{
+  return (node->node_pool == pool
+            ? node
+            : svn_fs_x__dag_dup(node, pool));
+}
+
 svn_error_t *
 svn_fs_x__dag_serialize(void **data,
                         apr_size_t *data_len,
@@ -1123,8 +1150,6 @@ svn_fs_x__dag_serialize(void **data,
                                 (const void * const *)&node->node_pool);
 
   /* serialize other sub-structures */
-  svn_fs_x__id_serialize(context, (const svn_fs_id_t **)&node->id);
-  svn_fs_x__id_serialize(context, &node->fresh_root_predecessor_id);
   svn_temp_serializer__add_string(context, &node->created_path);
 
   /* return serialized data */
@@ -1150,10 +1175,6 @@ svn_fs_x__dag_deserialize(void **out,
   node->fs = NULL;
 
   /* fixup all references to sub-structures */
-  svn_fs_x__id_deserialize(node, &node->id, pool);
-  svn_fs_x__id_deserialize(node,
-                           (svn_fs_id_t **)&node->fresh_root_predecessor_id,
-                           pool);
   svn_fs_x__noderev_deserialize(node, &node->node_revision, pool);
   node->node_pool = pool;
 
@@ -1172,12 +1193,11 @@ svn_fs_x__dag_open(dag_node_t **child_p,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
-  const svn_fs_id_t *node_id;
+  svn_fs_x__id_t node_id;
 
   /* Ensure that NAME exists in PARENT's entry list. */
-  SVN_ERR(dir_entry_id_from_node(&node_id, parent, name,
-                                 scratch_pool, scratch_pool));
-  if (! node_id)
+  SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, scratch_pool));
+  if (! svn_fs_x__id_used(&node_id))
     {
       *child_p = NULL;
       return SVN_NO_ERROR;
@@ -1191,7 +1211,7 @@ svn_fs_x__dag_open(dag_node_t **child_p,
 
   /* Now get the node that was requested. */
   return svn_fs_x__dag_get_node(child_p, svn_fs_x__dag_get_fs(parent),
-                                node_id, result_pool);
+                                &node_id, result_pool);
 }
 
 
@@ -1205,13 +1225,12 @@ svn_fs_x__dag_copy(dag_node_t *to_node,
                    svn_fs_x__txn_id_t txn_id,
                    apr_pool_t *pool)
 {
-  const svn_fs_id_t *id;
+  const svn_fs_x__id_t *id;
 
   if (preserve_history)
     {
-      node_revision_t *from_noderev, *to_noderev;
-      svn_fs_x__id_part_t copy_id;
-      const svn_fs_id_t *src_id = svn_fs_x__dag_get_id(from_node);
+      svn_fs_x__noderev_t *from_noderev, *to_noderev;
+      svn_fs_x__id_t copy_id;
       svn_fs_t *fs = svn_fs_x__dag_get_fs(from_node);
 
       /* Make a copy of the original node revision. */
@@ -1223,7 +1242,7 @@ svn_fs_x__dag_copy(dag_node_t *to_node,
 
       /* Create a successor with its predecessor pointing at the copy
          source. */
-      to_noderev->predecessor_id = svn_fs_x__id_copy(src_id, pool);
+      to_noderev->predecessor_id = to_noderev->noderev_id;
       if (to_noderev->predecessor_count != -1)
         to_noderev->predecessor_count++;
       to_noderev->created_path =
@@ -1235,9 +1254,9 @@ svn_fs_x__dag_copy(dag_node_t *to_node,
       /* Set the copyroot equal to our own id. */
       to_noderev->copyroot_path = NULL;
 
-      SVN_ERR(svn_fs_x__create_successor(&id, fs, src_id, to_noderev,
+      SVN_ERR(svn_fs_x__create_successor(fs, to_noderev,
                                          &copy_id, txn_id, pool));
-
+      id = &to_noderev->noderev_id;
     }
   else  /* don't preserve history */
     {
@@ -1261,7 +1280,7 @@ svn_fs_x__dag_things_different(svn_boole
                                svn_boolean_t strict,
                                apr_pool_t *pool)
 {
-  node_revision_t *noderev1, *noderev2;
+  svn_fs_x__noderev_t *noderev1, *noderev2;
   svn_fs_t *fs;
   svn_boolean_t same;
 
@@ -1297,7 +1316,7 @@ svn_fs_x__dag_get_copyroot(svn_revnum_t
                            const char **path,
                            dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Go get a fresh node-revision for NODE. */
   SVN_ERR(get_node_revision(&noderev, node));
@@ -1312,7 +1331,7 @@ svn_error_t *
 svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev,
                                dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Go get a fresh node-revision for NODE. */
   SVN_ERR(get_node_revision(&noderev, node));
@@ -1326,7 +1345,7 @@ svn_error_t *
 svn_fs_x__dag_get_copyfrom_path(const char **path,
                                 dag_node_t *node)
 {
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Go get a fresh node-revision for NODE. */
   SVN_ERR(get_node_revision(&noderev, node));
@@ -1341,7 +1360,7 @@ svn_fs_x__dag_update_ancestry(dag_node_t
                               dag_node_t *source,
                               apr_pool_t *pool)
 {
-  node_revision_t *source_noderev, *target_noderev;
+  svn_fs_x__noderev_t *source_noderev, *target_noderev;
 
   if (! svn_fs_x__dag_check_mutable(target))
     return svn_error_createf
@@ -1351,11 +1370,11 @@ svn_fs_x__dag_update_ancestry(dag_node_t
   SVN_ERR(get_node_revision(&source_noderev, source));
   SVN_ERR(get_node_revision(&target_noderev, target));
 
-  target_noderev->predecessor_id = source->id;
+  target_noderev->predecessor_id = source_noderev->noderev_id;
   target_noderev->predecessor_count = source_noderev->predecessor_count;
   if (target_noderev->predecessor_count != -1)
     target_noderev->predecessor_count++;
 
-  return svn_fs_x__put_node_revision(target->fs, target->id, target_noderev,
-                                     FALSE, pool);
+  return svn_fs_x__put_node_revision(target->fs, target_noderev, FALSE,
+                                     pool);
 }

Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/dag.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/dag.h?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_x/dag.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_x/dag.h Sat Jan  3 14:00:41 2015
@@ -27,6 +27,7 @@
 #include "svn_delta.h"
 #include "private/svn_cache.h"
 
+#include "fs.h"
 #include "id.h"
 
 #ifdef __cplusplus
@@ -68,7 +69,7 @@ typedef struct dag_node_t dag_node_t;
 svn_error_t *
 svn_fs_x__dag_get_node(dag_node_t **node,
                        svn_fs_t *fs,
-                       const svn_fs_id_t *id,
+                       const svn_fs_x__id_t *id,
                        apr_pool_t *pool);
 
 
@@ -80,6 +81,12 @@ dag_node_t *
 svn_fs_x__dag_dup(const dag_node_t *node,
                   apr_pool_t *pool);
 
+/* If NODE has been allocated in POOL, return NODE.  Otherwise, return
+   a copy created in POOL with svn_fs_fs__dag_dup. */
+dag_node_t *
+svn_fs_x__dag_copy_into_pool(dag_node_t *node,
+                             apr_pool_t *pool);
+
 /* Serialize a DAG node, except don't try to preserve the 'fs' member.
    Implements svn_cache__serialize_func_t */
 svn_error_t *
@@ -104,28 +111,49 @@ svn_fs_t *svn_fs_x__dag_get_fs(dag_node_
 void svn_fs_x__dag_set_fs(dag_node_t *node, svn_fs_t *fs);
 
 
-/* Set *REV to NODE's revision number, allocating in POOL.  If NODE
-   has never been committed as part of a revision, set *REV to
-   SVN_INVALID_REVNUM.  */
-svn_error_t *svn_fs_x__dag_get_revision(svn_revnum_t *rev,
-                                        dag_node_t *node,
-                                        apr_pool_t *pool);
+/* Return NODE's revision number.  If NODE has never been committed as
+   part of a revision, set *REV to SVN_INVALID_REVNUM.  */
+svn_revnum_t svn_fs_x__dag_get_revision(const dag_node_t *node);
 
 
 /* Return the node revision ID of NODE.  The value returned is shared
    with NODE, and will be deallocated when NODE is.  */
-const svn_fs_id_t *svn_fs_x__dag_get_id(const dag_node_t *node);
+const svn_fs_x__id_t *
+svn_fs_x__dag_get_id(const dag_node_t *node);
 
+/* Return the node ID of NODE.  The value returned is shared with NODE,
+   and will be deallocated when NODE is.  */
+svn_error_t *
+svn_fs_x__dag_get_node_id(svn_fs_x__id_t *node_id,
+                          dag_node_t *node);
+
+/* Return the copy ID of NODE.  The value returned is shared with NODE,
+   and will be deallocated when NODE is.  */
+svn_error_t *
+svn_fs_x__dag_get_copy_id(svn_fs_x__id_t *copy_id,
+                          dag_node_t *node);
+
+/* Set *SAME to TRUE, if nodes LHS and RHS have the same node ID. */
+svn_error_t *
+svn_fs_x__dag_related_node(svn_boolean_t *same,
+                           dag_node_t *lhs,
+                           dag_node_t *rhs);
+
+/* Set *SAME to TRUE, if nodes LHS and RHS have the same node and copy IDs.
+ */
+svn_error_t *
+svn_fs_x__dag_same_line_of_history(svn_boolean_t *same,
+                                   dag_node_t *lhs,
+                                   dag_node_t *rhs);
 
 /* Return the created path of NODE.  The value returned is shared
    with NODE, and will be deallocated when NODE is.  */
 const char *svn_fs_x__dag_get_created_path(dag_node_t *node);
 
 
-/* Set *ID_P to the node revision ID of NODE's immediate predecessor,
-   or NULL if NODE has no predecessor.
+/* Set *ID_P to the node revision ID of NODE's immediate predecessor.
  */
-svn_error_t *svn_fs_x__dag_get_predecessor_id(const svn_fs_id_t **id_p,
+svn_error_t *svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p,
                                               dag_node_t *node);
 
 
@@ -266,7 +294,7 @@ svn_fs_x__dag_open(dag_node_t **child_p,
 
 
 /* Set *ENTRIES_P to an array of NODE's entries, sorted by entry names,
-   and the values are svn_fs_dirent_t's.  The returned table (and elements)
+   and the values are svn_fs_x__dirent_t. The returned table (and elements)
    is allocated in POOL, which is also used for temporary allocations. */
 svn_error_t *svn_fs_x__dag_dir_entries(apr_array_header_t **entries_p,
                                        dag_node_t *node,
@@ -279,7 +307,7 @@ svn_error_t *svn_fs_x__dag_dir_entries(a
    Otherwise, the *DIRENT will be set to NULL.
  */
 /* ### This function is currently only called from dag.c. */
-svn_error_t * svn_fs_x__dag_dir_entry(svn_fs_dirent_t **dirent,
+svn_error_t * svn_fs_x__dag_dir_entry(svn_fs_x__dirent_t **dirent,
                                       dag_node_t *node,
                                       const char* name,
                                       apr_pool_t *result_pool,
@@ -296,7 +324,7 @@ svn_error_t * svn_fs_x__dag_dir_entry(sv
  */
 svn_error_t *svn_fs_x__dag_set_entry(dag_node_t *node,
                                      const char *entry_name,
-                                     const svn_fs_id_t *id,
+                                     const svn_fs_x__id_t *id,
                                      svn_node_kind_t kind,
                                      svn_fs_x__txn_id_t txn_id,
                                      apr_pool_t *pool);
@@ -325,7 +353,7 @@ svn_error_t *svn_fs_x__dag_clone_child(d
                                        dag_node_t *parent,
                                        const char *parent_path,
                                        const char *name,
-                                       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,
                                        svn_boolean_t is_parent_copyroot,
                                        apr_pool_t *pool);
@@ -349,27 +377,13 @@ svn_error_t *svn_fs_x__dag_delete(dag_no
                                   apr_pool_t *pool);
 
 
-/* Delete the node revision assigned to node ID from FS's `nodes'
-   table, allocating from POOL.  Also delete any mutable
-   representations and strings associated with that node revision.  ID
-   may refer to a file or directory, which must be mutable.
-
-   NOTE: If ID represents a directory, and that directory has mutable
-   children, you risk orphaning those children by leaving them
-   dangling, disconnected from all DAG trees.  It is assumed that
-   callers of this interface know what in the world they are doing.  */
-svn_error_t *svn_fs_x__dag_remove_node(svn_fs_t *fs,
-                                       const svn_fs_id_t *id,
-                                       apr_pool_t *pool);
-
-
 /* Delete all mutable node revisions reachable from node ID, including
    ID itself, from FS's `nodes' table, allocating from POOL.  Also
    delete any mutable representations and strings associated with that
    node revision.  ID may refer to a file or directory, which may be
    mutable or immutable. */
 svn_error_t *svn_fs_x__dag_delete_if_mutable(svn_fs_t *fs,
-                                             const svn_fs_id_t *id,
+                                             const svn_fs_x__id_t *id,
                                              apr_pool_t *pool);
 
 

Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/fs.c?rev=1649205&r1=1649204&r2=1649205&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_x/fs.c Sat Jan  3 14:00:41 2015
@@ -45,6 +45,7 @@
 #include "revprops.h"
 #include "rep-cache.h"
 #include "transaction.h"
+#include "util.h"
 #include "svn_private_config.h"
 #include "private/svn_fs_util.h"
 
@@ -62,30 +63,38 @@
 static svn_error_t *
 x_serialized_init(svn_fs_t *fs, apr_pool_t *common_pool, apr_pool_t *pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
   const char *key;
   void *val;
-  fs_x_shared_data_t *ffsd;
+  svn_fs_x__shared_data_t *ffsd;
   apr_status_t status;
 
   /* Note that we are allocating a small amount of long-lived data for
      each separate repository opened during the lifetime of the
      svn_fs_initialize pool.  It's unlikely that anyone will notice
      the modest expenditure; the alternative is to allocate each structure
-     in a subpool, add a reference-count, and add a serialized deconstructor
+     in a subpool, add a reference-count, and add a serialized destructor
      to the FS vtable.  That's more machinery than it's worth.
 
-     Using the uuid to obtain the lock creates a corner case if a
-     caller uses svn_fs_set_uuid on the repository in a process where
-     other threads might be using the same repository through another
-     FS object.  The only real-world consumer of svn_fs_set_uuid is
-     "svnadmin load", so this is a low-priority problem, and we don't
-     know of a better way of associating such data with the
-     repository. */
+     Picking an appropriate key for the shared data is tricky, because,
+     unfortunately, a filesystem UUID is not really unique.  It is implicitly
+     shared between hotcopied (1), dump / loaded (2) or naively copied (3)
+     filesystems.  We tackle this problem by using a combination of the UUID
+     and an instance ID as the key.  This allows us to avoid key clashing
+     in (1) and (2).
+
+     Speaking of (3), there is not so much we can do about it, except maybe
+     provide a convenient way of fixing things.  Naively copied filesystems
+     have identical filesystem UUIDs *and* instance IDs.  With the key being
+     a combination of these two, clashes can be fixed by changing either of
+     them (or both), e.g. with svn_fs_set_uuid(). */
+
 
   SVN_ERR_ASSERT(fs->uuid);
-  key = apr_pstrcat(pool, SVN_FSX_SHARED_USERDATA_PREFIX, fs->uuid,
-                    SVN_VA_NULL);
+  SVN_ERR_ASSERT(ffd->instance_id);
+
+  key = apr_pstrcat(pool, SVN_FSX_SHARED_USERDATA_PREFIX,
+                    fs->uuid, ":", ffd->instance_id, SVN_VA_NULL);
   status = apr_pool_userdata_get(&val, key, common_pool);
   if (status)
     return svn_error_wrap_apr(status, _("Can't fetch FSX shared data"));
@@ -99,13 +108,16 @@ x_serialized_init(svn_fs_t *fs, apr_pool
       /* POSIX fcntl locks are per-process, so we need a mutex for
          intra-process synchronization when grabbing the repository write
          lock. */
-      SVN_ERR(svn_mutex__init(&ffsd->fs_write_lock, TRUE, common_pool));
+      SVN_ERR(svn_mutex__init(&ffsd->fs_write_lock,
+                              SVN_FS_X__USE_LOCK_MUTEX, common_pool));
 
       /* ... the pack lock ... */
-      SVN_ERR(svn_mutex__init(&ffsd->fs_pack_lock, TRUE, common_pool));
+      SVN_ERR(svn_mutex__init(&ffsd->fs_pack_lock,
+                              SVN_FS_X__USE_LOCK_MUTEX, common_pool));
 
       /* ... not to mention locking the txn-current file. */
-      SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock, TRUE, common_pool));
+      SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock,
+                              SVN_FS_X__USE_LOCK_MUTEX, common_pool));
 
       /* We also need a mutex for synchronizing access to the active
          transaction list and free transaction pointer. */
@@ -158,6 +170,16 @@ x_freeze_body(void *baton,
 }
 
 static svn_error_t *
+x_freeze_body2(void *baton,
+               apr_pool_t *pool)
+{
+  struct x_freeze_baton_t *b = baton;
+  SVN_ERR(svn_fs_x__with_write_lock(b->fs, x_freeze_body, baton, pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 x_freeze(svn_fs_t *fs,
          svn_fs_freeze_func_t freeze_func,
          void *freeze_baton,
@@ -170,7 +192,7 @@ x_freeze(svn_fs_t *fs,
   b.freeze_baton = freeze_baton;
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
-  SVN_ERR(svn_fs_x__with_write_lock(fs, x_freeze_body, &b, pool));
+  SVN_ERR(svn_fs_x__with_pack_lock(fs, x_freeze_body2, &b, pool));
 
   return SVN_NO_ERROR;
 }
@@ -181,7 +203,7 @@ x_info(const void **fsx_info,
        apr_pool_t *result_pool,
        apr_pool_t *scratch_pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_fs_fsx_info_t *info = apr_palloc(result_pool, sizeof(*info));
   info->fs_type = SVN_FS_TYPE_FSX;
   info->shard_size = ffd->max_files_per_dir;
@@ -190,15 +212,40 @@ x_info(const void **fsx_info,
   return SVN_NO_ERROR;
 }
 
+/* Wrapper around svn_fs_x__get_revision_proplist() adapting between function
+   signatures. */
+static svn_error_t *
+x_revision_proplist(apr_hash_t **proplist_p,
+                    svn_fs_t *fs,
+                    svn_revnum_t rev,
+                    apr_pool_t *pool)
+{
+  /* No need to bypass the caches for r/o access to revprops. */
+  return svn_error_trace(svn_fs_x__get_revision_proplist(proplist_p, fs,
+                                                         rev, FALSE, pool));
+}
+
+/* Wrapper around svn_fs_x__set_uuid() adapting between function
+   signatures. */
+static svn_error_t *
+x_set_uuid(svn_fs_t *fs,
+           const char *uuid,
+           apr_pool_t *pool)
+{
+  /* Whenever we set a new UUID, imply that FS will also be a different
+   * instance (on formats that support this). */
+  return svn_error_trace(svn_fs_x__set_uuid(fs, uuid, NULL, pool));
+}
+
 
 
 /* The vtable associated with a specific open filesystem. */
 static fs_vtable_t fs_vtable = {
   svn_fs_x__youngest_rev,
   svn_fs_x__revision_prop,
-  svn_fs_x__revision_proplist,
+  x_revision_proplist,
   svn_fs_x__change_rev_prop,
-  svn_fs_x__set_uuid,
+  x_set_uuid,
   svn_fs_x__revision_root,
   svn_fs_x__begin_txn,
   svn_fs_x__open_txn,
@@ -225,12 +272,21 @@ static fs_vtable_t fs_vtable = {
 static svn_error_t *
 initialize_fs_struct(svn_fs_t *fs)
 {
-  fs_x_data_t *ffd = apr_pcalloc(fs->pool, sizeof(*ffd));
+  svn_fs_x__data_t *ffd = apr_pcalloc(fs->pool, sizeof(*ffd));
   fs->vtable = &fs_vtable;
   fs->fsap_data = ffd;
   return SVN_NO_ERROR;
 }
 
+/* Reset vtable and fsap_data fields in FS such that the FS is basically
+ * closed now.  Note that FS must not hold locks when you call this. */
+static void
+uninitialize_fs_struct(svn_fs_t *fs)
+{
+  fs->vtable = NULL;
+  fs->fsap_data = NULL;
+}
+
 /* This implements the fs_library_vtable_t.create() API.  Create a new
    fsx-backed Subversion filesystem at path PATH and link it into
    *FS.  Perform temporary allocations in POOL, and fs-global allocations
@@ -298,20 +354,53 @@ x_open_for_recovery(svn_fs_t *fs,
                     apr_pool_t *pool,
                     apr_pool_t *common_pool)
 {
-  /* Recovery for FSX is currently limited to recreating the 'current'
+  svn_error_t * err;
+  svn_revnum_t youngest_rev;
+  apr_pool_t * subpool = svn_pool_create(pool);
+
+  /* Recovery for FSFS is currently limited to recreating the 'current'
      file from the latest revision. */
 
   /* The only thing we have to watch out for is that the 'current' file
-     might not exist.  So we'll try to create it here unconditionally,
-     and just ignore any errors that might indicate that it's already
-     present. (We'll need it to exist later anyway as a source for the
-     new file's permissions). */
+     might not exist or contain garbage.  So we'll try to read it here
+     and provide or replace the existing file if we couldn't read it.
+     (We'll also need it to exist later anyway as a source for the new
+     file's permissions). */
 
-  /* Use a partly-filled fs pointer first to create 'current'.  This will fail
-     if 'current' already exists, but we don't care about that. */
+  /* Use a partly-filled fs pointer first to create 'current'. */
   fs->path = apr_pstrdup(fs->pool, path);
-  svn_error_clear(svn_io_file_create(svn_fs_x__path_current(fs, pool),
-                                     "0 1 1\n", pool));
+
+  SVN_ERR(initialize_fs_struct(fs));
+
+  /* Figure out the repo format and check that we can even handle it. */
+  SVN_ERR(svn_fs_x__read_format_file(fs, subpool));
+
+  /* Now, read 'current' and try to patch it if necessary. */
+  err = svn_fs_x__youngest_rev(&youngest_rev, fs, subpool);
+  if (err)
+    {
+      const char *file_path;
+
+      /* 'current' file is missing or contains garbage.  Since we are trying
+       * to recover from whatever problem there is, being picky about the
+       * error code here won't do us much good.  If there is a persistent
+       * problem that we can't fix, it will show up when we try rewrite the
+       * file a few lines further below and we will report the failure back
+       * to the caller.
+       *
+       * Start recovery with HEAD = 0. */
+      svn_error_clear(err);
+      file_path = svn_fs_x__path_current(fs, subpool);
+
+      /* Best effort to ensure the file exists and is valid.
+       * This may fail for r/o filesystems etc. */
+      SVN_ERR(svn_io_remove_file2(file_path, TRUE, subpool));
+      SVN_ERR(svn_io_file_create_empty(file_path, subpool));
+      SVN_ERR(svn_fs_x__write_current(fs, 0, subpool));
+    }
+
+  uninitialize_fs_struct(fs);
+  svn_pool_destroy(subpool);
 
   /* Now open the filesystem properly by calling the vtable method directly. */
   return x_open(fs, path, common_pool_lock, pool, common_pool);
@@ -399,11 +488,13 @@ x_hotcopy(svn_fs_t *src_fs,
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
 
-  /* Provide FFD for DST_FS, test / initialize target repo, remove FFD. */
+  /* Test target repo when in INCREMENTAL mode, initialize it when not.
+   * For this, we need our FS internal data structures to be temporarily
+   * available. */
   SVN_ERR(initialize_fs_struct(dst_fs));
   SVN_ERR(svn_fs_x__hotcopy_prepare_target(src_fs, dst_fs, dst_path,
                                            incremental, pool));
-  dst_fs->fsap_data = NULL;
+  uninitialize_fs_struct(dst_fs);
 
   /* Now, the destination repo should open just fine. */
   SVN_ERR(x_open(dst_fs, dst_path, common_pool_lock, pool, common_pool));
@@ -411,8 +502,9 @@ x_hotcopy(svn_fs_t *src_fs,
     SVN_ERR(cancel_func(cancel_baton));
 
   /* Now, we may copy data as needed ... */
-  return svn_fs_x__hotcopy(src_fs, dst_fs,
-                           incremental, cancel_func, cancel_baton, pool);
+  return svn_fs_x__hotcopy(src_fs, dst_fs, incremental,
+                           notify_func, notify_baton,
+                           cancel_func, cancel_baton, pool);
 }
 
 
@@ -443,7 +535,7 @@ x_delete_fs(const char *path,
             apr_pool_t *pool)
 {
   /* Remove everything. */
-  return svn_io_remove_dir2(path, FALSE, NULL, NULL, pool);
+  return svn_error_trace(svn_io_remove_dir2(path, FALSE, NULL, NULL, pool));
 }
 
 static const svn_version_t *
@@ -466,7 +558,7 @@ x_set_svn_fs_open(svn_fs_t *fs,
                                                apr_pool_t *,
                                                apr_pool_t *))
 {
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
   ffd->svn_fs_open_ = svn_fs_open_;
   return SVN_NO_ERROR;
 }