diff options
author | Peter Wemm <peter@FreeBSD.org> | 2018-05-08 03:44:38 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 2018-05-08 03:44:38 +0000 |
commit | 3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (patch) | |
tree | 7e47911263e75034b767fe34b2f8d3d17e91f66d /subversion/libsvn_fs_x/dag.c | |
parent | a55fb3c0d5eca7d887798125d5b95942b1f01d4b (diff) |
Import Subversion-1.10.0vendor/subversion/subversion-1.10.0
Notes
Notes:
svn path=/vendor/subversion/dist/; revision=333347
svn path=/vendor/subversion/subversion-1.10.0/; revision=333348; tag=vendor/subversion/subversion-1.10.0
Diffstat (limited to 'subversion/libsvn_fs_x/dag.c')
-rw-r--r-- | subversion/libsvn_fs_x/dag.c | 603 |
1 files changed, 159 insertions, 444 deletions
diff --git a/subversion/libsvn_fs_x/dag.c b/subversion/libsvn_fs_x/dag.c index 2f5bcb260a6c..5656dbe60034 100644 --- a/subversion/libsvn_fs_x/dag.c +++ b/subversion/libsvn_fs_x/dag.c @@ -1,4 +1,4 @@ -/* dag.c : DAG-like interface filesystem, private to libsvn_fs +/* dag.c : DAG-like interface filesystem * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one @@ -41,6 +41,7 @@ #include "svn_private_config.h" #include "private/svn_temp_serializer.h" #include "temp_serializer.h" +#include "dag_cache.h" /* Initializing a filesystem. */ @@ -50,34 +51,12 @@ struct dag_node_t /* The filesystem this dag node came from. */ svn_fs_t *fs; - /* The node revision ID for this dag node. */ - svn_fs_x__id_t id; - - /* In the special case that this node is the root of a transaction - that has not yet been modified, the revision of this node is the - respective txn's base rev. Otherwise, this is SVN_INVALID_REVNUM - for txn nodes and the respective crev for committed nodes. - (Used in svn_fs_node_created_rev.) */ - svn_revnum_t revision; - - /* The node's type (file, dir, etc.) */ - svn_node_kind_t kind; - - /* The node's NODE-REVISION, or NULL if we haven't read it in yet. - This is allocated in this node's POOL. - - If you're willing to respect all the rules above, you can munge - this yourself, but you're probably better off just calling - `get_node_revision' and `set_node_revision', which take care of - things for you. */ + /* The node's NODE-REVISION. */ svn_fs_x__noderev_t *node_revision; /* The pool to allocate NODE_REVISION in. */ apr_pool_t *node_pool; - /* the path at which this node was created. */ - const char *created_path; - /* Directory entry lookup hint to speed up consecutive calls to svn_fs_x__rep_contents_dir_entry(). Only used for directory nodes. Any value is legal but should default to APR_SIZE_MAX. */ @@ -90,20 +69,20 @@ struct dag_node_t svn_node_kind_t svn_fs_x__dag_node_kind(dag_node_t *node) { - return node->kind; + return node->node_revision->kind; } const svn_fs_x__id_t * svn_fs_x__dag_get_id(const dag_node_t *node) { - return &node->id; + return &node->node_revision->noderev_id; } const char * svn_fs_x__dag_get_created_path(dag_node_t *node) { - return node->created_path; + return node->node_revision->created_path; } @@ -144,94 +123,35 @@ copy_node_revision(svn_fs_x__noderev_t *noderev, } -/* Set *NODEREV_P to the cached node-revision for NODE. - If the node-revision was not already cached in NODE, read it in, - allocating the cache in NODE->NODE_POOL. - - If you plan to change the contents of NODE, be careful! We're - handing you a pointer directly to our cached node-revision, not - your own copy. If you change it as part of some operation, but - then some Berkeley DB function deadlocks or gets an error, you'll - need to back out your changes, or else the cache will reflect - changes that never got committed. It's probably best not to change - the structure at all. */ -static svn_error_t * -get_node_revision(svn_fs_x__noderev_t **noderev_p, - dag_node_t *node) -{ - /* If we've already got a copy, there's no need to read it in. */ - if (! node->node_revision) - { - svn_fs_x__noderev_t *noderev; - apr_pool_t *scratch_pool = svn_pool_create(node->node_pool); - - SVN_ERR(svn_fs_x__get_node_revision(&noderev, node->fs, &node->id, - node->node_pool, scratch_pool)); - node->node_revision = noderev; - svn_pool_destroy(scratch_pool); - } - - /* Now NODE->node_revision is set. */ - *noderev_p = node->node_revision; - return SVN_NO_ERROR; -} - -/* Return the node revision ID of NODE. The value returned is shared - with NODE, and will be deallocated when NODE is. */ -svn_error_t * -svn_fs_x__dag_get_node_id(svn_fs_x__id_t *node_id, - dag_node_t *node) +const svn_fs_x__id_t * +svn_fs_x__dag_get_node_id(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - SVN_ERR(get_node_revision(&noderev, node)); - - *node_id = noderev->node_id; - return SVN_NO_ERROR; + return &node->node_revision->node_id; } -/* Return the node revision ID of NODE. The value returned is shared - with NODE, and will be deallocated when NODE is. */ -svn_error_t * -svn_fs_x__dag_get_copy_id(svn_fs_x__id_t *copy_id, - dag_node_t *node) +const svn_fs_x__id_t * +svn_fs_x__dag_get_copy_id(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - SVN_ERR(get_node_revision(&noderev, node)); - - *copy_id = noderev->copy_id; - return SVN_NO_ERROR; + return &node->node_revision->copy_id; } -/* Return the node ID of NODE. The value returned is shared with NODE, - and will be deallocated when NODE is. */ -svn_error_t * -svn_fs_x__dag_related_node(svn_boolean_t *same, - dag_node_t *lhs, +svn_boolean_t +svn_fs_x__dag_related_node(dag_node_t *lhs, dag_node_t *rhs) { - svn_fs_x__id_t lhs_node, rhs_node; - - SVN_ERR(svn_fs_x__dag_get_node_id(&lhs_node, lhs)); - SVN_ERR(svn_fs_x__dag_get_node_id(&rhs_node, rhs)); - *same = svn_fs_x__id_eq(&lhs_node, &rhs_node); - - return SVN_NO_ERROR; + return svn_fs_x__id_eq(&lhs->node_revision->node_id, + &rhs->node_revision->node_id); } -svn_error_t * -svn_fs_x__dag_same_line_of_history(svn_boolean_t *same, - dag_node_t *lhs, +svn_boolean_t +svn_fs_x__dag_same_line_of_history(dag_node_t *lhs, dag_node_t *rhs) { - svn_fs_x__noderev_t *lhs_noderev, *rhs_noderev; + svn_fs_x__noderev_t *lhs_noderev = lhs->node_revision; + svn_fs_x__noderev_t *rhs_noderev = rhs->node_revision; - SVN_ERR(get_node_revision(&lhs_noderev, lhs)); - SVN_ERR(get_node_revision(&rhs_noderev, rhs)); - - *same = svn_fs_x__id_eq(&lhs_noderev->node_id, &rhs_noderev->node_id) - && svn_fs_x__id_eq(&lhs_noderev->copy_id, &rhs_noderev->copy_id); - - return SVN_NO_ERROR; + return svn_fs_x__id_eq(&lhs_noderev->node_id, &rhs_noderev->node_id) + && svn_fs_x__id_eq(&lhs_noderev->copy_id, &rhs_noderev->copy_id); } svn_boolean_t @@ -240,7 +160,6 @@ svn_fs_x__dag_check_mutable(const dag_node_t *node) return svn_fs_x__is_txn(svn_fs_x__dag_get_id(node)->change_set); } - svn_error_t * svn_fs_x__dag_get_node(dag_node_t **node, svn_fs_t *fs, @@ -254,7 +173,6 @@ svn_fs_x__dag_get_node(dag_node_t **node, /* Construct the node. */ new_node = apr_pcalloc(result_pool, sizeof(*new_node)); new_node->fs = fs; - new_node->id = *id; new_node->hint = APR_SIZE_MAX; /* Grab the contents so we can inspect the node's kind and created path. */ @@ -263,17 +181,6 @@ svn_fs_x__dag_get_node(dag_node_t **node, new_node->node_pool = result_pool; new_node->node_revision = noderev; - /* Initialize the KIND and CREATED_PATH attributes */ - new_node->kind = noderev->kind; - new_node->created_path = noderev->created_path; - - /* Support our quirky svn_fs_node_created_rev API. - Untouched txn roots report the base rev as theirs. */ - new_node->revision - = ( svn_fs_x__is_fresh_txn_root(noderev) - ? svn_fs_x__get_revnum(noderev->predecessor_id.change_set) - : svn_fs_x__get_revnum(id->change_set)); - /* Return a fresh new node */ *node = new_node; return SVN_NO_ERROR; @@ -283,76 +190,50 @@ svn_fs_x__dag_get_node(dag_node_t **node, svn_revnum_t svn_fs_x__dag_get_revision(const dag_node_t *node) { - return node->revision; + svn_fs_x__noderev_t *noderev = node->node_revision; + return ( svn_fs_x__is_fresh_txn_root(noderev) + ? svn_fs_x__get_revnum(noderev->predecessor_id.change_set) + : svn_fs_x__get_revnum(noderev->noderev_id.change_set)); } - -svn_error_t * -svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p, - dag_node_t *node) +const svn_fs_x__id_t * +svn_fs_x__dag_get_predecessor_id(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - - SVN_ERR(get_node_revision(&noderev, node)); - *id_p = noderev->predecessor_id; - - return SVN_NO_ERROR; + return &node->node_revision->predecessor_id; } - -svn_error_t * -svn_fs_x__dag_get_predecessor_count(int *count, - dag_node_t *node) +int +svn_fs_x__dag_get_predecessor_count(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - - SVN_ERR(get_node_revision(&noderev, node)); - *count = noderev->predecessor_count; - return SVN_NO_ERROR; + return node->node_revision->predecessor_count; } -svn_error_t * -svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count, - dag_node_t *node) +apr_int64_t +svn_fs_x__dag_get_mergeinfo_count(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - - SVN_ERR(get_node_revision(&noderev, node)); - *count = noderev->mergeinfo_count; - return SVN_NO_ERROR; + return node->node_revision->mergeinfo_count; } -svn_error_t * -svn_fs_x__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo, - dag_node_t *node) +svn_boolean_t +svn_fs_x__dag_has_mergeinfo(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - - SVN_ERR(get_node_revision(&noderev, node)); - *has_mergeinfo = noderev->has_mergeinfo; - return SVN_NO_ERROR; + return node->node_revision->has_mergeinfo; } -svn_error_t * -svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they, - dag_node_t *node) +svn_boolean_t +svn_fs_x__dag_has_descendants_with_mergeinfo(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; + svn_fs_x__noderev_t *noderev = node->node_revision; - if (node->kind != svn_node_dir) - { - *do_they = FALSE; - return SVN_NO_ERROR; - } + if (noderev->kind != svn_node_dir) + return FALSE; - SVN_ERR(get_node_revision(&noderev, node)); if (noderev->mergeinfo_count > 1) - *do_they = TRUE; + return TRUE; else if (noderev->mergeinfo_count == 1 && !noderev->has_mergeinfo) - *do_they = TRUE; - else - *do_they = FALSE; - return SVN_NO_ERROR; + return TRUE; + + return FALSE; } @@ -362,16 +243,15 @@ svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they, /* Set *ID_P to the noderev-id for entry NAME in PARENT. If no such entry, set *ID_P to NULL but do not error. */ -static svn_error_t * -dir_entry_id_from_node(svn_fs_x__id_t *id_p, +svn_error_t * +svn_fs_x__dir_entry_id(svn_fs_x__id_t *id_p, dag_node_t *parent, const char *name, apr_pool_t *scratch_pool) { svn_fs_x__dirent_t *dirent; - svn_fs_x__noderev_t *noderev; + svn_fs_x__noderev_t *noderev = parent->node_revision; - SVN_ERR(get_node_revision(&noderev, parent)); if (noderev->kind != svn_node_dir) return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL, _("Can't get entries of non-directory")); @@ -411,14 +291,16 @@ set_entry(dag_node_t *parent, svn_fs_x__txn_id_t txn_id, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *parent_noderev; - - /* Get the parent's node-revision. */ - SVN_ERR(get_node_revision(&parent_noderev, parent)); + svn_fs_x__noderev_t *parent_noderev = parent->node_revision; /* Set the new entry. */ - return svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name, id, - kind, parent->node_pool, scratch_pool); + SVN_ERR(svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name, id, + kind, parent->node_pool, scratch_pool)); + + /* Update cached data. */ + svn_fs_x__update_dag_cache(parent); + + return SVN_NO_ERROR; } @@ -439,7 +321,8 @@ make_entry(dag_node_t **child_p, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t new_noderev, *parent_noderev; + svn_fs_x__noderev_t new_noderev; + svn_fs_x__noderev_t *parent_noderev = parent->node_revision; /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) @@ -448,7 +331,7 @@ make_entry(dag_node_t **child_p, _("Attempted to create a node with an illegal name '%s'"), name); /* Make sure that parent is a directory */ - if (parent->kind != svn_node_dir) + if (parent_noderev->kind != svn_node_dir) return svn_error_create (SVN_ERR_FS_NOT_DIRECTORY, NULL, _("Attempted to create entry in non-directory parent")); @@ -464,7 +347,6 @@ make_entry(dag_node_t **child_p, new_noderev.kind = is_dir ? svn_node_dir : svn_node_file; new_noderev.created_path = svn_fspath__join(parent_path, name, result_pool); - SVN_ERR(get_node_revision(&parent_noderev, parent)); new_noderev.copyroot_path = apr_pstrdup(result_pool, parent_noderev->copyroot_path); new_noderev.copyroot_rev = parent_noderev->copyroot_rev; @@ -495,9 +377,7 @@ svn_fs_x__dag_dir_entries(apr_array_header_t **entries, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *noderev; - - SVN_ERR(get_node_revision(&noderev, node)); + svn_fs_x__noderev_t *noderev = node->node_revision; if (noderev->kind != svn_node_dir) return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL, @@ -517,7 +397,7 @@ svn_fs_x__dag_set_entry(dag_node_t *node, apr_pool_t *scratch_pool) { /* Check it's a directory. */ - if (node->kind != svn_node_dir) + if (node->node_revision->kind != svn_node_dir) return svn_error_create (SVN_ERR_FS_NOT_DIRECTORY, NULL, _("Attempted to set entry in non-directory node")); @@ -541,16 +421,8 @@ svn_fs_x__dag_get_proplist(apr_hash_t **proplist_p, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *noderev; - apr_hash_t *proplist = NULL; - - SVN_ERR(get_node_revision(&noderev, node)); - - SVN_ERR(svn_fs_x__get_proplist(&proplist, node->fs, noderev, result_pool, - scratch_pool)); - - *proplist_p = proplist; - + SVN_ERR(svn_fs_x__get_proplist(proplist_p, node->fs, node->node_revision, + result_pool, scratch_pool)); return SVN_NO_ERROR; } @@ -560,37 +432,51 @@ svn_fs_x__dag_set_proplist(dag_node_t *node, apr_hash_t *proplist, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *noderev; - /* Sanity check: this node better be mutable! */ if (! svn_fs_x__dag_check_mutable(node)) { - svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); + svn_string_t *idstr + = svn_fs_x__id_unparse(&node->node_revision->noderev_id, + scratch_pool); return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Can't set proplist on *immutable* node-revision %s", idstr->data); } - /* Go get a fresh NODE-REVISION for this node. */ - SVN_ERR(get_node_revision(&noderev, node)); - /* Set the new proplist. */ - return svn_fs_x__set_proplist(node->fs, noderev, proplist, scratch_pool); + SVN_ERR(svn_fs_x__set_proplist(node->fs, node->node_revision, proplist, + scratch_pool)); + svn_fs_x__update_dag_cache(node); + + return SVN_NO_ERROR; } +/* Write NODE's NODEREV element to disk. Update the DAG cache. + Use SCRATCH_POOL for temporary allocations. */ +static svn_error_t * +noderev_changed(dag_node_t *node, + apr_pool_t *scratch_pool) +{ + SVN_ERR(svn_fs_x__put_node_revision(node->fs, node->node_revision, + scratch_pool)); + svn_fs_x__update_dag_cache(node); + + return SVN_NO_ERROR; +} svn_error_t * svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node, apr_int64_t increment, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *noderev; + svn_fs_x__noderev_t *noderev = node->node_revision; /* Sanity check: this node better be mutable! */ if (! svn_fs_x__dag_check_mutable(node)) { - svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&noderev->noderev_id, + scratch_pool); return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Can't increment mergeinfo count on *immutable* node-revision %s", @@ -600,13 +486,11 @@ svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node, if (increment == 0) return SVN_NO_ERROR; - /* Go get a fresh NODE-REVISION for this node. */ - SVN_ERR(get_node_revision(&noderev, node)); - noderev->mergeinfo_count += increment; if (noderev->mergeinfo_count < 0) { - svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&noderev->noderev_id, + scratch_pool); return svn_error_createf (SVN_ERR_FS_CORRUPT, NULL, apr_psprintf(scratch_pool, @@ -617,7 +501,8 @@ svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node, } if (noderev->mergeinfo_count > 1 && noderev->kind == svn_node_file) { - svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&noderev->noderev_id, + scratch_pool); return svn_error_createf (SVN_ERR_FS_CORRUPT, NULL, apr_psprintf(scratch_pool, @@ -628,7 +513,7 @@ svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node, } /* Flush it out. */ - return svn_fs_x__put_node_revision(node->fs, noderev, scratch_pool); + return noderev_changed(node, scratch_pool); } svn_error_t * @@ -636,55 +521,38 @@ svn_fs_x__dag_set_has_mergeinfo(dag_node_t *node, svn_boolean_t has_mergeinfo, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *noderev; - /* Sanity check: this node better be mutable! */ if (! svn_fs_x__dag_check_mutable(node)) { - svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); + svn_string_t *idstr + = svn_fs_x__id_unparse(&node->node_revision->noderev_id, + scratch_pool); return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Can't set mergeinfo flag on *immutable* node-revision %s", idstr->data); } - /* Go get a fresh NODE-REVISION for this node. */ - SVN_ERR(get_node_revision(&noderev, node)); - - noderev->has_mergeinfo = has_mergeinfo; + node->node_revision->has_mergeinfo = has_mergeinfo; /* Flush it out. */ - return svn_fs_x__put_node_revision(node->fs, noderev, scratch_pool); + return noderev_changed(node, scratch_pool); } /*** Roots. ***/ svn_error_t * -svn_fs_x__dag_revision_root(dag_node_t **node_p, - svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_fs_x__id_t root_id; - - svn_fs_x__init_rev_root(&root_id, rev); - return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool, - scratch_pool); -} - - -svn_error_t * -svn_fs_x__dag_txn_root(dag_node_t **node_p, - svn_fs_t *fs, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +svn_fs_x__dag_root(dag_node_t **node_p, + svn_fs_t *fs, + svn_fs_x__change_set_t change_set, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { svn_fs_x__id_t root_id; + root_id.change_set = change_set; + root_id.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE; - svn_fs_x__init_txn_root(&root_id, txn_id); return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool, scratch_pool); } @@ -734,14 +602,11 @@ svn_fs_x__dag_clone_child(dag_node_t **child_p, } else { - svn_fs_x__noderev_t *noderev, *parent_noderev; - - /* Go get a fresh NODE-REVISION for current child node. */ - SVN_ERR(get_node_revision(&noderev, cur_entry)); + svn_fs_x__noderev_t *noderev = cur_entry->node_revision; if (is_parent_copyroot) { - SVN_ERR(get_node_revision(&parent_noderev, parent)); + svn_fs_x__noderev_t *parent_noderev = parent->node_revision; noderev->copyroot_rev = parent_noderev->copyroot_rev; noderev->copyroot_path = apr_pstrdup(scratch_pool, parent_noderev->copyroot_path); @@ -796,7 +661,7 @@ delete_if_mutable(svn_fs_t *fs, return SVN_NO_ERROR; /* Else it's mutable. Recurse on directories... */ - if (node->kind == svn_node_dir) + if (node->node_revision->kind == svn_node_dir) { apr_array_header_t *entries; int i; @@ -829,13 +694,13 @@ svn_fs_x__dag_delete(dag_node_t *parent, svn_fs_x__txn_id_t txn_id, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *parent_noderev; + svn_fs_x__noderev_t *parent_noderev = parent->node_revision; svn_fs_t *fs = parent->fs; svn_fs_x__dirent_t *dirent; apr_pool_t *subpool; /* Make sure parent is a directory. */ - if (parent->kind != svn_node_dir) + if (parent_noderev->kind != svn_node_dir) return svn_error_createf (SVN_ERR_FS_NOT_DIRECTORY, NULL, "Attempted to delete entry '%s' from *non*-directory node", name); @@ -852,9 +717,9 @@ svn_fs_x__dag_delete(dag_node_t *parent, (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL, "Attempted to delete a node with an illegal name '%s'", name); - /* Get a fresh NODE-REVISION for the parent node. */ - SVN_ERR(get_node_revision(&parent_noderev, parent)); - + /* We allocate a few potentially heavy temporary objects (file buffers + and directories). Make sure we don't keep them around for longer + than necessary. */ subpool = svn_pool_create(scratch_pool); /* Search this directory for a dirent with that NAME. */ @@ -871,13 +736,13 @@ svn_fs_x__dag_delete(dag_node_t *parent, "Delete failed--directory has no entry '%s'", name); /* If mutable, remove it and any mutable children from db. */ - SVN_ERR(delete_if_mutable(parent->fs, &dirent->id, scratch_pool)); - svn_pool_destroy(subpool); + SVN_ERR(delete_if_mutable(parent->fs, &dirent->id, subpool)); /* Remove this entry from its parent's entries list. */ - return svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name, - NULL, svn_node_unknown, parent->node_pool, - scratch_pool); + SVN_ERR(set_entry(parent, name, NULL, svn_node_unknown, txn_id, subpool)); + + svn_pool_destroy(subpool); + return SVN_NO_ERROR; } @@ -916,23 +781,16 @@ svn_fs_x__dag_get_contents(svn_stream_t **contents_p, dag_node_t *file, apr_pool_t *result_pool) { - svn_fs_x__noderev_t *noderev; - svn_stream_t *contents; - /* Make sure our node is a file. */ - if (file->kind != svn_node_file) + if (file->node_revision->kind != svn_node_file) return svn_error_createf (SVN_ERR_FS_NOT_FILE, NULL, "Attempted to get textual contents of a *non*-file node"); - /* Go get a fresh node-revision for FILE. */ - SVN_ERR(get_node_revision(&noderev, file)); - /* Get a stream to the contents. */ - SVN_ERR(svn_fs_x__get_contents(&contents, file->fs, - noderev->data_rep, TRUE, result_pool)); - - *contents_p = contents; + SVN_ERR(svn_fs_x__get_contents(contents_p, file->fs, + file->node_revision->data_rep, TRUE, + result_pool)); return SVN_NO_ERROR; } @@ -945,23 +803,16 @@ svn_fs_x__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *src_noderev; - svn_fs_x__noderev_t *tgt_noderev; + svn_fs_x__noderev_t *src_noderev = source ? source->node_revision : NULL; + svn_fs_x__noderev_t *tgt_noderev = target->node_revision; /* Make sure our nodes are files. */ - if ((source && source->kind != svn_node_file) - || target->kind != svn_node_file) + if ((source && src_noderev->kind != svn_node_file) + || tgt_noderev->kind != svn_node_file) return svn_error_createf (SVN_ERR_FS_NOT_FILE, NULL, "Attempted to get textual contents of a *non*-file node"); - /* Go get fresh node-revisions for the nodes. */ - if (source) - SVN_ERR(get_node_revision(&src_noderev, source)); - else - src_noderev = NULL; - SVN_ERR(get_node_revision(&tgt_noderev, target)); - /* Get the delta stream. */ return svn_fs_x__get_file_delta_stream(stream_p, target->fs, src_noderev, tgt_noderev, @@ -976,13 +827,8 @@ svn_fs_x__dag_try_process_file_contents(svn_boolean_t *success, void* baton, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *noderev; - - /* Go get fresh node-revisions for the nodes. */ - SVN_ERR(get_node_revision(&noderev, node)); - return svn_fs_x__try_process_file_contents(success, node->fs, - noderev, + node->node_revision, processor, baton, scratch_pool); } @@ -991,18 +837,13 @@ svn_error_t * svn_fs_x__dag_file_length(svn_filesize_t *length, dag_node_t *file) { - svn_fs_x__noderev_t *noderev; - /* Make sure our node is a file. */ - if (file->kind != svn_node_file) + if (file->node_revision->kind != svn_node_file) return svn_error_createf (SVN_ERR_FS_NOT_FILE, NULL, "Attempted to get length of a *non*-file node"); - /* Go get a fresh node-revision for FILE, and . */ - SVN_ERR(get_node_revision(&noderev, file)); - - return svn_fs_x__file_length(length, noderev); + return svn_fs_x__file_length(length, file->node_revision); } @@ -1012,16 +853,13 @@ svn_fs_x__dag_file_checksum(svn_checksum_t **checksum, svn_checksum_kind_t kind, apr_pool_t *result_pool) { - svn_fs_x__noderev_t *noderev; - - if (file->kind != svn_node_file) + if (file->node_revision->kind != svn_node_file) return svn_error_createf (SVN_ERR_FS_NOT_FILE, NULL, "Attempted to get checksum of a *non*-file node"); - SVN_ERR(get_node_revision(&noderev, file)); - - return svn_fs_x__file_checksum(checksum, noderev, kind, result_pool); + return svn_fs_x__file_checksum(checksum, file->node_revision, kind, + result_pool); } @@ -1030,11 +868,8 @@ svn_fs_x__dag_get_edit_stream(svn_stream_t **contents, dag_node_t *file, apr_pool_t *result_pool) { - svn_fs_x__noderev_t *noderev; - svn_stream_t *ws; - /* Make sure our node is a file. */ - if (file->kind != svn_node_file) + if (file->node_revision->kind != svn_node_file) return svn_error_createf (SVN_ERR_FS_NOT_FILE, NULL, "Attempted to set textual contents of a *non*-file node"); @@ -1045,13 +880,8 @@ svn_fs_x__dag_get_edit_stream(svn_stream_t **contents, (SVN_ERR_FS_NOT_MUTABLE, NULL, "Attempted to set textual contents of an immutable node"); - /* Get the node revision. */ - SVN_ERR(get_node_revision(&noderev, file)); - - SVN_ERR(svn_fs_x__set_contents(&ws, file->fs, noderev, result_pool)); - - *contents = ws; - + SVN_ERR(svn_fs_x__set_contents(contents, file->fs, file->node_revision, + result_pool)); return SVN_NO_ERROR; } @@ -1072,9 +902,10 @@ svn_fs_x__dag_finalize_edits(dag_node_t *file, return svn_checksum_mismatch_err(checksum, file_checksum, scratch_pool, _("Checksum mismatch for '%s'"), - file->created_path); + file->node_revision->created_path); } + svn_fs_x__update_dag_cache(file); return SVN_NO_ERROR; } @@ -1086,101 +917,14 @@ svn_fs_x__dag_dup(const dag_node_t *node, /* Allocate our new node. */ dag_node_t *new_node = apr_pmemdup(result_pool, node, sizeof(*new_node)); - /* Only copy cached svn_fs_x__noderev_t for immutable nodes. */ - if (node->node_revision && !svn_fs_x__dag_check_mutable(node)) - { - new_node->node_revision = copy_node_revision(node->node_revision, - result_pool); - new_node->created_path = new_node->node_revision->created_path; - } - else - { - new_node->node_revision = NULL; - new_node->created_path = apr_pstrdup(result_pool, node->created_path); - } - + /* Copy sub-structures. */ + new_node->node_revision = copy_node_revision(node->node_revision, + result_pool); new_node->node_pool = result_pool; return new_node; } -dag_node_t * -svn_fs_x__dag_copy_into_pool(dag_node_t *node, - apr_pool_t *result_pool) -{ - return (node->node_pool == result_pool - ? node - : svn_fs_x__dag_dup(node, result_pool)); -} - -svn_error_t * -svn_fs_x__dag_serialize(void **data, - apr_size_t *data_len, - void *in, - apr_pool_t *pool) -{ - dag_node_t *node = in; - svn_stringbuf_t *serialized; - - /* create an serialization context and serialize the dag node as root */ - svn_temp_serializer__context_t *context = - svn_temp_serializer__init(node, - sizeof(*node), - 1024 - SVN_TEMP_SERIALIZER__OVERHEAD, - pool); - - /* for mutable nodes, we will _never_ cache the noderev */ - if (node->node_revision && !svn_fs_x__dag_check_mutable(node)) - { - svn_fs_x__noderev_serialize(context, &node->node_revision); - } - else - { - svn_temp_serializer__set_null(context, - (const void * const *)&node->node_revision); - svn_temp_serializer__add_string(context, &node->created_path); - } - - /* The deserializer will use its own pool. */ - svn_temp_serializer__set_null(context, - (const void * const *)&node->node_pool); - - /* return serialized data */ - serialized = svn_temp_serializer__get(context); - *data = serialized->data; - *data_len = serialized->len; - - return SVN_NO_ERROR; -} - -svn_error_t * -svn_fs_x__dag_deserialize(void **out, - void *data, - apr_size_t data_len, - apr_pool_t *pool) -{ - dag_node_t *node = (dag_node_t *)data; - if (data_len == 0) - return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, - _("Empty noderev in cache")); - - /* Copy the _full_ buffer as it also contains the sub-structures. */ - node->fs = NULL; - - /* fixup all references to sub-structures */ - svn_fs_x__noderev_deserialize(node, &node->node_revision, pool); - node->node_pool = pool; - - if (node->node_revision) - node->created_path = node->node_revision->created_path; - else - svn_temp_deserializer__resolve(node, (void**)&node->created_path); - - /* return result */ - *out = node; - - return SVN_NO_ERROR; -} svn_error_t * svn_fs_x__dag_open(dag_node_t **child_p, @@ -1192,7 +936,7 @@ svn_fs_x__dag_open(dag_node_t **child_p, svn_fs_x__id_t node_id; /* Ensure that NAME exists in PARENT's entry list. */ - SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, scratch_pool)); + SVN_ERR(svn_fs_x__dir_entry_id(&node_id, parent, name, scratch_pool)); if (! svn_fs_x__id_used(&node_id)) { *child_p = NULL; @@ -1219,13 +963,12 @@ svn_fs_x__dag_copy(dag_node_t *to_node, if (preserve_history) { - svn_fs_x__noderev_t *from_noderev, *to_noderev; + svn_fs_x__noderev_t *to_noderev; svn_fs_x__id_t copy_id; svn_fs_t *fs = svn_fs_x__dag_get_fs(from_node); /* Make a copy of the original node revision. */ - SVN_ERR(get_node_revision(&from_noderev, from_node)); - to_noderev = copy_node_revision(from_noderev, scratch_pool); + to_noderev = copy_node_revision(from_node->node_revision, scratch_pool); /* Reserve a copy ID for this new copy. */ SVN_ERR(svn_fs_x__reserve_copy_id(©_id, fs, txn_id, scratch_pool)); @@ -1253,7 +996,8 @@ svn_fs_x__dag_copy(dag_node_t *to_node, } /* Set the entry in to_node to the new id. */ - return svn_fs_x__dag_set_entry(to_node, entry, id, from_node->kind, + return svn_fs_x__dag_set_entry(to_node, entry, id, + from_node->node_revision->kind, txn_id, scratch_pool); } @@ -1269,7 +1013,8 @@ svn_fs_x__dag_things_different(svn_boolean_t *props_changed, svn_boolean_t strict, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *noderev1, *noderev2; + svn_fs_x__noderev_t *noderev1 = node1->node_revision; + svn_fs_x__noderev_t *noderev2 = node2->node_revision; svn_fs_t *fs; svn_boolean_t same; @@ -1280,10 +1025,6 @@ svn_fs_x__dag_things_different(svn_boolean_t *props_changed, fs = svn_fs_x__dag_get_fs(node1); - /* The node revision skels for these two nodes. */ - SVN_ERR(get_node_revision(&noderev1, node1)); - SVN_ERR(get_node_revision(&noderev2, node2)); - /* Compare property keys. */ if (props_changed != NULL) { @@ -1300,48 +1041,25 @@ svn_fs_x__dag_things_different(svn_boolean_t *props_changed, return SVN_NO_ERROR; } -svn_error_t * +void svn_fs_x__dag_get_copyroot(svn_revnum_t *rev, const char **path, dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - - /* Go get a fresh node-revision for NODE. */ - SVN_ERR(get_node_revision(&noderev, node)); - - *rev = noderev->copyroot_rev; - *path = noderev->copyroot_path; - - return SVN_NO_ERROR; + *rev = node->node_revision->copyroot_rev; + *path = node->node_revision->copyroot_path; } -svn_error_t * -svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev, - dag_node_t *node) +svn_revnum_t +svn_fs_x__dag_get_copyfrom_rev(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - - /* Go get a fresh node-revision for NODE. */ - SVN_ERR(get_node_revision(&noderev, node)); - - *rev = noderev->copyfrom_rev; - - return SVN_NO_ERROR; + return node->node_revision->copyfrom_rev; } -svn_error_t * -svn_fs_x__dag_get_copyfrom_path(const char **path, - dag_node_t *node) +const char * +svn_fs_x__dag_get_copyfrom_path(dag_node_t *node) { - svn_fs_x__noderev_t *noderev; - - /* Go get a fresh node-revision for NODE. */ - SVN_ERR(get_node_revision(&noderev, node)); - - *path = noderev->copyfrom_path; - - return SVN_NO_ERROR; + return node->node_revision->copyfrom_path; } svn_error_t * @@ -1349,20 +1067,17 @@ svn_fs_x__dag_update_ancestry(dag_node_t *target, dag_node_t *source, apr_pool_t *scratch_pool) { - svn_fs_x__noderev_t *source_noderev, *target_noderev; + svn_fs_x__noderev_t *source_noderev = source->node_revision; + svn_fs_x__noderev_t *target_noderev = target->node_revision; if (! svn_fs_x__dag_check_mutable(target)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to update ancestry of non-mutable node")); - SVN_ERR(get_node_revision(&source_noderev, source)); - SVN_ERR(get_node_revision(&target_noderev, target)); - target_noderev->predecessor_id = source_noderev->noderev_id; target_noderev->predecessor_count = source_noderev->predecessor_count; target_noderev->predecessor_count++; - return svn_fs_x__put_node_revision(target->fs, target_noderev, - scratch_pool); + return noderev_changed(target, scratch_pool); } |