Author: stefan2
Date: Sat Feb 21 13:02:27 2015
New Revision: 1661352

URL: http://svn.apache.org/r1661352
Log:
On the fsx-1.10 branch:  Switch the second path walker function to the
new path handling and lookup utlitities.

* subversion/libsvn_fs_x/dag_cache.c
  (make_parent_path): Provide the ENTRY name as a more efficiently copyable
                      object and copy it as well.  Now we return a deep
                      copy of everything.
  (svn_fs_x__get_dag_path): Reimplement.  Model it after walk_dag_path().

Modified:
    subversion/branches/fsx-1.10/subversion/libsvn_fs_x/dag_cache.c

Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs_x/dag_cache.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs_x/dag_cache.c?rev=1661352&r1=1661351&r2=1661352&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs_x/dag_cache.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs_x/dag_cache.c Sat Feb 21 
13:02:27 2015
@@ -878,11 +878,11 @@ get_copy_inheritance(svn_fs_x__copy_id_i
   return SVN_NO_ERROR;
 }
 
-/* Allocate a new svn_fs_x__dag_path_t node from RESULT_POOL, referring to
-   NODE, ENTRY, PARENT, and COPY_ID.  */
+/* Allocate a new svn_fs_x__dag_path_t node from RESULT_POOL, containing
+   NODE, ENTRY and PARENT, all copied into RESULT_POOL as well.  */
 static svn_fs_x__dag_path_t *
 make_parent_path(dag_node_t *node,
-                 char *entry,
+                 const svn_stringbuf_t *entry,
                  svn_fs_x__dag_path_t *parent,
                  apr_pool_t *result_pool)
 {
@@ -890,7 +890,7 @@ make_parent_path(dag_node_t *node,
     = apr_pcalloc(result_pool, sizeof(*dag_path));
   if (node)
     dag_path->node = svn_fs_x__dag_copy_into_pool(node, result_pool);
-  dag_path->entry = entry;
+  dag_path->entry = apr_pstrmemdup(result_pool, entry->data, entry->len);
   dag_path->parent = parent;
   dag_path->copy_inherit = svn_fs_x__copy_id_inherit_unknown;
   dag_path->copy_src_path = NULL;
@@ -900,7 +900,7 @@ make_parent_path(dag_node_t *node,
 svn_error_t *
 svn_fs_x__get_dag_path(svn_fs_x__dag_path_t **dag_path_p,
                        svn_fs_root_t *root,
-                       const char *path,
+                       const char *fs_path,
                        int flags,
                        svn_boolean_t is_txn_path,
                        apr_pool_t *pool)
@@ -908,132 +908,74 @@ svn_fs_x__get_dag_path(svn_fs_x__dag_pat
   svn_fs_t *fs = root->fs;
   dag_node_t *here = NULL; /* The directory we're currently looking at.  */
   svn_fs_x__dag_path_t *dag_path; /* The path from HERE up to the root. */
-  const char *rest = NULL; /* 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() PATH to be canonical. */
-  svn_stringbuf_t *path_so_far = svn_stringbuf_create(path, pool);
-
-  /* Callers often traverse the DAG in some path-based order or along the
-     history segments.  That allows us to try a few guesses about where to
-     find the next item.  This is only useful if the caller didn't request
-     the full parent chain. */
-  assert(svn_fs__is_canonical_abspath(path));
-  path_so_far->len = 0; /* "" */
+  svn_fs_x__change_set_t change_set = root_change_set(root);
+  const char *entry;
+  svn_string_t path;
+  svn_stringbuf_t *entry_buffer = svn_stringbuf_create_ensure(64, pool);
+  apr_size_t path_len;
 
-  /* Make a parent_path item for the root node, using its own current
-     copy id.  */
-  SVN_ERR(svn_fs_x__root_node(&here, root, pool, iterpool));
-  rest = path + 1; /* skip the leading '/', it saves in iteration */
+  /* Normalize the FS_PATH to be compatible with our DAG walk utils. */
+  normalize_path(&path, fs_path); /* "" */
 
-  path_so_far->data[path_so_far->len] = '\0';
-  dag_path = make_parent_path(here, 0, 0, pool);
+  /* Make a DAG_PATH for the root node, using its own current copy id.  */
+  SVN_ERR(svn_fs_x__root_node(&here, root, pool, iterpool));
+  dag_path = make_parent_path(here, entry_buffer, NULL, pool);
   dag_path->copy_inherit = svn_fs_x__copy_id_inherit_self;
 
-  /* Whenever we are at the top of this loop:
-     - HERE is our current directory,
-     - ID is the node revision ID of HERE,
-     - REST is the path we're going to find in HERE, and
-     - PARENT_PATH includes HERE and all its parents.  */
-  for (;;)
-    {
-      const char *next;
-      char *entry;
-      dag_node_t *child;
+  path_len = path.len;
+  path.len = 0;
 
+  /* Walk the path segment by segment.  Add to the DAG_PATH as we go. */
+  for (entry = next_entry_name(&path, entry_buffer);
+       entry;
+       entry = next_entry_name(&path, entry_buffer))
+    {
       svn_pool_clear(iterpool);
 
-      /* The NODE in PARENT_PATH always lives in POOL, i.e. it will
-       * survive the cleanup of ITERPOOL and the DAG cache.*/
-      here = dag_path->node;
-
-      /* Parse out the next entry from the path.  */
-      entry = svn_fs__next_entry_name(&next, rest, pool);
-
-      /* Update the path traversed thus far. */
-      path_so_far->data[path_so_far->len] = '/';
-      path_so_far->len += strlen(entry) + 1;
-      path_so_far->data[path_so_far->len] = '\0';
-
-      /* Given the behavior of svn_fs__next_entry_name(), ENTRY may be an
-         empty string when the path either starts or ends with a slash.
-         In either case, we stay put: the current directory stays the
-         same, and we add nothing to the parent path.  We only need to
-         process non-empty path segments. */
-      if (*entry != '\0')
-        {
-          svn_fs_x__copy_id_inherit_t inherit;
-          const char *copy_path = NULL;
-          dag_node_t *cached_node = NULL;
-          svn_string_t normalized;
-
-          /* If we found a directory entry, follow it.  First, we
-             check our node cache, and, failing that, we hit the DAG
-             layer.  Don't bother to contact the cache for the last
-             element if we already know the lookup to fail for the
-             complete path. */
-          cached_node = dag_node_cache_get(root,
-                                           normalize_path(&normalized,
-                                                          path_so_far->data));
-          if (cached_node)
-            child = cached_node;
-          else
-            SVN_ERR(svn_fs_x__dag_open(&child, here, entry, pool, iterpool));
+      /* Find the sub-node. */
+      SVN_ERR(dag_step(&here, root, dag_path->node, entry, &path, change_set,
+                       TRUE, iterpool));
 
-          /* "file not found" requires special handling.  */
-          if (child == NULL)
+      /* "node not found" requires special handling.  */
+      if (here == NULL)
+        {
+          /* If this was the last path component, and the caller
+             said it was optional, then don't return an error;
+             just put a NULL node pointer in the path. 
+           */
+          if ((flags & svn_fs_x__dag_path_last_optional)
+              && (path_len == path.len))
             {
-              /* If this was the last path component, and the caller
-                 said it was optional, then don't return an error;
-                 just put a NULL node pointer in the path.  */
-
-              if ((flags & svn_fs_x__dag_path_last_optional)
-                  && (! next || *next == '\0'))
-                {
-                  dag_path = make_parent_path(NULL, entry, dag_path, pool);
-                  break;
-                }
-              else if (flags & svn_fs_x__dag_path_allow_null)
-                {
-                  dag_path = NULL;
-                  break;
-                }
-              else
-                {
-                  /* Build a better error message than svn_fs_x__dag_open
-                     can provide, giving the root and full path name.  */
-                  return SVN_FS__NOT_FOUND(root, path);
-                }
+              dag_path = make_parent_path(NULL, entry_buffer, dag_path, pool);
+              break;
             }
-
-          /* Now, make a parent_path item for CHILD. */
-          dag_path = make_parent_path(child, entry, dag_path, pool);
-          if (is_txn_path)
+          else if (flags & svn_fs_x__dag_path_allow_null)
             {
-              SVN_ERR(get_copy_inheritance(&inherit, &copy_path, fs,
-                                           dag_path, iterpool));
-              dag_path->copy_inherit = inherit;
-              dag_path->copy_src_path = apr_pstrdup(pool, copy_path);
+              dag_path = NULL;
+              break;
+            }
+          else
+            {
+              /* Build a better error message than svn_fs_x__dag_open
+                 can provide, giving the root and full path name.  */
+              return SVN_FS__NOT_FOUND(root, fs_path);
             }
-
-          /* Cache the node we found (if it wasn't already cached). */
-          if (! cached_node)
-            set_dag_node(root, path_so_far->data, child);
         }
 
-      /* Are we finished traversing the path?  */
-      if (! next)
-        break;
-
-      /* The path isn't finished yet; we'd better be in a directory.  */
-      if (svn_fs_x__dag_node_kind(child) != svn_node_dir)
-        SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data),
-                  apr_psprintf(iterpool, _("Failure opening '%s'"), path));
+      /* Now, make a parent_path item for CHILD. */
+      dag_path = make_parent_path(here, entry_buffer, dag_path, pool);
+      if (is_txn_path)
+        {
+          svn_fs_x__copy_id_inherit_t inherit;
+          const char *copy_path = NULL;
+          SVN_ERR(get_copy_inheritance(&inherit, &copy_path, fs,
+                                       dag_path, iterpool));
 
-      rest = next;
+          dag_path->copy_inherit = inherit;
+          dag_path->copy_src_path = apr_pstrdup(pool, copy_path);
+        }
     }
 
   svn_pool_destroy(iterpool);


Reply via email to