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 2014/01/28 12:18:26 UTC

svn commit: r1562037 - /subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c

Author: brane
Date: Tue Jan 28 11:18:26 2014
New Revision: 1562037

URL: http://svn.apache.org/r1562037
Log:
On the fsfs-ucsnorm branch: Temporarily revert changes in lookup processing.

* subversion/libsvn_fs_fs/tree.c: Revert to trunk version.

Modified:
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c?rev=1562037&r1=1562036&r2=1562037&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c Tue Jan 28 11:18:26 2014
@@ -67,7 +67,6 @@
 #include "private/svn_subr_private.h"
 #include "private/svn_fs_util.h"
 #include "private/svn_fspath.h"
-#include "private/svn_utf_private.h"
 #include "../libsvn_fs/fs-loader.h"
 
 
@@ -462,9 +461,7 @@ locate_cache(svn_cache__t **cache,
 
    Since locking can be expensive and POOL may be long-living, for
    nodes that will not need to survive the next call to this function,
-   set NEEDS_LOCK_CACHE to FALSE.
-
-   If normalized lookup is enabled, PATH *must* be normalized. */
+   set NEEDS_LOCK_CACHE to FALSE. */
 static svn_error_t *
 dag_node_cache_get(dag_node_t **node_p,
                    svn_fs_root_t *root,
@@ -532,9 +529,7 @@ dag_node_cache_get(dag_node_t **node_p,
 }
 
 
-/* Add the NODE for PATH to ROOT's node cache.
-
-   If normalized lookup is enabled, PATH *must* be normalized. */
+/* Add the NODE for PATH to ROOT's node cache. */
 static svn_error_t *
 dag_node_cache_set(svn_fs_root_t *root,
                    const char *path,
@@ -734,57 +729,6 @@ typedef enum copy_id_inherit_t
 
 } copy_id_inherit_t;
 
-/* Structure used to propagate paths throught the FSFS implementation. */
-typedef struct path_lookup_t
-{
-  /* The original path, as found on disk or received by the API. */
-  const char *path;
-
-  /* The representation of PATH used for cache keys and
-     lookups. Depending on whether normalized lookups are enabled,
-     this will either be exactly the same pointer as PATH (i.e.,
-     normalization is disabled), or it will be a normalized
-     representation of PATH (which may turn out to be exactly the same
-     as PATH). The invariant is:
-
-         (normalized_lookup == false) ==> (path == key)
-
-     Note that when normalized lookup is enabled and PATH is already
-     normalized, KEY will still be the same as PATH, in order to make
-     lookups slightly faster.
-  */
-  const char *key;
-} path_lookup_t;
-
-
-/* Initialize *LOOKUP as a key for path lookup.
-   LOOKUP->path will always be canonical. */
-static svn_error_t *
-create_path_lookup(path_lookup_t *lookup,
-                   const char *path,
-                   svn_fs_root_t *root,
-                   apr_pool_t *result_pool)
-{
-  const svn_boolean_t normalized_lookup =
-    ((fs_fs_data_t*)root->fs->fsap_data)->normalized_lookup;
-
-  lookup->path = svn_fs__canonicalize_abspath(path, result_pool);
-  if (normalized_lookup)
-    {
-      svn_membuf_t buffer;
-      svn_membuf__create(&buffer, 0, result_pool);
-      SVN_ERR(svn_utf__normalize(&lookup->key, lookup->path,
-                                 SVN_UTF__UNKNOWN_LENGTH, &buffer));
-      if (0 == strcmp(lookup->key, lookup->path))
-        lookup->key = lookup->path;
-    }
-  else
-    {
-      lookup->key = lookup->path;
-    }
-  return SVN_NO_ERROR;
-}
-
 /* A linked list representing the path from a node up to a root
    directory.  We use this for cloning, and for operations that need
    to deal with both a node and its parent directory.  For example, a
@@ -802,10 +746,6 @@ typedef struct parent_path_t
      root directory, which (obviously) has no name in its parent.  */
   char *entry;
 
-  /* The normalized form of ENTRY. The same invariant obtains as for
-     path_lookup_t::key. */
-  char *entry_key;
-
   /* The parent of NODE, or zero if NODE is the root directory.  */
   struct parent_path_t *parent;
 
@@ -832,7 +772,8 @@ parent_path_path(parent_path_t *parent_p
     : path_so_far;
 }
 
-/* return the FS path for the parent path chain object CHILD relative
+
+/* Return the FS path for the parent path chain object CHILD relative
    to its ANCESTOR in the same chain, allocated in POOL.  */
 static const char *
 parent_path_relpath(parent_path_t *child,
@@ -940,18 +881,16 @@ get_copy_inheritance(copy_id_inherit_t *
 }
 
 /* Allocate a new parent_path_t node from POOL, referring to NODE,
-   ENTRY, ENTRY_KEY, PARENT, and COPY_ID.  */
+   ENTRY, PARENT, and COPY_ID.  */
 static parent_path_t *
 make_parent_path(dag_node_t *node,
                  char *entry,
-                 char *entry_key,
                  parent_path_t *parent,
                  apr_pool_t *pool)
 {
   parent_path_t *parent_path = apr_pcalloc(pool, sizeof(*parent_path));
   parent_path->node = node;
   parent_path->entry = entry;
-  parent_path->entry_key = entry_key;
   parent_path->parent = parent;
   parent_path->copy_inherit = copy_id_inherit_unknown;
   parent_path->copy_src_path = NULL;
@@ -979,7 +918,7 @@ typedef enum open_path_flags_t {
 } open_path_flags_t;
 
 
-/* Open the node identified by LOOKUP in ROOT, allocating in POOL.  Set
+/* Open the node identified by PATH in ROOT, allocating in POOL.  Set
    *PARENT_PATH_P to a path from the node up to ROOT.  The resulting
    **PARENT_PATH_P value is guaranteed to contain at least one
    *element, for the root directory.  PATH must be in canonical form.
@@ -990,7 +929,7 @@ typedef enum open_path_flags_t {
    inheritance information will be calculated for the *PARENT_PATH_P chain.
 
    If FLAGS & open_path_last_optional is zero, return the error
-   SVN_ERR_FS_NOT_FOUND if the node LOOKUP refers to does not exist.  If
+   SVN_ERR_FS_NOT_FOUND if the node PATH refers to does not exist.  If
    non-zero, require all the parent directories to exist as normal,
    but if the final path component doesn't exist, simply return a path
    whose bottom `node' member is zero.  This option is useful for
@@ -1009,39 +948,32 @@ typedef enum open_path_flags_t {
 static svn_error_t *
 open_path(parent_path_t **parent_path_p,
           svn_fs_root_t *root,
-          const path_lookup_t *lookup,
+          const char *path,
           int flags,
           svn_boolean_t is_txn_path,
           apr_pool_t *pool)
 {
-  const svn_boolean_t denormalized = (lookup->path != lookup->key);
   svn_fs_t *fs = root->fs;
   dag_node_t *here = NULL; /* The directory we're currently looking at.  */
   parent_path_t *parent_path; /* The path from HERE up to the root. */
-  const char *rest_path;      /* The portion of LOOKUP->path we
-                                 haven't traversed yet. */
-  const char *rest_key;       /* The portion of LOOKUP->key we haven't
-                                 traversed yet. */
+  const char *rest; /* The portion of PATH we haven't traversed yet.  */
   apr_pool_t *iterpool = svn_pool_create(pool);
 
-  /* path to the currently processed entry without trailing '/'.  We
-     will reuse this across iterations by simply putting a NUL
-     terminator at the respective position and replacing that with a
-     '/' in the next iteration.  This is correct as we assert()
-     LOOKUP->key to be canonical. */
-  svn_stringbuf_t *key_so_far = svn_stringbuf_create(lookup->key, pool);
-
-  /* callers often traverse the tree in some path-based order.  That
-     means a sibling of LOOKUP->key has been presently accessed.  Try
-     to start the lookup directly at the parent node, if the caller
-     did not requested the full parent chain. */
-  assert(svn_fs__is_canonical_abspath(lookup->key));
-  assert(lookup->path != lookup->key
-         && svn_fs__is_canonical_abspath(lookup->path));
-  key_so_far->len = 0; /* "" */
+  /* path to the currently processed entry without trailing '/'.
+     We will reuse this across iterations by simply putting a NUL terminator
+     at the respective position and replacing that with a '/' in the next
+     iteration.  This is correct as we assert() PATH to be canonical. */
+  svn_stringbuf_t *path_so_far = svn_stringbuf_create(path, pool);
+
+  /* callers often traverse the tree in some path-based order.  That means
+     a sibling of PATH has been presently accessed.  Try to start the lookup
+     directly at the parent node, if the caller did not requested the full
+     parent chain. */
+  assert(svn_fs__is_canonical_abspath(path));
+  path_so_far->len = 0; /* "" */
   if (flags & open_path_node_only)
     {
-      const char *directory = svn_dirent_dirname(lookup->key, pool);
+      const char *directory = svn_dirent_dirname(path, pool);
       if (directory[1] != 0) /* root nodes are covered anyway */
         {
           SVN_ERR(dag_node_cache_get(&here, root, directory, TRUE, pool));
@@ -1049,17 +981,8 @@ open_path(parent_path_t **parent_path_p,
           if (here)
             {
               apr_size_t dirname_len = strlen(directory);
-              key_so_far->len = dirname_len;
-              rest_key = lookup->key + dirname_len + 1;
-
-              /* Adjust the rest_path */
-              if (!denormalized)
-                rest_path = rest_key;
-              else
-                {
-                  const char *part = svn_dirent_dirname(lookup->path, pool);
-                  rest_path = lookup->path + strlen(part) + 1;
-                }
+              path_so_far->len = dirname_len;
+              rest = path + dirname_len + 1;
             }
         }
     }
@@ -1070,13 +993,11 @@ open_path(parent_path_t **parent_path_p,
       /* Make a parent_path item for the root node, using its own current
          copy id.  */
       SVN_ERR(root_node(&here, root, pool));
-      /* Skip the leading '/', saving an iteration. */
-      rest_key = lookup->key + 1;
-      rest_path = lookup->path + 1;
+      rest = path + 1; /* skip the leading '/', it saves in iteration */
     }
 
-  key_so_far->data[key_so_far->len] = '\0';
-  parent_path = make_parent_path(here, NULL, NULL, NULL, pool);
+  path_so_far->data[path_so_far->len] = '\0';
+  parent_path = make_parent_path(here, 0, 0, pool);
   parent_path->copy_inherit = copy_id_inherit_self;
 
   /* Whenever we are at the top of this loop:
@@ -1086,27 +1007,21 @@ open_path(parent_path_t **parent_path_p,
      - PARENT_PATH includes HERE and all its parents.  */
   for (;;)
     {
-      const char *next_key;
-      const char *next_path;
-      char *entry_key;
-      char *entry_path;
+      const char *next;
+      char *entry;
       dag_node_t *child;
 
       svn_pool_clear(iterpool);
 
       /* Parse out the next entry from the path.  */
-      entry_key = svn_fs__next_entry_name(&next_key, rest_key, pool);
-      if (!denormalized)
-        entry_path = entry_key;
-      else
-        entry_path = svn_fs__next_entry_name(&next_path, rest_path, pool);
+      entry = svn_fs__next_entry_name(&next, rest, pool);
 
       /* Update the path traversed thus far. */
-      key_so_far->data[key_so_far->len] = '/';
-      key_so_far->len += strlen(entry_key) + 1;
-      key_so_far->data[key_so_far->len] = '\0';
+      path_so_far->data[path_so_far->len] = '/';
+      path_so_far->len += strlen(entry) + 1;
+      path_so_far->data[path_so_far->len] = '\0';
 
-      if (*entry_key == '\0')
+      if (*entry == '\0')
         {
           /* Given the behavior of svn_fs__next_entry_name(), this
              happens when the path either starts or ends with a slash.
@@ -1126,12 +1041,12 @@ open_path(parent_path_t **parent_path_p,
              layer.  Don't bother to contact the cache for the last
              element if we already know the lookup to fail for the
              complete path. */
-          if (next_key || !(flags & open_path_uncached))
-            SVN_ERR(dag_node_cache_get(&cached_node, root, key_so_far->data,
+          if (next || !(flags & open_path_uncached))
+            SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far->data,
                                        TRUE, pool));
           if (cached_node)
             child = cached_node;
-          else /**TODOXXX**/
+          else
             err = svn_fs_fs__dag_open(&child, here, entry, pool, iterpool);
 
           /* "file not found" requires special handling.  */
@@ -1144,17 +1059,17 @@ open_path(parent_path_t **parent_path_p,
               svn_error_clear(err);
 
               if ((flags & open_path_last_optional)
-                  && (! next_key || *next_key == '\0'))
+                  && (! next || *next == '\0'))
                 {
-                  parent_path = make_parent_path(NULL, entry_path, entry_key,
-                                                 parent_path, pool);
+                  parent_path = make_parent_path(NULL, entry, parent_path,
+                                                 pool);
                   break;
                 }
               else
                 {
                   /* Build a better error message than svn_fs_fs__dag_open
                      can provide, giving the root and full path name.  */
-                  return SVN_FS__NOT_FOUND(root, lookup->path);
+                  return SVN_FS__NOT_FOUND(root, path);
                 }
             }
 
@@ -1169,8 +1084,7 @@ open_path(parent_path_t **parent_path_p,
           else
             {
               /* Now, make a parent_path item for CHILD. */
-              parent_path = make_parent_path(child, entry_path, entry_key,
-                                             parent_path, pool);
+              parent_path = make_parent_path(child, entry, parent_path, pool);
               if (is_txn_path)
                 {
                   SVN_ERR(get_copy_inheritance(&inherit, &copy_path, fs,
@@ -1182,22 +1096,20 @@ open_path(parent_path_t **parent_path_p,
 
           /* Cache the node we found (if it wasn't already cached). */
           if (! cached_node)
-            SVN_ERR(dag_node_cache_set(root, key_so_far->data, child,
+            SVN_ERR(dag_node_cache_set(root, path_so_far->data, child,
                                        iterpool));
         }
 
       /* Are we finished traversing the path?  */
-      if (! next_key)
+      if (! next)
         break;
 
       /* The path isn't finished yet; we'd better be in a directory.  */
       if (svn_fs_fs__dag_node_kind(child) != svn_node_dir)
-        SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, key_so_far->data),
-                  apr_psprintf(iterpool, _("Failure opening '%s'"),
-                               lookup->path));
+        SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data),
+                  apr_psprintf(iterpool, _("Failure opening '%s'"), path));
 
-      rest_path = next_path;
-      rest_key = next_key;
+      rest = next;
       here = child;
     }
 
@@ -1313,7 +1225,7 @@ make_path_mutable(svn_fs_root_t *root,
    Since locking can be expensive and POOL may be long-living, for
    nodes that will not need to survive the next call to this function,
    set NEEDS_LOCK_CACHE to FALSE. */
-static svn_error_t * /**TODOXXX**/
+static svn_error_t *
 get_dag(dag_node_t **dag_node_p,
         svn_fs_root_t *root,
         const char *path,
@@ -1631,7 +1543,6 @@ fs_change_node_prop(svn_fs_root_t *root,
 {
   parent_path_t *parent_path;
   apr_hash_t *proplist;
-  path_lookup_t lookup;
   const svn_fs_fs__id_part_t *txn_id;
   svn_boolean_t modeinfo_mod = FALSE;
 
@@ -1639,8 +1550,8 @@ fs_change_node_prop(svn_fs_root_t *root,
     return SVN_FS__NOT_TXN(root);
   txn_id = root_txn_id(root);
 
-  SVN_ERR(create_path_lookup(&lookup, path, root, pool));
-  SVN_ERR(open_path(&parent_path, root, &lookup, 0, TRUE, pool));
+  path = svn_fs__canonicalize_abspath(path, pool);
+  SVN_ERR(open_path(&parent_path, root, path, 0, TRUE, pool));
 
   /* Check (non-recursively) to see if path is locked; if so, check
      that we can use it. */
@@ -2499,13 +2410,12 @@ fs_make_dir(svn_fs_root_t *root,
 {
   parent_path_t *parent_path;
   dag_node_t *sub_dir;
-  path_lookup_t lookup;
   const svn_fs_fs__id_part_t *txn_id = root_txn_id(root);
 
   SVN_ERR(check_newline(path, pool));
 
-  SVN_ERR(create_path_lookup(&lookup, path, root, pool));
-  SVN_ERR(open_path(&parent_path, root, &lookup, open_path_last_optional,
+  path = svn_fs__canonicalize_abspath(path, pool);
+  SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional,
                     TRUE, pool));
 
   /* Check (recursively) to see if some lock is 'reserving' a path at
@@ -2549,7 +2459,6 @@ fs_delete_node(svn_fs_root_t *root,
                apr_pool_t *pool)
 {
   parent_path_t *parent_path;
-  path_lookup_t lookup;
   const svn_fs_fs__id_part_t *txn_id;
   apr_int64_t mergeinfo_count = 0;
   svn_node_kind_t kind;
@@ -2558,7 +2467,7 @@ fs_delete_node(svn_fs_root_t *root,
     return SVN_FS__NOT_TXN(root);
 
   txn_id = root_txn_id(root);
-  SVN_ERR(create_path_lookup(&lookup, path, root, pool));
+  path = svn_fs__canonicalize_abspath(path, pool);
   SVN_ERR(open_path(&parent_path, root, path, 0, TRUE, pool));
   kind = svn_fs_fs__dag_node_kind(parent_path->node);
 
@@ -2697,7 +2606,7 @@ copy_helper(svn_fs_root_t *from_root,
             const char *to_path,
             copy_type_t copy_type,
             apr_pool_t *pool)
-{ /**TODOXXX**/
+{
   dag_node_t *from_node;
   parent_path_t *to_parent_path;
   const svn_fs_fs__id_part_t *txn_id = root_txn_id(to_root);
@@ -2964,14 +2873,13 @@ fs_make_file(svn_fs_root_t *root,
              apr_pool_t *pool)
 {
   parent_path_t *parent_path;
-  path_lookup_t lookup;
   dag_node_t *child;
   const svn_fs_fs__id_part_t *txn_id = root_txn_id(root);
 
   SVN_ERR(check_newline(path, pool));
 
-  SVN_ERR(create_path_lookup(&lookup, path, root, pool));
-  SVN_ERR(open_path(&parent_path, root, &lookup, open_path_last_optional,
+  path = svn_fs__canonicalize_abspath(path, pool);
+  SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional,
                     TRUE, pool));
 
   /* If there's already a file by that name, complain.
@@ -3199,7 +3107,7 @@ window_consumer(svn_txdelta_window_t *wi
    txdelta_baton_t. */
 static svn_error_t *
 apply_textdelta(void *baton, apr_pool_t *pool)
-{ /**TODOXXX**/
+{
   txdelta_baton_t *tb = (txdelta_baton_t *) baton;
   parent_path_t *parent_path;
   const svn_fs_fs__id_part_t *txn_id = root_txn_id(tb->root);
@@ -3364,7 +3272,7 @@ text_stream_closer(void *baton)
    text_baton_t. */
 static svn_error_t *
 apply_text(void *baton, apr_pool_t *pool)
-{/**TODOXXX**/
+{
   struct text_baton_t *tb = baton;
   parent_path_t *parent_path;
   const svn_fs_fs__id_part_t *txn_id = root_txn_id(tb->root);
@@ -3617,10 +3525,9 @@ static svn_error_t *fs_closest_copy(svn_
                                     svn_fs_root_t *root,
                                     const char *path,
                                     apr_pool_t *pool)
-{/**TODOXXX**/
+{
   svn_fs_t *fs = root->fs;
   parent_path_t *parent_path, *copy_dst_parent_path;
-  path_lookup_t lookup, dst_lookup;
   svn_revnum_t copy_dst_rev, created_rev;
   const char *copy_dst_path;
   svn_fs_root_t *copy_dst_root;
@@ -3631,8 +3538,8 @@ static svn_error_t *fs_closest_copy(svn_
   *root_p = NULL;
   *path_p = NULL;
 
-  SVN_ERR(create_path_lookup(&lookup, path, root, pool));
-  SVN_ERR(open_path(&parent_path, root, &lookup, 0, FALSE, pool));
+  path = svn_fs__canonicalize_abspath(path, pool);
+  SVN_ERR(open_path(&parent_path, root, path, 0, FALSE, pool));
 
   /* Find the youngest copyroot in the path of this node-rev, which
      will indicate the target of the innermost copy affecting the