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 2013/03/08 12:38:25 UTC

svn commit: r1454329 - in /subversion/branches/fsfs-format7/subversion/libsvn_fs_fs: dag.c dag.h fs.h fs_fs.c fs_fs.h id.c id.h recovery.c transaction.c transaction.h tree.c util.c util.h

Author: stefan2
Date: Fri Mar  8 11:38:25 2013
New Revision: 1454329

URL: http://svn.apache.org/r1454329
Log:
On the fsfs-format7 branch:  Switch the internal representation of copy
and node IDs from strings to integer pairs.  Informally, they have been
integer pairs in preformat7 repos but now this is formalized.  Replace
the types in a gazillion places and update users and API callers.

Transaction IDs remain strings in this patch but will be replaced by the
same ID part structs in a later patch.

This is the second larger patch in the "numerical IDs" patch series.

* subversion/libsvn_fs_fs/id.h
  (svn_fs_fs__id_part_t): define new struct to replace ID strings
  (svn_fs_fs__id_part_is_root,
   svn_fs_fs__id_part_eq): declare new convenience functions on ID parts
  (svn_fs_fs__id_node_id,
   svn_fs_fs__id_copy_id): return ID parts instead of strings
  (svn_fs_fs__id_txn_create,
   svn_fs_fs__id_rev_create): accept ID parts instead of strings

* subversion/libsvn_fs_fs/id.c
  (fs_fs__id_t): replace node & copy ID stringd with svn_fs_fs__id_part_t
  (part_parse,
   unparse_id_part): new string <-> ID part conversion utilities
  (svn_fs_fs__id_part_is_root,
   svn_fs_fs__id_part_eq): implement
  (svn_fs_fs__id_node_id,
   svn_fs_fs__id_copy_id,
   svn_fs_fs__id_unparse,
   svn_fs_fs__id_eq,
   svn_fs_fs__id_check_related,
   svn_fs_fs__id_txn_create_root,
   svn_fs_fs__id_txn_create,
   svn_fs_fs__id_rev_create,
   svn_fs_fs__id_copy,
   svn_fs_fs__id_parse): update implementation
  (svn_fs_fs__id_serialize,
   svn_fs_fs__id_deserialize): fewer pointers to worry about

* subversion/libsvn_fs_fs/dag.h
  (svn_fs_fs__dag_clone_child): update signature

* subversion/libsvn_fs_fs/dag.c
  (svn_fs_fs__dag_clone_child): ditto
  (svn_fs_fs__dag_copy): update implementation

* subversion/libsvn_fs_fs/util.h
  (path_node_origin): update signature

* subversion/libsvn_fs_fs/util.c
  (path_txn_node_rev,
   path_node_origin): update to converting ID parts to strings

* subversion/libsvn_fs_fs/fs_fs.h
  (svn_fs_fs__set_node_origin,
   svn_fs_fs__get_node_origin): update signatures

* subversion/libsvn_fs_fs/fs_fs.c
  (svn_fs_fs__set_node_origin,
   svn_fs_fs__get_node_origin): update signatures
  (set_node_origins_for_file): convert ID part to string at file interface

* subversion/libsvn_fs_fs/fs.h
  (): make ID parts avaible to private headers

* subversion/libsvn_fs_fs/recovery.c
  (count_from_id): drop
  (recover_find_max_ids): update

* subversion/libsvn_fs_fs/transaction.h
  (svn_fs_fs__reserve_copy_id,
   svn_fs_fs__create_node,
   svn_fs_fs__create_successor): update signatures

* subversion/libsvn_fs_fs/transaction.c
  (create_new_txn_noderev_from_rev,
   svn_fs_fs__create_node): update
  (get_new_txn_node_id,
   svn_fs_fs__reserve_copy_id): update and simplify
  (set_uniquifier): new ints -> string conversion utility function
  (svn_fs_fs__set_entry,
   rep_write_contents_close): update, use new utiltiy function
  (svn_fs_fs__create_successor): update signature
  (get_final_id,
   write_final_rev): update

* subversion/libsvn_fs_fs/tree.c
  (get_copy_inheritance,
   make_path_mutable,
   merge): update, use the new ID part API
  (fs_node_origin_rev): update

Modified:
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.h
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.h
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.c
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.h

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.c Fri Mar  8 11:38:25 2013
@@ -647,7 +647,7 @@ svn_fs_fs__dag_clone_child(dag_node_t **
                            dag_node_t *parent,
                            const char *parent_path,
                            const char *name,
-                           const char *copy_id,
+                           const svn_fs_fs__id_part_t *copy_id,
                            const char *txn_id,
                            svn_boolean_t is_parent_copyroot,
                            apr_pool_t *pool)
@@ -1198,7 +1198,7 @@ svn_fs_fs__dag_copy(dag_node_t *to_node,
   if (preserve_history)
     {
       node_revision_t *from_noderev, *to_noderev;
-      const char *copy_id;
+      svn_fs_fs__id_part_t copy_id;
       const svn_fs_id_t *src_id = svn_fs_fs__dag_get_id(from_node);
       svn_fs_t *fs = svn_fs_fs__dag_get_fs(from_node);
 
@@ -1224,7 +1224,7 @@ svn_fs_fs__dag_copy(dag_node_t *to_node,
       to_noderev->copyroot_path = NULL;
 
       SVN_ERR(svn_fs_fs__create_successor(&id, fs, src_id, to_noderev,
-                                          copy_id, txn_id, pool));
+                                          &copy_id, txn_id, pool));
 
     }
   else  /* don't preserve history */

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.h?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/dag.h Fri Mar  8 11:38:25 2013
@@ -27,6 +27,8 @@
 #include "svn_delta.h"
 #include "private/svn_cache.h"
 
