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, ©_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