summaryrefslogtreecommitdiff
path: root/subversion/libsvn_fs_base/tree.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-03-18 13:33:26 +0000
committer <>2015-07-08 14:41:01 +0000
commitbb0ef45f7c46b0ae221b26265ef98a768c33f820 (patch)
tree98bae10dde41c746c51ae97ec4f879e330415aa7 /subversion/libsvn_fs_base/tree.c
parent239dfafe71711b2f4c43d7b90a1228d7bdc5195e (diff)
downloadsubversion-tarball-subversion-1.8.13.tar.gz
Imported from /home/lorry/working-area/delta_subversion-tarball/subversion-1.8.13.tar.gz.subversion-1.8.13
Diffstat (limited to 'subversion/libsvn_fs_base/tree.c')
-rw-r--r--subversion/libsvn_fs_base/tree.c142
1 files changed, 62 insertions, 80 deletions
diff --git a/subversion/libsvn_fs_base/tree.c b/subversion/libsvn_fs_base/tree.c
index 25fa69c..046ab5d 100644
--- a/subversion/libsvn_fs_base/tree.c
+++ b/subversion/libsvn_fs_base/tree.c
@@ -39,6 +39,7 @@
#include <string.h>
#include <assert.h>
#include "svn_private_config.h"
+#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_path.h"
@@ -160,7 +161,7 @@ dag_node_cache_get(svn_fs_root_t *root,
return NULL;
/* Look in the cache for our desired item. */
- cache_item = apr_hash_get(brd->node_cache, path, APR_HASH_KEY_STRING);
+ cache_item = svn_hash_gets(brd->node_cache, path);
if (cache_item)
return svn_fs_base__dag_dup(cache_item->node, pool);
@@ -208,7 +209,7 @@ dag_node_cache_set(svn_fs_root_t *root,
root, and that only happens once under that root. So, we'll be a
little bit sloppy here, and count on callers doing the right
thing. */
- cache_item = apr_hash_get(brd->node_cache, path, APR_HASH_KEY_STRING);
+ cache_item = svn_hash_gets(brd->node_cache, path);
if (cache_item)
{
/* ### This section is somehow broken. I don't know how, but it
@@ -250,9 +251,8 @@ dag_node_cache_set(svn_fs_root_t *root,
{
/* No room. Expire the oldest thing. */
cache_path = brd->node_cache_keys[brd->node_cache_idx];
- cache_item = apr_hash_get(brd->node_cache, cache_path,
- APR_HASH_KEY_STRING);
- apr_hash_set(brd->node_cache, cache_path, APR_HASH_KEY_STRING, NULL);
+ cache_item = svn_hash_gets(brd->node_cache, cache_path);
+ svn_hash_sets(brd->node_cache, cache_path, NULL);
cache_pool = cache_item->pool;
svn_pool_clear(cache_pool);
}
@@ -269,7 +269,7 @@ dag_node_cache_set(svn_fs_root_t *root,
/* Now add it to the cache. */
cache_path = apr_pstrdup(cache_pool, path);
- apr_hash_set(brd->node_cache, cache_path, APR_HASH_KEY_STRING, cache_item);
+ svn_hash_sets(brd->node_cache, cache_path, cache_item);
brd->node_cache_keys[brd->node_cache_idx] = cache_path;
/* Advance the cache pointer. */
@@ -309,11 +309,10 @@ txn_body_txn_root(void *baton,
/* Look for special txn props that represent the 'flags' behavior of
the transaction. */
SVN_ERR(svn_fs_base__txn_proplist_in_trail(&txnprops, svn_txn_id, trail));
- if (apr_hash_get(txnprops, SVN_FS__PROP_TXN_CHECK_OOD, APR_HASH_KEY_STRING))
+ if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_OOD))
flags |= SVN_FS_TXN_CHECK_OOD;
- if (apr_hash_get(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS,
- APR_HASH_KEY_STRING))
+ if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS))
flags |= SVN_FS_TXN_CHECK_LOCKS;
root = make_txn_root(fs, svn_txn_id, txn->base_rev, flags, trail->pool);
@@ -431,7 +430,7 @@ mutable_root_node(dag_node_t **node_p,
trail, pool);
else
/* If it's not a transaction root, we can't change its contents. */
- return SVN_FS__ERR_NOT_MUTABLE(root->fs, root->rev, error_path, pool);
+ return SVN_FS__ERR_NOT_MUTABLE(root->fs, root->rev, error_path);
}
@@ -769,7 +768,7 @@ open_path(parent_path_t **parent_path_p,
/* The path isn't finished yet; we'd better be in a directory. */
if (svn_fs_base__dag_node_kind(child) != svn_node_dir)
- SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far, pool),
+ SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far),
apr_psprintf(pool, _("Failure opening '%s'"), path));
rest = next;
@@ -1191,8 +1190,7 @@ txn_body_node_prop(void *baton,
trail, trail->pool));
*(args->value_p) = NULL;
if (proplist)
- *(args->value_p) = apr_hash_get(proplist, args->propname,
- APR_HASH_KEY_STRING);
+ *(args->value_p) = svn_hash_gets(proplist, args->propname);
return SVN_NO_ERROR;
}
@@ -1304,7 +1302,7 @@ txn_body_change_node_prop(void *baton,
proplist = apr_hash_make(trail->pool);
/* Set the property. */
- apr_hash_set(proplist, args->name, APR_HASH_KEY_STRING, args->value);
+ svn_hash_sets(proplist, args->name, args->value);
/* Overwrite the node's proplist. */
SVN_ERR(svn_fs_base__dag_set_proplist(parent_path->node, proplist,
@@ -2523,11 +2521,11 @@ verify_locks(const char *txn_name,
/* If this path has already been verified as part of a recursive
check of one of its parents, no need to do it again. */
if (last_recursed
- && svn_fspath__is_child(last_recursed->data, path, subpool))
+ && svn_fspath__skip_ancestor(last_recursed->data, path))
continue;
/* Fetch the change associated with our path. */
- change = apr_hash_get(changes, path, APR_HASH_KEY_STRING);
+ change = svn_hash_gets(changes, path);
/* What does it mean to succeed at lock verification for a given
path? For an existing file or directory getting modified
@@ -2722,7 +2720,7 @@ svn_fs_base__commit_txn(const char **conflict_p,
merge_args.ancestor_node = NULL;
merge_args.source_node = youngish_root_node;
merge_args.txn = txn;
- merge_args.conflict = svn_stringbuf_create("", pool); /* use pool */
+ merge_args.conflict = svn_stringbuf_create_empty(pool); /* use pool */
err = svn_fs_base__retry_txn(fs, txn_body_merge, &merge_args,
FALSE, subpool);
if (err)
@@ -2832,7 +2830,7 @@ base_merge(const char **conflict_p,
merge_args.source_node = source;
merge_args.ancestor_node = ancestor;
merge_args.txn = txn;
- merge_args.conflict = svn_stringbuf_create("", pool);
+ merge_args.conflict = svn_stringbuf_create_empty(pool);
err = svn_fs_base__retry_txn(fs, txn_body_merge, &merge_args, FALSE, pool);
if (err)
{
@@ -2926,7 +2924,7 @@ txn_body_make_dir(void *baton,
/* If there's already a sub-directory by that name, complain. This
also catches the case of trying to make a subdirectory named `/'. */
if (parent_path->node)
- return SVN_FS__ALREADY_EXISTS(root, path, trail->pool);
+ return SVN_FS__ALREADY_EXISTS(root, path);
/* Check to see if some lock is 'reserving' a file-path or dir-path
at that location, or even some child-path; if so, check that we
@@ -3192,17 +3190,7 @@ fs_same_p(svn_boolean_t *same_p,
svn_fs_t *fs2,
apr_pool_t *pool)
{
- const char *uuid1;
- const char *uuid2;
-
- /* Random thought: if fetching UUIDs to compare filesystems is too
- expensive, one solution would be to cache the UUID in each fs
- object (copying the UUID into fs->pool, of course). */
-
- SVN_ERR(fs1->vtable->get_uuid(fs1, &uuid1, pool));
- SVN_ERR(fs2->vtable->get_uuid(fs2, &uuid2, pool));
-
- *same_p = ! strcmp(uuid1, uuid2);
+ *same_p = ! strcmp(fs1->uuid, fs2->uuid);
return SVN_NO_ERROR;
}
@@ -3379,7 +3367,7 @@ txn_body_make_file(void *baton,
/* If there's already a file by that name, complain.
This also catches the case of trying to make a file named `/'. */
if (parent_path->node)
- return SVN_FS__ALREADY_EXISTS(root, path, trail->pool);
+ return SVN_FS__ALREADY_EXISTS(root, path);
/* Check to see if some lock is 'reserving' a file-path or dir-path
at that location, or even some child-path; if so, check that we
@@ -3686,7 +3674,7 @@ window_consumer(svn_txdelta_window_t *window, void *baton)
SVN_ERR(svn_stream_write(tb->target_stream,
tb->target_string->data,
&len));
- svn_stringbuf_set(tb->target_string, "");
+ svn_stringbuf_setempty(tb->target_string);
}
/* Is the window NULL? If so, we're done. */
@@ -3742,8 +3730,7 @@ txn_body_apply_textdelta(void *baton, trail_t *trail)
we're calculating both SHA1 and MD5 checksums somewhere in
reps-strings.c. Could we keep them both around somehow so this
check could be more comprehensive? */
- if (tb->base_checksum->kind == checksum->kind
- && !svn_checksum_match(tb->base_checksum, checksum))
+ if (!svn_checksum_match(tb->base_checksum, checksum))
return svn_checksum_mismatch_err(tb->base_checksum, checksum,
trail->pool,
_("Base checksum mismatch on '%s'"),
@@ -3762,7 +3749,7 @@ txn_body_apply_textdelta(void *baton, trail_t *trail)
/* Make a writable "string" stream which writes data to
tb->target_string. */
- tb->target_string = svn_stringbuf_create("", tb->pool);
+ tb->target_string = svn_stringbuf_create_empty(tb->pool);
tb->string_stream = svn_stream_create(tb, tb->pool);
svn_stream_set_write(tb->string_stream, write_to_string);
@@ -3793,16 +3780,8 @@ base_apply_textdelta(svn_txdelta_window_handler_t *contents_p,
tb->root = root;
tb->path = path;
tb->pool = pool;
-
- if (base_checksum)
- tb->base_checksum = svn_checksum_dup(base_checksum, pool);
- else
- tb->base_checksum = NULL;
-
- if (result_checksum)
- tb->result_checksum = svn_checksum_dup(result_checksum, pool);
- else
- tb->result_checksum = NULL;
+ tb->base_checksum = svn_checksum_dup(base_checksum, pool);
+ tb->result_checksum = svn_checksum_dup(result_checksum, pool);
SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_apply_textdelta, tb,
FALSE, pool));
@@ -3943,11 +3922,7 @@ base_apply_text(svn_stream_t **contents_p,
tb->root = root;
tb->path = path;
tb->pool = pool;
-
- if (result_checksum)
- tb->result_checksum = svn_checksum_dup(result_checksum, pool);
- else
- tb->result_checksum = NULL;
+ tb->result_checksum = svn_checksum_dup(result_checksum, pool);
SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_apply_text, tb,
FALSE, pool));
@@ -4046,7 +4021,7 @@ base_get_file_delta_stream(svn_txdelta_stream_t **stream_p,
SVN_ERR(base_file_contents(&target, target_root, target_path, pool));
/* Create a delta stream that turns the ancestor into the target. */
- svn_txdelta(&delta_stream, source, target, pool);
+ svn_txdelta2(&delta_stream, source, target, TRUE, pool);
*stream_p = delta_stream;
return SVN_NO_ERROR;
@@ -4349,10 +4324,7 @@ txn_body_history_prev(void *baton, trail_t *trail)
the copy source. Finally, if our current path doesn't meet
one of these other criteria ... ### for now just fallback to
the old copy hunt algorithm. */
- if (strcmp(path, copy_dst) == 0)
- remainder = "";
- else
- remainder = svn_fspath__is_child(copy_dst, path, trail->pool);
+ remainder = svn_fspath__skip_ancestor(copy_dst, path);
if (remainder)
{
@@ -4745,7 +4717,7 @@ prev_location(const char **prev_path,
const char *path,
apr_pool_t *pool)
{
- const char *copy_path, *copy_src_path, *remainder = "";
+ const char *copy_path, *copy_src_path, *remainder;
svn_fs_root_t *copy_root;
svn_revnum_t copy_src_rev;
@@ -4774,8 +4746,7 @@ prev_location(const char **prev_path,
*/
SVN_ERR(base_copied_from(&copy_src_rev, &copy_src_path,
copy_root, copy_path, pool));
- if (! strcmp(copy_path, path) == 0)
- remainder = svn_fspath__is_child(copy_path, path, pool);
+ remainder = svn_fspath__skip_ancestor(copy_path, path);
*prev_path = svn_fspath__join(copy_src_path, remainder, pool);
*prev_rev = copy_src_rev;
return SVN_NO_ERROR;
@@ -4840,6 +4811,13 @@ base_node_origin_rev(svn_revnum_t *revision,
prev_location() does below will work. */
path = svn_fs__canonicalize_abspath(path, pool);
+ /* Special-case the root node (for performance reasons) */
+ if (strcmp(path, "/") == 0)
+ {
+ *revision = 0;
+ return SVN_NO_ERROR;
+ }
+
/* If we have support for the node-origins table, we'll try to use
it. */
if (bfd->format >= SVN_FS_BASE__MIN_NODE_ORIGINS_FORMAT)
@@ -5026,7 +5004,7 @@ txn_body_get_mergeinfo_data_and_entries(void *baton, trail_t *trail)
SVN_ERR(svn_fs_base__dag_get_proplist(&plist, child_node,
trail, iterpool));
- pval = apr_hash_get(plist, SVN_PROP_MERGEINFO, APR_HASH_KEY_STRING);
+ pval = svn_hash_gets(plist, SVN_PROP_MERGEINFO);
if (! pval)
{
svn_string_t *id_str = svn_fs_base__id_unparse(child_id,
@@ -5050,11 +5028,10 @@ txn_body_get_mergeinfo_data_and_entries(void *baton, trail_t *trail)
}
else
{
- apr_hash_set(args->result_catalog,
- svn_fspath__join(args->node_path, dirent->name,
- result_pool),
- APR_HASH_KEY_STRING,
- child_mergeinfo);
+ svn_hash_sets(args->result_catalog,
+ svn_fspath__join(args->node_path, dirent->name,
+ result_pool),
+ child_mergeinfo);
}
}
@@ -5074,10 +5051,9 @@ txn_body_get_mergeinfo_data_and_entries(void *baton, trail_t *trail)
"but is not a directory"),
id_str->data);
}
- apr_hash_set(args->children_atop_mergeinfo_trees,
- apr_pstrdup(children_pool, dirent->name),
- APR_HASH_KEY_STRING,
- svn_fs_base__dag_dup(child_node, children_pool));
+ svn_hash_sets(args->children_atop_mergeinfo_trees,
+ apr_pstrdup(children_pool, dirent->name),
+ svn_fs_base__dag_dup(child_node, children_pool));
}
}
@@ -5142,6 +5118,7 @@ struct get_mergeinfo_for_path_baton
svn_fs_root_t *root;
const char *path;
svn_mergeinfo_inheritance_t inherit;
+ svn_boolean_t adjust_inherited_mergeinfo;
apr_pool_t *pool;
};
@@ -5202,8 +5179,7 @@ txn_body_get_mergeinfo_for_path(void *baton, trail_t *trail)
svn_pool_destroy(iterpool);
SVN_ERR(svn_fs_base__dag_get_proplist(&proplist, node, trail, trail->pool));
- mergeinfo_string = apr_hash_get(proplist, SVN_PROP_MERGEINFO,
- APR_HASH_KEY_STRING);
+ mergeinfo_string = svn_hash_gets(proplist, SVN_PROP_MERGEINFO);
if (! mergeinfo_string)
{
svn_string_t *id_str =
@@ -5237,7 +5213,7 @@ txn_body_get_mergeinfo_for_path(void *baton, trail_t *trail)
can return the mergeinfo results directly. Otherwise, we're
inheriting the mergeinfo, so we need to a) remove non-inheritable
ranges and b) telescope the merged-from paths. */
- if (nearest_ancestor != parent_path)
+ if (args->adjust_inherited_mergeinfo && (nearest_ancestor != parent_path))
{
svn_mergeinfo_t tmp_mergeinfo;
@@ -5291,10 +5267,12 @@ get_mergeinfos_for_paths(svn_fs_root_t *root,
const apr_array_header_t *paths,
svn_mergeinfo_inheritance_t inherit,
svn_boolean_t include_descendants,
- apr_pool_t *pool)
+ svn_boolean_t adjust_inherited_mergeinfo,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- svn_mergeinfo_catalog_t result_catalog = apr_hash_make(pool);
- apr_pool_t *iterpool = svn_pool_create(pool);
+ svn_mergeinfo_catalog_t result_catalog = apr_hash_make(result_pool);
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
int i;
for (i = 0; i < paths->nelts; i++)
@@ -5312,14 +5290,14 @@ get_mergeinfos_for_paths(svn_fs_root_t *root,
gmfp_args.root = root;
gmfp_args.path = path;
gmfp_args.inherit = inherit;
- gmfp_args.pool = pool;
+ gmfp_args.pool = result_pool;
+ gmfp_args.adjust_inherited_mergeinfo = adjust_inherited_mergeinfo;
SVN_ERR(svn_fs_base__retry_txn(root->fs,
txn_body_get_mergeinfo_for_path,
&gmfp_args, FALSE, iterpool));
if (path_mergeinfo)
- apr_hash_set(result_catalog, apr_pstrdup(pool, path),
- APR_HASH_KEY_STRING,
- path_mergeinfo);
+ svn_hash_sets(result_catalog, apr_pstrdup(result_pool, path),
+ path_mergeinfo);
/* If we're including descendants, do so. */
if (include_descendants)
@@ -5363,7 +5341,9 @@ base_get_mergeinfo(svn_mergeinfo_catalog_t *catalog,
const apr_array_header_t *paths,
svn_mergeinfo_inheritance_t inherit,
svn_boolean_t include_descendants,
- apr_pool_t *pool)
+ svn_boolean_t adjust_inherited_mergeinfo,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
/* Verify that our filesystem version supports mergeinfo stuff. */
SVN_ERR(svn_fs_base__test_required_feature_format
@@ -5376,7 +5356,8 @@ base_get_mergeinfo(svn_mergeinfo_catalog_t *catalog,
/* Retrieve a path -> mergeinfo mapping. */
return get_mergeinfos_for_paths(root, catalog, paths,
inherit, include_descendants,
- pool);
+ adjust_inherited_mergeinfo,
+ result_pool, scratch_pool);
}
@@ -5406,6 +5387,7 @@ static root_vtable_t root_vtable = {
base_file_length,
base_file_checksum,
base_file_contents,
+ NULL,
base_make_file,
base_apply_textdelta,
base_apply_text,