+#include "id.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -323,7 +325,7 @@ svn_error_t *svn_fs_fs__dag_clone_child(
                                         dag_node_t *parent,
                                         const char *parent_path,
                                         const char *name,
-                                        const char *copy_id,
+                                        const svn_fs_fs__id_part_t *copy_id,
                                         const char *txn_id,
                                         svn_boolean_t is_parent_copyroot,
                                         apr_pool_t *pool);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h Fri Mar  8 11:38:25 2013
@@ -36,6 +36,8 @@
 #include "private/svn_mutex.h"
 #include "private/svn_named_atomic.h"
 
+#include "id.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c Fri Mar  8 11:38:25 2013
@@ -38,6 +38,7 @@
 #include "util.h"
 
 #include "private/svn_fs_util.h"
+#include "private/svn_string_private.h"
 #include "../libsvn_fs/fs-loader.h"
 
 #include "svn_private_config.h"
@@ -1143,7 +1144,7 @@ get_node_origins_from_file(svn_fs_t *fs,
 svn_error_t *
 svn_fs_fs__get_node_origin(const svn_fs_id_t **origin_id,
                            svn_fs_t *fs,
-                           const char *node_id,
+                           const svn_fs_fs__id_part_t *node_id,
                            apr_pool_t *pool)
 {
   apr_hash_t *node_origins;
@@ -1169,7 +1170,7 @@ svn_fs_fs__get_node_origin(const svn_fs_
 static svn_error_t *
 set_node_origins_for_file(svn_fs_t *fs,
                           const char *node_origins_path,
-                          const char *node_id,
+                          const svn_fs_fs__id_part_t *node_id,
                           svn_string_t *node_rev_id,
                           apr_pool_t *pool)
 {
@@ -1178,6 +1179,10 @@ set_node_origins_for_file(svn_fs_t *fs,
   apr_hash_t *origins_hash;
   svn_string_t *old_node_rev_id;
 
+  /* the hash serialization functions require strings as keys */
+  char node_id_ptr[SVN_INT64_BUFFER_SIZE];
+  apr_size_t len = svn__ui64tobase36(node_id_ptr, node_id->number);
+
   SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_join(fs->path,
                                                        PATH_NODE_ORIGINS_DIR,
                                                        pool),
@@ -1190,16 +1195,17 @@ set_node_origins_for_file(svn_fs_t *fs,
   if (! origins_hash)
     origins_hash = apr_hash_make(pool);
 
-  old_node_rev_id = apr_hash_get(origins_hash, node_id, APR_HASH_KEY_STRING);
+  old_node_rev_id = apr_hash_get(origins_hash, node_id_ptr, len);
 
   if (old_node_rev_id && !svn_string_compare(node_rev_id, old_node_rev_id))
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Node origin for '%s' exists with a different "
                                "value (%s) than what we were about to store "
                                "(%s)"),
-                             node_id, old_node_rev_id->data, node_rev_id->data);
+                             node_id_ptr, old_node_rev_id->data,
+                             node_rev_id->data);
 
-  apr_hash_set(origins_hash, node_id, APR_HASH_KEY_STRING, node_rev_id);
+  apr_hash_set(origins_hash, node_id_ptr, len, node_rev_id);
 
   /* Sure, there's a race condition here.  Two processes could be
      trying to add different cache elements to the same file at the
@@ -1222,7 +1228,7 @@ set_node_origins_for_file(svn_fs_t *fs,
 
 svn_error_t *
 svn_fs_fs__set_node_origin(svn_fs_t *fs,
-                           const char *node_id,
+                           const svn_fs_fs__id_part_t *node_id,
                            const svn_fs_id_t *node_rev_id,
                            apr_pool_t *pool)
 {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h Fri Mar  8 11:38:25 2013
@@ -202,7 +202,7 @@ svn_error_t *svn_fs_fs__ensure_dir_exist
  */
 svn_error_t *
 svn_fs_fs__set_node_origin(svn_fs_t *fs,
-                           const char *node_id,
+                           const svn_fs_fs__id_part_t *node_id,
                            const svn_fs_id_t *node_rev_id,
                            apr_pool_t *pool);
 
@@ -216,7 +216,7 @@ svn_fs_fs__set_node_origin(svn_fs_t *fs,
 svn_error_t *
 svn_fs_fs__get_node_origin(const svn_fs_id_t **origin_id,
                            svn_fs_t *fs,
-                           const char *node_id,
+                           const svn_fs_fs__id_part_t *node_id,
                            apr_pool_t *pool);
 
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.c Fri Mar  8 11:38:25 2013
@@ -35,31 +35,115 @@ typedef struct fs_fs__id_t
   svn_fs_id_t generic_id;
 
   /* private members */
-  const char *node_id;
-  const char *copy_id;
+  svn_fs_fs__id_part_t node_id;
+  svn_fs_fs__id_part_t copy_id;
   const char *txn_id;
   svn_revnum_t rev;
   apr_uint64_t item;
 } fs_fs__id_t;
 
 
+
+/* Parse the NUL-terminated ID part at DATA and write the result into *PART.
+ * Return TRUE if no errors were detected. */
+static svn_boolean_t
+part_parse(svn_fs_fs__id_part_t *part,
+           const char *data)
+{
+  /* special case: ID inside some transaction */
+  if (data[0] == '_')
+    {
+      part->revision = SVN_INVALID_REVNUM;
+      part->number = svn__base36toui64(&data, data + 1);
+      return *data == '\0';
+    }
+
+  /* special case: 0 / default ID */
+  if (data[0] == '0' && data[1] == '\0')
+    {
+      part->revision = 0;
+      part->number = 0;
+      return TRUE;
+    }
+
+  /* read old style / new style ID */
+  part->number = svn__base36toui64(&data, data);
+  if (data[0] != '-')
+    {
+      part->revision = 0;
+      return *data == '\0';
+    }
+
+  part->revision = SVN_STR_TO_REV(++data);
+
+  return TRUE;
+}
+
+/* Write the textual representation of *PART into P and return a pointer
+ * to the first position behind that string.
+ */
+static char *
+unparse_id_part(char *p,
+                const svn_fs_fs__id_part_t *part)
+{
+  if (SVN_IS_VALID_REVNUM(part->revision))
+    {
+      /* ordinary old style / new style ID */
+      p += svn__ui64tobase36(p, part->number);
+      if (part->revision > 0)
+        {
+          *(p++) = '-';
+          p += svn__i64toa(p, part->revision);
+        }
+    }
+  else
+    {
+      /* in txn: mark with "_" prefix */
+      *(p++) = '_';
+      p += svn__ui64tobase36(p, part->number);
+    }
+
+  *(p++) = '.';
+
+  return p;
+}
+
+
+
+/* Operations on ID parts */
+
+svn_boolean_t
+svn_fs_fs__id_part_is_root(const svn_fs_fs__id_part_t* part)
+{
+  return part->revision == 0 && part->number == 0;
+}
+
+svn_boolean_t
+svn_fs_fs__id_part_eq(const svn_fs_fs__id_part_t *lhs,
+                      const svn_fs_fs__id_part_t *rhs)
+{
+  return lhs->revision == rhs->revision && lhs->number == rhs->number;
+}
+
+
+
 /* Accessing ID Pieces.  */
 
-const char *
+const svn_fs_fs__id_part_t *
 svn_fs_fs__id_node_id(const svn_fs_id_t *fs_id)
 {
   fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
 
-  return id->node_id;
+  return &id->node_id;
 }
 
 
-const char *
+const svn_fs_fs__id_part_t *
 svn_fs_fs__id_copy_id(const svn_fs_id_t *fs_id)
 {
   fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
 
-  return id->copy_id;
+  return &id->copy_id;
 }
 
 
@@ -94,8 +178,13 @@ svn_string_t *
 svn_fs_fs__id_unparse(const svn_fs_id_t *fs_id,
                       apr_pool_t *pool)
 {
+  char string[4 * SVN_INT64_BUFFER_SIZE + 4];
   fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
 
+  char *p = unparse_id_part(string, &id->node_id);
+  p = unparse_id_part(p, &id->copy_id);
+  *p = '\0';
+
   if ((! id->txn_id))
     {
       char rev_string[SVN_INT64_BUFFER_SIZE];
@@ -103,15 +192,12 @@ svn_fs_fs__id_unparse(const svn_fs_id_t 
 
       svn__i64toa(rev_string, id->rev);
       svn__i64toa(offset_string, id->item);
-      return svn_string_createf(pool, "%s.%s.r%s/%s",
-                                id->node_id, id->copy_id,
+      return svn_string_createf(pool, "%sr%s/%s", string,
                                 rev_string, offset_string);
     }
   else
     {
-      return svn_string_createf(pool, "%s.%s.t%s",
-                                id->node_id, id->copy_id,
-                                id->txn_id);
+      return svn_string_createf(pool, "%st%s", string, id->txn_id);
     }
 }
 
@@ -127,10 +213,8 @@ svn_fs_fs__id_eq(const svn_fs_id_t *a,
 
   if (a == b)
     return TRUE;
-  if (strcmp(id_a->node_id, id_b->node_id) != 0)
+  if (memcmp(&id_a->node_id, &id_b->node_id, 2 * sizeof(id_a->node_id)) != 0)
      return FALSE;
-  if (strcmp(id_a->copy_id, id_b->copy_id) != 0)
-    return FALSE;
   if ((id_a->txn_id == NULL) != (id_b->txn_id == NULL))
     return FALSE;
   if (id_a->txn_id && id_b->txn_id && strcmp(id_a->txn_id, id_b->txn_id) != 0)
@@ -152,16 +236,17 @@ svn_fs_fs__id_check_related(const svn_fs
 
   if (a == b)
     return TRUE;
+
   /* If both node_ids start with _ and they have differing transaction
      IDs, then it is impossible for them to be related. */
-  if (id_a->node_id[0] == '_')
+  if (id_a->node_id.revision == SVN_INVALID_REVNUM)
     {
       if (id_a->txn_id && id_b->txn_id &&
           (strcmp(id_a->txn_id, id_b->txn_id) != 0))
         return FALSE;
     }
 
-  return (strcmp(id_a->node_id, id_b->node_id) == 0);
+  return svn_fs_fs__id_part_eq(&id_a->node_id, &id_b->node_id);
 }
 
 
@@ -191,8 +276,6 @@ svn_fs_fs__id_txn_create_root(const char
 
   /* node ID and copy ID are "0" */
   
-  id->node_id = "0";
-  id->copy_id = "0";
   id->txn_id = apr_pstrdup(pool, txn_id);
   id->rev = SVN_INVALID_REVNUM;
 
@@ -203,18 +286,17 @@ svn_fs_fs__id_txn_create_root(const char
 }
 
 svn_fs_id_t *
-svn_fs_fs__id_txn_create(const char *node_id,
-                         const char *copy_id,
+svn_fs_fs__id_txn_create(const svn_fs_fs__id_part_t *node_id,
+                         const svn_fs_fs__id_part_t *copy_id,
                          const char *txn_id,
                          apr_pool_t *pool)
 {
   fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
 
-  id->node_id = apr_pstrdup(pool, node_id);
-  id->copy_id = apr_pstrdup(pool, copy_id);
+  id->node_id = *node_id;
+  id->copy_id = *copy_id;
   id->txn_id = apr_pstrdup(pool, txn_id);
   id->rev = SVN_INVALID_REVNUM;
-  id->item = 0;
 
   id->generic_id.vtable = &id_vtable;
   id->generic_id.fsap_data = &id;
@@ -224,16 +306,16 @@ svn_fs_fs__id_txn_create(const char *nod
 
 
 svn_fs_id_t *
-svn_fs_fs__id_rev_create(const char *node_id,
-                         const char *copy_id,
+svn_fs_fs__id_rev_create(const svn_fs_fs__id_part_t *node_id,
+                         const svn_fs_fs__id_part_t *copy_id,
                          svn_revnum_t rev,
                          apr_uint64_t item,
                          apr_pool_t *pool)
 {
   fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
 
-  id->node_id = apr_pstrdup(pool, node_id);
-  id->copy_id = apr_pstrdup(pool, copy_id);
+  id->node_id = *node_id;
+  id->copy_id = *copy_id;
   id->txn_id = NULL;
   id->rev = rev;
   id->item = item;
@@ -251,14 +333,9 @@ svn_fs_fs__id_copy(const svn_fs_id_t *so
   fs_fs__id_t *id = (fs_fs__id_t *)source;
   fs_fs__id_t *new_id = apr_palloc(pool, sizeof(*new_id));
 
-  new_id->node_id = apr_pstrdup(pool, id->node_id);
-  new_id->copy_id = apr_pstrdup(pool, id->copy_id);
+  *new_id = *id;
   new_id->txn_id = id->txn_id ? apr_pstrdup(pool, id->txn_id) : NULL;
-  new_id->rev = id->rev;
-  new_id->item = id->item;
-
-  new_id->generic_id.vtable = &id_vtable;
-  new_id->generic_id.fsap_data = &new_id;
+  new_id->generic_id.fsap_data = new_id;
 
   return (svn_fs_id_t *)new_id;
 }
@@ -291,13 +368,15 @@ svn_fs_fs__id_parse(const char *data,
   str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
-  id->node_id = str;
+  if (! part_parse(&id->node_id, str))
+    return NULL;
 
   /* Copy Id */
   str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
-  id->copy_id = str;
+  if (! part_parse(&id->copy_id, str))
+    return NULL;
 
   /* Txn/Rev Id */
   str = svn_cstring_tokenize(".", &data_copy);
@@ -348,7 +427,7 @@ svn_fs_fs__id_parse(const char *data,
  */
 void
 svn_fs_fs__id_serialize(svn_temp_serializer__context_t *context,
-                        const struct svn_fs_id_t * const *in)
+                        const svn_fs_id_t * const *in)
 {
   const fs_fs__id_t *id = (const fs_fs__id_t *)*in;
   
@@ -362,8 +441,6 @@ svn_fs_fs__id_serialize(svn_temp_seriali
                             sizeof(fs_fs__id_t));
 
   /* append the referenced strings */
-  svn_temp_serializer__add_string(context, &id->node_id);
-  svn_temp_serializer__add_string(context, &id->copy_id);
   svn_temp_serializer__add_string(context, &id->txn_id);
 
   /* return to caller's nesting level */
@@ -393,8 +470,6 @@ svn_fs_fs__id_deserialize(void *buffer, 
   id->generic_id.fsap_data = id;
 
   /* handle sub-structures */
-  svn_temp_deserializer__resolve(id, (void**)&id->node_id);
-  svn_temp_deserializer__resolve(id, (void**)&id->copy_id);
   svn_temp_deserializer__resolve(id, (void**)&id->txn_id);
 }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/id.h Fri Mar  8 11:38:25 2013
@@ -29,14 +29,39 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* A rev node ID in FSFS consists of a 3 of sub-IDs ("parts") that consist
+ * of a creation REVISION number and some revision-local counter value
+ * (NUMBER).  Old-style ID parts use global counter values.
+ */
+typedef struct svn_fs_fs__id_part_t
+{
+  /* SVN_INVALID_REVNUM -> not assigned to a revision, yet
+     0                  -> old-style ID or the root in rev 0. */
+  svn_revnum_t revision;
+
+  /* some numerical value. */
+  apr_uint64_t number;
+} svn_fs_fs__id_part_t;
+
+
+/*** Operations on ID parts. ***/
+
+/* Return TRUE, if both elements of the PART is 0, i.e. this is the default
+ * value if e.g. no copies were made of this node. */
+svn_boolean_t svn_fs_fs__id_part_is_root(const svn_fs_fs__id_part_t *part);
+
+/* Return TRUE, if all element values of *LHS and *RHS match. */
+svn_boolean_t svn_fs_fs__id_part_eq(const svn_fs_fs__id_part_t *lhs,
+                                    const svn_fs_fs__id_part_t *rhs);
+
 
 /*** ID accessor functions. ***/
 
 /* Get the "node id" portion of ID. */
-const char *svn_fs_fs__id_node_id(const svn_fs_id_t *id);
+const svn_fs_fs__id_part_t *svn_fs_fs__id_node_id(const svn_fs_id_t *id);
 
 /* Get the "copy id" portion of ID. */
-const char *svn_fs_fs__id_copy_id(const svn_fs_id_t *id);
+const svn_fs_fs__id_part_t *svn_fs_fs__id_copy_id(const svn_fs_id_t *id);
 
 /* Get the "txn id" portion of ID, or NULL if it is a permanent ID. */
 const char *svn_fs_fs__id_txn_id(const svn_fs_id_t *id);
@@ -71,15 +96,15 @@ svn_fs_id_t *svn_fs_fs__id_txn_create_ro
 
 /* Create an ID within a transaction based on NODE_ID, COPY_ID, and
    TXN_ID, allocated in POOL. */
-svn_fs_id_t *svn_fs_fs__id_txn_create(const char *node_id,
-                                      const char *copy_id,
+svn_fs_id_t *svn_fs_fs__id_txn_create(const svn_fs_fs__id_part_t *node_id,
+                                      const svn_fs_fs__id_part_t *copy_id,
                                       const char *txn_id,
                                       apr_pool_t *pool);
 
 /* Create a permanent ID based on NODE_ID, COPY_ID, REV, and OFFSET,
    allocated in POOL. */
-svn_fs_id_t *svn_fs_fs__id_rev_create(const char *node_id,
-                                      const char *copy_id,
+svn_fs_id_t *svn_fs_fs__id_rev_create(const svn_fs_fs__id_part_t *node_id,
+                                      const svn_fs_fs__id_part_t *copy_id,
                                       svn_revnum_t rev,
                                       apr_uint64_t item,
                                       apr_pool_t *pool);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c Fri Mar  8 11:38:25 2013
@@ -135,21 +135,6 @@ read_handler_recover(void *baton, char *
   return svn_stream_read(b->stream, buffer, &bytes_to_read);
 }
 
-/* From the node or copy ID, extract the counter sub-string and return it
- * as integer.
- */
-static apr_uint64_t
-count_from_id(const char *id)
-{
-  if (id == NULL || *id == '\0')
-    return 0;
-
-  if (*id == '_')
-    return svn__base36toui64(NULL, id + 1);
-
-  return svn__base36toui64(NULL, id);
-}
-
 /* Part of the recovery procedure.  Read the directory noderev at offset
    OFFSET of file REV_FILE (the revision file of revision REV of
    filesystem FS), and set MAX_NODE_ID and MAX_COPY_ID to be the node-id
@@ -268,8 +253,8 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
           continue;
         }
 
-      node_id = count_from_id(svn_fs_fs__id_node_id(id));
-      copy_id = count_from_id(svn_fs_fs__id_copy_id(id));
+      node_id = svn_fs_fs__id_node_id(id)->number;
+      copy_id = svn_fs_fs__id_copy_id(id)->number;
 
       if (node_id > *max_node_id)
         *max_node_id = node_id;

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c Fri Mar  8 11:38:25 2013
@@ -960,7 +960,7 @@ create_new_txn_noderev_from_rev(svn_fs_t
                                 apr_pool_t *pool)
 {
   node_revision_t *noderev;
-  const char *node_id, *copy_id;
+  const svn_fs_fs__id_part_t *node_id, *copy_id;
 
   SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, src, pool));
 
@@ -1328,19 +1328,18 @@ 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(const char **node_id_p,
+get_new_txn_node_id(svn_fs_fs__id_part_t *node_id_p,
                     svn_fs_t *fs,
                     const char *txn_id,
                     apr_pool_t *pool)
 {
   apr_uint64_t node_id, copy_id;
-  char cur_node_id[SVN_INT64_BUFFER_SIZE];
 
   /* First read in the current next-ids file. */
   SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));
 
-  svn__ui64tobase36(cur_node_id, node_id);
-  *node_id_p = apr_pstrcat(pool, "_", cur_node_id, (char *)NULL);
+  node_id_p->revision = SVN_INVALID_REVNUM;
+  node_id_p->number = node_id;
 
   SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, pool));
 
@@ -1348,19 +1347,18 @@ get_new_txn_node_id(const char **node_id
 }
 
 svn_error_t *
-svn_fs_fs__reserve_copy_id(const char **copy_id_p,
+svn_fs_fs__reserve_copy_id(svn_fs_fs__id_part_t *copy_id_p,
                            svn_fs_t *fs,
                            const char *txn_id,
                            apr_pool_t *pool)
 {
   apr_uint64_t node_id, copy_id;
-  char cur_copy_id[SVN_INT64_BUFFER_SIZE];
 
   /* First read in the current next-ids file. */
   SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));
 
-  svn__ui64tobase36(cur_copy_id, copy_id);
-  *copy_id_p = apr_pstrcat(pool, "_", cur_copy_id, (char *)NULL);
+  copy_id_p->revision = SVN_INVALID_REVNUM;
+  copy_id_p->number = copy_id;
 
   SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, pool));
 
@@ -1371,17 +1369,17 @@ svn_error_t *
 svn_fs_fs__create_node(const svn_fs_id_t **id_p,
                        svn_fs_t *fs,
                        node_revision_t *noderev,
-                       const char *copy_id,
+                       const svn_fs_fs__id_part_t *copy_id,
                        const char *txn_id,
                        apr_pool_t *pool)
 {
-  const char *node_id;
+  svn_fs_fs__id_part_t node_id;
   const svn_fs_id_t *id;
 
   /* Get a new node-id for this node. */
   SVN_ERR(get_new_txn_node_id(&node_id, fs, txn_id, pool));
 
-  id = svn_fs_fs__id_txn_create(node_id, copy_id, txn_id, pool);
+  id = svn_fs_fs__id_txn_create(&node_id, copy_id, txn_id, pool);
 
   noderev->id = id;
 
@@ -1433,6 +1431,24 @@ svn_fs_fs__abort_txn(svn_fs_txn_t *txn,
   return SVN_NO_ERROR;
 }
 
+/* Assign the UNIQUIFIER member of REP based on the current state of TXN_ID
+ * in FS.  Allocate the uniquifier in POOL.
+ */
+static svn_error_t *
+set_uniquifier(svn_fs_t *fs,
+               representation_t *rep,
+               const char *txn_id,
+               apr_pool_t *pool)
+{
+  char unique_suffix[SVN_INT64_BUFFER_SIZE];
+  svn_fs_fs__id_part_t temp;
+
+  SVN_ERR(get_new_txn_node_id(&temp, fs, txn_id, pool));
+  svn__ui64tobase36(unique_suffix, temp.number);
+  rep->uniquifier = apr_psprintf(pool, "%s/_%s", txn_id, unique_suffix);
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_fs_fs__set_entry(svn_fs_t *fs,
@@ -1452,7 +1468,6 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
 
   if (!rep || !rep->txn_id)
     {
-      const char *unique_suffix;
       apr_hash_t *entries;
 
       /* Before we can modify the directory, we need to dump its old
@@ -1472,8 +1487,7 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
       rep = apr_pcalloc(pool, sizeof(*rep));
       rep->revision = SVN_INVALID_REVNUM;
       rep->txn_id = txn_id;
-      SVN_ERR(get_new_txn_node_id(&unique_suffix, fs, txn_id, pool));
-      rep->uniquifier = apr_psprintf(pool, "%s/%s", txn_id, unique_suffix);
+      SVN_ERR(set_uniquifier(fs, rep, txn_id, pool));
       parent_noderev->data_rep = rep;
       SVN_ERR(svn_fs_fs__put_node_revision(fs, parent_noderev->id,
                                            parent_noderev, FALSE, pool));
@@ -2050,7 +2064,6 @@ static svn_error_t *
 rep_write_contents_close(void *baton)
 {
   struct rep_write_baton *b = baton;
-  const char *unique_suffix;
   representation_t *rep;
   representation_t *old_rep;
   apr_off_t offset;
@@ -2069,9 +2082,7 @@ rep_write_contents_close(void *baton)
   /* Fill in the rest of the representation field. */
   rep->expanded_size = b->rep_size;
   rep->txn_id = svn_fs_fs__id_txn_id(b->noderev->id);
-  SVN_ERR(get_new_txn_node_id(&unique_suffix, b->fs, rep->txn_id, b->pool));
-  rep->uniquifier = apr_psprintf(b->parent_pool, "%s/%s", rep->txn_id,
-                                 unique_suffix);
+  SVN_ERR(set_uniquifier(b->fs, rep, rep->txn_id, b->pool));
   rep->revision = SVN_INVALID_REVNUM;
 
   /* Finalize the checksum. */
@@ -2174,7 +2185,7 @@ svn_fs_fs__create_successor(const svn_fs
                             svn_fs_t *fs,
                             const svn_fs_id_t *old_idp,
                             node_revision_t *new_noderev,
-                            const char *copy_id,
+                            const svn_fs_fs__id_part_t *copy_id,
                             const char *txn_id,
                             apr_pool_t *pool)
 {
@@ -2566,28 +2577,28 @@ validate_root_noderev(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
-/* Given the potentially txn-local ID, return the permanent ID based on
- * the REVISION currently written and the START_ID for that revision.
- * Use the repository FORMAT to decide which implementation to use.
- * Use POOL for allocations.
+/* Given the potentially txn-local id PART, update that to a permanent ID
+ * based on the REVISION currently being written and the START_ID for that
+ * revision.  Use the repo FORMAT to decide which implementation to use.
  */
-static const char*
-get_final_id(const char *id,
+static void
+get_final_id(svn_fs_fs__id_part_t *part,
              svn_revnum_t revision,
              apr_uint64_t start_id,
-             int format,
-             apr_pool_t *pool)
+             int format)
 {
-  char buffer[SVN_INT64_BUFFER_SIZE];
-  apr_uint64_t global_id;
-  if (*id != '_')
-    return id;
-
-  if (format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
-    return apr_psprintf(pool, "%s-%ld", id + 1, revision);
-
-  global_id = start_id + svn__base36toui64(NULL, id + 1);
-  return apr_pstrmemdup(pool, buffer, svn__ui64tobase36(buffer, global_id));
+  if (part->revision == SVN_INVALID_REVNUM)
+    {
+      if (format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
+        {
+          part->revision = revision;
+        }
+      else
+        {
+          part->revision = 0;
+          part->number += start_id;
+        }
+    }
 }
 
 /* Copy a node-revision specified by id ID in fileystem FS from a
@@ -2634,7 +2645,7 @@ 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;
-  const char *node_id, *copy_id;
+  svn_fs_fs__id_part_t node_id, copy_id;
   fs_fs_data_t *ffd = fs->fsap_data;
   apr_uint64_t item_index;
   const char *txn_id = svn_fs_fs__id_txn_id(id);
@@ -2744,10 +2755,10 @@ write_final_rev(const svn_fs_id_t **new_
     }
 
   /* Convert our temporary ID into a permanent revision one. */
-  node_id = get_final_id(svn_fs_fs__id_node_id(noderev->id),
-                         rev, start_node_id, ffd->format, pool);
-  copy_id = get_final_id(svn_fs_fs__id_copy_id(noderev->id),
-                         rev, start_copy_id, ffd->format, pool);
+  node_id = *svn_fs_fs__id_node_id(noderev->id);
+  get_final_id(&node_id, rev, start_node_id, ffd->format);
+  copy_id = *svn_fs_fs__id_copy_id(noderev->id);
+  get_final_id(&copy_id, rev, start_copy_id, ffd->format);
 
   if (noderev->copyroot_rev == SVN_INVALID_REVNUM)
     noderev->copyroot_rev = rev;
@@ -2761,7 +2772,8 @@ write_final_rev(const svn_fs_id_t **new_
     }
   else
     SVN_ERR(allocate_item_index(&item_index, fs, txn_id, my_offset, pool));
-  new_id = svn_fs_fs__id_rev_create(node_id, copy_id, rev, item_index, pool);
+  new_id = svn_fs_fs__id_rev_create(&node_id, &copy_id, rev, item_index,
+                                    pool);
 
   noderev->id = new_id;
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.h?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.h Fri Mar  8 11:38:25 2013
@@ -100,7 +100,7 @@ svn_fs_fs__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_fs__reserve_copy_id(const char **copy_id_p,
+svn_fs_fs__reserve_copy_id(svn_fs_fs__id_part_t *copy_id_p,
                            svn_fs_t *fs,
                            const char *txn_id,
                            apr_pool_t *pool);
@@ -114,7 +114,7 @@ svn_error_t *
 svn_fs_fs__create_node(const svn_fs_id_t **id_p,
                        svn_fs_t *fs,
                        node_revision_t *noderev,
-                       const char *copy_id,
+                       const svn_fs_fs__id_part_t *copy_id,
                        const char *txn_id,
                        apr_pool_t *pool);
 
@@ -192,7 +192,7 @@ svn_fs_fs__create_successor(const svn_fs
                             svn_fs_t *fs,
                             const svn_fs_id_t *old_idp,
                             node_revision_t *new_noderev,
-                            const char *copy_id,
+                            const svn_fs_fs__id_part_t *copy_id,
                             const char *txn_id,
                             apr_pool_t *pool);
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c Fri Mar  8 11:38:25 2013
@@ -752,7 +752,7 @@ get_copy_inheritance(copy_id_inherit_t *
                      apr_pool_t *pool)
 {
   const svn_fs_id_t *child_id, *parent_id, *copyroot_id;
-  const char *child_copy_id, *parent_copy_id;
+  const svn_fs_fs__id_part_t *child_copy_id, *parent_copy_id;
   const char *id_path = NULL;
   svn_fs_root_t *copyroot_root;
   dag_node_t *copyroot_node;
@@ -782,14 +782,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 (strcmp(child_copy_id, "0") == 0)
+  if (svn_fs_fs__id_part_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 (strcmp(child_copy_id, parent_copy_id) == 0)
+  if (svn_fs_fs__id_part_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
@@ -1075,7 +1075,8 @@ make_path_mutable(svn_fs_root_t *root,
   if (parent_path->parent)
     {
       const svn_fs_id_t *parent_id, *child_id, *copyroot_id;
-      const char *copy_id = NULL;
+      svn_fs_fs__id_part_t copy_id = { SVN_INVALID_REVNUM, 0 };
+      svn_fs_fs__id_part_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;
@@ -1092,7 +1093,7 @@ make_path_mutable(svn_fs_root_t *root,
         {
         case copy_id_inherit_parent:
           parent_id = svn_fs_fs__dag_get_id(parent_path->parent->node);
-          copy_id = svn_fs_fs__id_copy_id(parent_id);
+          copy_id = *svn_fs_fs__id_copy_id(parent_id);
           break;
 
         case copy_id_inherit_new:
@@ -1101,7 +1102,7 @@ make_path_mutable(svn_fs_root_t *root,
           break;
 
         case copy_id_inherit_self:
-          copy_id = NULL;
+          copy_id_ptr = NULL;
           break;
 
         case copy_id_inherit_unknown:
@@ -1120,8 +1121,8 @@ make_path_mutable(svn_fs_root_t *root,
 
       child_id = svn_fs_fs__dag_get_id(parent_path->node);
       copyroot_id = svn_fs_fs__dag_get_id(copyroot_node);
-      if (strcmp(svn_fs_fs__id_node_id(child_id),
-                 svn_fs_fs__id_node_id(copyroot_id)) != 0)
+      if (!svn_fs_fs__id_part_eq(svn_fs_fs__id_node_id(child_id),
+                                 svn_fs_fs__id_node_id(copyroot_id)))
         is_parent_copyroot = TRUE;
 
       /* Now make this node mutable.  */
@@ -1130,7 +1131,7 @@ make_path_mutable(svn_fs_root_t *root,
                                          parent_path->parent->node,
                                          clone_path,
                                          parent_path->entry,
-                                         copy_id, txn_id,
+                                         copy_id_ptr, txn_id,
                                          is_parent_copyroot,
                                          pool));
 
@@ -1808,14 +1809,14 @@ merge(svn_stringbuf_t *conflict_p,
 
           /* If either SOURCE-ENTRY or TARGET-ENTRY is not a direct
              modification of ANCESTOR-ENTRY, declare a conflict. */
-          if (strcmp(svn_fs_fs__id_node_id(s_entry->id),
-                     svn_fs_fs__id_node_id(a_entry->id)) != 0
-              || strcmp(svn_fs_fs__id_copy_id(s_entry->id),
-                        svn_fs_fs__id_copy_id(a_entry->id)) != 0
-              || strcmp(svn_fs_fs__id_node_id(t_entry->id),
-                        svn_fs_fs__id_node_id(a_entry->id)) != 0
-              || strcmp(svn_fs_fs__id_copy_id(t_entry->id),
-                        svn_fs_fs__id_copy_id(a_entry->id)) != 0)
+          if (!svn_fs_fs__id_part_eq(svn_fs_fs__id_node_id(s_entry->id),
+                                     svn_fs_fs__id_node_id(a_entry->id))
+              || !svn_fs_fs__id_part_eq(svn_fs_fs__id_copy_id(s_entry->id),
+                                        svn_fs_fs__id_copy_id(a_entry->id))
+              || !svn_fs_fs__id_part_eq(svn_fs_fs__id_node_id(t_entry->id),
+                                        svn_fs_fs__id_node_id(a_entry->id))
+              || !svn_fs_fs__id_part_eq(svn_fs_fs__id_copy_id(t_entry->id),
+                                        svn_fs_fs__id_copy_id(a_entry->id)))
             return conflict_err(conflict_p,
                                 svn_fspath__join(target_path,
                                                  a_entry->name,
@@ -3329,7 +3330,7 @@ fs_node_origin_rev(svn_revnum_t *revisio
 {
   svn_fs_t *fs = root->fs;
   const svn_fs_id_t *given_noderev_id, *cached_origin_id;
-  const char *node_id, *dash;
+  const svn_fs_fs__id_part_t *node_id;
 
   path = svn_fs__canonicalize_abspath(path, pool);
 
@@ -3337,19 +3338,12 @@ fs_node_origin_rev(svn_revnum_t *revisio
   SVN_ERR(svn_fs_fs__node_id(&given_noderev_id, root, path, pool));
   node_id = svn_fs_fs__id_node_id(given_noderev_id);
 
-  /* Is it a brand new uncommitted node? */
-  if (node_id[0] == '_')
+  /* Is it a brand new uncommitted node or a new-style one?
+   * (committed old-style nodes will have a 0 revision value;
+   * rev 0, number 0 is rev 0 root node) */
+  if (node_id->revision != 0 || node_id->number == 0)
     {
-      *revision = SVN_INVALID_REVNUM;
-      return SVN_NO_ERROR;
-    }
-
-  /* Maybe this is a new-style node ID that just has the revision
-     sitting right in it. */
-  dash = strchr(node_id, '-');
-  if (dash && *(dash+1))
-    {
-      *revision = SVN_STR_TO_REV(dash + 1);
+      *revision = node_id->revision;
       return SVN_NO_ERROR;
     }
 
@@ -3429,7 +3423,7 @@ fs_node_origin_rev(svn_revnum_t *revisio
 
     /* Wow, I don't want to have to do all that again.  Let's cache
        the result. */
-    if (node_id[0] != '_')
+    if (node_id->revision != SVN_INVALID_REVNUM)
       SVN_ERR(svn_fs_fs__set_node_origin(fs, node_id,
                                          svn_fs_fs__dag_get_id(node), pool));
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.c?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.c Fri Mar  8 11:38:25 2013
@@ -334,13 +334,13 @@ path_txn_proto_rev_lock(svn_fs_t *fs, co
 const char *
 path_txn_node_rev(svn_fs_t *fs, const svn_fs_id_t *id, apr_pool_t *pool)
 {
-  const char *txn_id = svn_fs_fs__id_txn_id(id);
-  const char *node_id = svn_fs_fs__id_node_id(id);
-  const char *copy_id = svn_fs_fs__id_copy_id(id);
-  const char *name = apr_psprintf(pool, PATH_PREFIX_NODE "%s.%s",
-                                  node_id, copy_id);
+  char *filename = (char *)svn_fs_fs__id_unparse(id, pool)->data;
+  *strrchr(filename, '.') = '\0';
 
-  return svn_dirent_join(path_txn_dir(fs, txn_id, pool), name, pool);
+  return svn_dirent_join(path_txn_dir(fs, svn_fs_fs__id_txn_id(id), pool),
+                         apr_psprintf(pool, PATH_PREFIX_NODE "%s",
+                                      filename),
+                         pool);
 }
 
 const char *
@@ -358,13 +358,18 @@ path_txn_node_children(svn_fs_t *fs, con
 }
 
 const char *
-path_node_origin(svn_fs_t *fs, const char *node_id, apr_pool_t *pool)
+path_node_origin(svn_fs_t *fs,
+                 const svn_fs_fs__id_part_t *node_id,
+                 apr_pool_t *pool)
 {
-  size_t len = strlen(node_id);
-  const char *node_id_minus_last_char =
-    (len == 1) ? "0" : apr_pstrmemdup(pool, node_id, len - 1);
+  char buffer[SVN_INT64_BUFFER_SIZE];
+  apr_size_t len = svn__ui64tobase36(buffer, node_id->number);
+
+  if (len > 1)
+    buffer[len - 1] = '\0';
+
   return svn_dirent_join_many(pool, fs->path, PATH_NODE_ORIGINS_DIR,
-                              node_id_minus_last_char, NULL);
+                              buffer, NULL);
 }
 
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.h?rev=1454329&r1=1454328&r2=1454329&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/util.h Fri Mar  8 11:38:25 2013
@@ -24,6 +24,7 @@
 #define SVN_LIBSVN_FS__UTIL_H
 
 #include "svn_fs.h"
+#include "id.h"
 
 /* Functions for dealing with recoverable errors on mutable files
  *
@@ -218,7 +219,7 @@ path_txn_node_children(svn_fs_t *fs,
 
 const char *
 path_node_origin(svn_fs_t *fs,
-                 const char *node_id,
+                 const svn_fs_fs__id_part_t *node_id,
                  apr_pool_t *pool);
 
 /* Check that BUF, a nul-terminated buffer of text from file PATH,