Modified: subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.c?rev=1653578&r1=1653577&r2=1653578&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.c (original) +++ subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.c Wed Jan 21 16:22:19 2015 @@ -31,7 +31,7 @@ #include "dag.h" #include "fs.h" #include "fs_x.h" -#include "id.h" +#include "fs_id.h" #include "cached_data.h" #include "transaction.h" @@ -50,14 +50,15 @@ struct dag_node_t /* The filesystem this dag node came from. */ svn_fs_t *fs; - /* The node revision ID for this dag node, allocated in POOL. */ - svn_fs_id_t *id; + /* 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 node revision ID for this dag - node's predecessor; otherwise NULL. (Used in - svn_fs_node_created_rev.) */ - const svn_fs_id_t *fresh_root_predecessor_id; + 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; @@ -69,28 +70,33 @@ struct dag_node_t this yourself, but you're probably better off just calling `get_node_revision' and `set_node_revision', which take care of things for you. */ - node_revision_t *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. */ + apr_size_t hint; }; /* Trivial helper/accessor functions. */ -svn_node_kind_t svn_fs_x__dag_node_kind(dag_node_t *node) +svn_node_kind_t +svn_fs_x__dag_node_kind(dag_node_t *node) { return node->kind; } - -const svn_fs_id_t * +const svn_fs_x__id_t * svn_fs_x__dag_get_id(const dag_node_t *node) { - return node->id; + return &node->id; } @@ -108,35 +114,32 @@ svn_fs_x__dag_get_fs(dag_node_t *node) } void -svn_fs_x__dag_set_fs(dag_node_t *node, svn_fs_t *fs) +svn_fs_x__dag_set_fs(dag_node_t *node, + svn_fs_t *fs) { node->fs = fs; } -/* Dup NODEREV and all associated data into POOL. +/* Dup NODEREV and all associated data into RESULT_POOL. Leaves the id and is_fresh_txn_root fields as zero bytes. */ -static node_revision_t * -copy_node_revision(node_revision_t *noderev, - apr_pool_t *pool) -{ - node_revision_t *nr = apr_pcalloc(pool, sizeof(*nr)); - nr->kind = noderev->kind; - if (noderev->predecessor_id) - nr->predecessor_id = svn_fs_x__id_copy(noderev->predecessor_id, pool); - nr->predecessor_count = noderev->predecessor_count; +static svn_fs_x__noderev_t * +copy_node_revision(svn_fs_x__noderev_t *noderev, + apr_pool_t *result_pool) +{ + svn_fs_x__noderev_t *nr = apr_pmemdup(result_pool, noderev, + sizeof(*noderev)); + if (noderev->copyfrom_path) - nr->copyfrom_path = apr_pstrdup(pool, noderev->copyfrom_path); - nr->copyfrom_rev = noderev->copyfrom_rev; - nr->copyroot_path = apr_pstrdup(pool, noderev->copyroot_path); - nr->copyroot_rev = noderev->copyroot_rev; - nr->data_rep = svn_fs_x__rep_copy(noderev->data_rep, pool); - nr->prop_rep = svn_fs_x__rep_copy(noderev->prop_rep, pool); - nr->mergeinfo_count = noderev->mergeinfo_count; - nr->has_mergeinfo = noderev->has_mergeinfo; + nr->copyfrom_path = apr_pstrdup(result_pool, noderev->copyfrom_path); + + nr->copyroot_path = apr_pstrdup(result_pool, noderev->copyroot_path); + nr->data_rep = svn_fs_x__rep_copy(noderev->data_rep, result_pool); + nr->prop_rep = svn_fs_x__rep_copy(noderev->prop_rep, result_pool); if (noderev->created_path) - nr->created_path = apr_pstrdup(pool, noderev->created_path); + nr->created_path = apr_pstrdup(result_pool, noderev->created_path); + return nr; } @@ -153,18 +156,17 @@ copy_node_revision(node_revision_t *node changes that never got committed. It's probably best not to change the structure at all. */ static svn_error_t * -get_node_revision(node_revision_t **noderev_p, +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) { - node_revision_t *noderev; + 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)); + 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); } @@ -174,39 +176,100 @@ get_node_revision(node_revision_t **node 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) +{ + svn_fs_x__noderev_t *noderev; + SVN_ERR(get_node_revision(&noderev, node)); + + *node_id = noderev->node_id; + return SVN_NO_ERROR; +} -svn_boolean_t svn_fs_x__dag_check_mutable(const dag_node_t *node) +/* 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) { - return svn_fs_x__id_is_txn(svn_fs_x__dag_get_id(node)); + svn_fs_x__noderev_t *noderev; + SVN_ERR(get_node_revision(&noderev, node)); + + *copy_id = noderev->copy_id; + return SVN_NO_ERROR; +} + +/* 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, + 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; +} + +svn_error_t * +svn_fs_x__dag_same_line_of_history(svn_boolean_t *same, + dag_node_t *lhs, + dag_node_t *rhs) +{ + svn_fs_x__noderev_t *lhs_noderev, *rhs_noderev; + + 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; +} + +svn_boolean_t +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, - const svn_fs_id_t *id, - apr_pool_t *pool) + const svn_fs_x__id_t *id, + apr_pool_t *result_pool) { dag_node_t *new_node; - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; /* Construct the node. */ - new_node = apr_pcalloc(pool, sizeof(*new_node)); + new_node = apr_pcalloc(result_pool, sizeof(*new_node)); new_node->fs = fs; - new_node->id = svn_fs_x__id_copy(id, pool); + new_node->id = *id; + new_node->hint = APR_SIZE_MAX; /* Grab the contents so we can inspect the node's kind and created path. */ - new_node->node_pool = pool; + new_node->node_pool = result_pool; SVN_ERR(get_node_revision(&noderev, new_node)); /* Initialize the KIND and CREATED_PATH attributes */ new_node->kind = noderev->kind; - new_node->created_path = apr_pstrdup(pool, noderev->created_path); + new_node->created_path = apr_pstrdup(result_pool, noderev->created_path); - if (noderev->is_fresh_txn_root) - new_node->fresh_root_predecessor_id = noderev->predecessor_id; - else - new_node->fresh_root_predecessor_id = NULL; + /* Support our quirky svn_fs_node_created_rev API. + Untouched txn roots report the base rev as theirs. */ + new_node->revision + = ( noderev->is_fresh_txn_root + ? 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; @@ -214,32 +277,22 @@ svn_fs_x__dag_get_node(dag_node_t **node } -svn_error_t * -svn_fs_x__dag_get_revision(svn_revnum_t *rev, - dag_node_t *node, - apr_pool_t *pool) +svn_revnum_t +svn_fs_x__dag_get_revision(const dag_node_t *node) { - /* In the special case that this is an unmodified transaction root, - we need to actually get the revision of the noderev's predecessor - (the revision root); see Issue #2608. */ - const svn_fs_id_t *correct_id = node->fresh_root_predecessor_id - ? node->fresh_root_predecessor_id : node->id; - - /* Look up the committed revision from the Node-ID. */ - *rev = svn_fs_x__id_rev(correct_id); - - return SVN_NO_ERROR; + return node->revision; } svn_error_t * -svn_fs_x__dag_get_predecessor_id(const svn_fs_id_t **id_p, +svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; SVN_ERR(get_node_revision(&noderev, node)); *id_p = noderev->predecessor_id; + return SVN_NO_ERROR; } @@ -248,7 +301,7 @@ svn_error_t * svn_fs_x__dag_get_predecessor_count(int *count, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; SVN_ERR(get_node_revision(&noderev, node)); *count = noderev->predecessor_count; @@ -259,7 +312,7 @@ svn_error_t * svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; SVN_ERR(get_node_revision(&noderev, node)); *count = noderev->mergeinfo_count; @@ -270,7 +323,7 @@ svn_error_t * svn_fs_x__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; SVN_ERR(get_node_revision(&noderev, node)); *has_mergeinfo = noderev->has_mergeinfo; @@ -281,7 +334,7 @@ svn_error_t * svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; if (node->kind != svn_node_dir) { @@ -304,28 +357,37 @@ svn_fs_x__dag_has_descendants_with_merge /* Some of these are helpers for functions outside this section. */ -/* Set *ID_P to the node-id for entry NAME in PARENT. If no such - entry, set *ID_P to NULL but do not error. The node-id is - allocated in POOL. */ +/* 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(const svn_fs_id_t **id_p, +dir_entry_id_from_node(svn_fs_x__id_t *id_p, dag_node_t *parent, const char *name, - apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - svn_fs_dirent_t *dirent; + svn_fs_x__dirent_t *dirent; + svn_fs_x__noderev_t *noderev; + + 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")); - SVN_ERR(svn_fs_x__dag_dir_entry(&dirent, parent, name, result_pool, - scratch_pool)); - *id_p = dirent ? dirent->id : NULL; + /* Get a dirent hash for this directory. */ + SVN_ERR(svn_fs_x__rep_contents_dir_entry(&dirent, parent->fs, noderev, + name, &parent->hint, + scratch_pool, scratch_pool)); + if (dirent) + *id_p = dirent->id; + else + svn_fs_x__id_reset(id_p); return SVN_NO_ERROR; } /* Add or set in PARENT a directory entry NAME pointing to ID. - Allocations are done in POOL. + Temporary allocations are done in SCRATCH_POOL. Assumptions: - PARENT is a mutable directory. @@ -335,28 +397,28 @@ dir_entry_id_from_node(const svn_fs_id_t static svn_error_t * set_entry(dag_node_t *parent, const char *name, - const svn_fs_id_t *id, + const svn_fs_x__id_t *id, svn_node_kind_t kind, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - node_revision_t *parent_noderev; + svn_fs_x__noderev_t *parent_noderev; /* Get the parent's node-revision. */ SVN_ERR(get_node_revision(&parent_noderev, parent)); /* Set the new entry. */ return svn_fs_x__set_entry(parent->fs, txn_id, parent_noderev, name, id, - kind, pool); + kind, parent->node_pool, scratch_pool); } /* Make a new entry named NAME in PARENT. If IS_DIR is true, then the node revision the new entry points to will be a directory, else it - will be a file. The new node will be allocated in POOL. PARENT + will be a file. The new node will be allocated in RESULT_POOL. PARENT must be mutable, and must not have an entry named NAME. - Use POOL for all allocations, except caching the node_revision in PARENT. + Use SCRATCH_POOL for all temporary allocations. */ static svn_error_t * make_entry(dag_node_t **child_p, @@ -365,10 +427,10 @@ make_entry(dag_node_t **child_p, const char *name, svn_boolean_t is_dir, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - const svn_fs_id_t *new_node_id; - node_revision_t new_noderev, *parent_noderev; + svn_fs_x__noderev_t new_noderev, *parent_noderev; /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) @@ -391,38 +453,39 @@ make_entry(dag_node_t **child_p, /* Create the new node's NODE-REVISION */ memset(&new_noderev, 0, sizeof(new_noderev)); new_noderev.kind = is_dir ? svn_node_dir : svn_node_file; - new_noderev.created_path = svn_fspath__join(parent_path, name, pool); + 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(pool, + new_noderev.copyroot_path = apr_pstrdup(result_pool, parent_noderev->copyroot_path); new_noderev.copyroot_rev = parent_noderev->copyroot_rev; new_noderev.copyfrom_rev = SVN_INVALID_REVNUM; new_noderev.copyfrom_path = NULL; + svn_fs_x__id_reset(&new_noderev.predecessor_id); SVN_ERR(svn_fs_x__create_node - (&new_node_id, svn_fs_x__dag_get_fs(parent), &new_noderev, - svn_fs_x__id_copy_id(svn_fs_x__dag_get_id(parent)), - txn_id, pool)); + (svn_fs_x__dag_get_fs(parent), &new_noderev, + &parent_noderev->copy_id, txn_id, scratch_pool)); /* Create a new dag_node_t for our new node */ SVN_ERR(svn_fs_x__dag_get_node(child_p, svn_fs_x__dag_get_fs(parent), - new_node_id, pool)); + &new_noderev.noderev_id, result_pool)); /* We can safely call set_entry because we already know that PARENT is mutable, and we just created CHILD, so we know it has no ancestors (therefore, PARENT cannot be an ancestor of CHILD) */ - return set_entry(parent, name, svn_fs_x__dag_get_id(*child_p), - new_noderev.kind, txn_id, pool); + return set_entry(parent, name, &new_noderev.noderev_id, + new_noderev.kind, txn_id, scratch_pool); } svn_error_t * svn_fs_x__dag_dir_entries(apr_array_header_t **entries, dag_node_t *node, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; SVN_ERR(get_node_revision(&noderev, node)); @@ -430,36 +493,18 @@ svn_fs_x__dag_dir_entries(apr_array_head return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL, _("Can't get entries of non-directory")); - return svn_fs_x__rep_contents_dir(entries, node->fs, noderev, pool, pool); -} - -svn_error_t * -svn_fs_x__dag_dir_entry(svn_fs_dirent_t **dirent, - dag_node_t *node, - const char* name, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - node_revision_t *noderev; - SVN_ERR(get_node_revision(&noderev, node)); - - if (noderev->kind != svn_node_dir) - return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL, - _("Can't get entries of non-directory")); - - /* Get a dirent hash for this directory. */ - return svn_fs_x__rep_contents_dir_entry(dirent, node->fs, noderev, name, - result_pool, scratch_pool); + return svn_fs_x__rep_contents_dir(entries, node->fs, noderev, result_pool, + scratch_pool); } svn_error_t * svn_fs_x__dag_set_entry(dag_node_t *node, const char *entry_name, - const svn_fs_id_t *id, + const svn_fs_x__id_t *id, svn_node_kind_t kind, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { /* Check it's a directory. */ if (node->kind != svn_node_dir) @@ -473,7 +518,7 @@ svn_fs_x__dag_set_entry(dag_node_t *node (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to set entry in immutable node")); - return set_entry(node, entry_name, id, kind, txn_id, pool); + return set_entry(node, entry_name, id, kind, txn_id, scratch_pool); } @@ -483,14 +528,16 @@ svn_fs_x__dag_set_entry(dag_node_t *node svn_error_t * svn_fs_x__dag_get_proplist(apr_hash_t **proplist_p, dag_node_t *node, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - node_revision_t *noderev; + 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, pool)); + SVN_ERR(svn_fs_x__get_proplist(&proplist, node->fs, noderev, result_pool, + scratch_pool)); *proplist_p = proplist; @@ -501,14 +548,14 @@ svn_fs_x__dag_get_proplist(apr_hash_t ** svn_error_t * svn_fs_x__dag_set_proplist(dag_node_t *node, apr_hash_t *proplist, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - node_revision_t *noderev; + 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, pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Can't set proplist on *immutable* node-revision %s", @@ -519,21 +566,21 @@ svn_fs_x__dag_set_proplist(dag_node_t *n SVN_ERR(get_node_revision(&noderev, node)); /* Set the new proplist. */ - return svn_fs_x__set_proplist(node->fs, noderev, proplist, pool); + return svn_fs_x__set_proplist(node->fs, noderev, proplist, scratch_pool); } svn_error_t * svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node, apr_int64_t increment, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - node_revision_t *noderev; + 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, pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Can't increment mergeinfo count on *immutable* node-revision %s", @@ -549,10 +596,10 @@ svn_fs_x__dag_increment_mergeinfo_count( noderev->mergeinfo_count += increment; if (noderev->mergeinfo_count < 0) { - svn_string_t *idstr = svn_fs_x__id_unparse(node->id, pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); return svn_error_createf (SVN_ERR_FS_CORRUPT, NULL, - apr_psprintf(pool, + apr_psprintf(scratch_pool, _("Can't increment mergeinfo count on node-revision %%s " "to negative value %%%s"), APR_INT64_T_FMT), @@ -560,10 +607,10 @@ svn_fs_x__dag_increment_mergeinfo_count( } if (noderev->mergeinfo_count > 1 && noderev->kind == svn_node_file) { - svn_string_t *idstr = svn_fs_x__id_unparse(node->id, pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); return svn_error_createf (SVN_ERR_FS_CORRUPT, NULL, - apr_psprintf(pool, + apr_psprintf(scratch_pool, _("Can't increment mergeinfo count on *file* " "node-revision %%s to %%%s (> 1)"), APR_INT64_T_FMT), @@ -571,21 +618,20 @@ svn_fs_x__dag_increment_mergeinfo_count( } /* Flush it out. */ - return svn_fs_x__put_node_revision(node->fs, noderev->id, - noderev, FALSE, pool); + return svn_fs_x__put_node_revision(node->fs, noderev, FALSE, scratch_pool); } svn_error_t * svn_fs_x__dag_set_has_mergeinfo(dag_node_t *node, - svn_boolean_t has_mergeinfo, - apr_pool_t *pool) + svn_boolean_t has_mergeinfo, + apr_pool_t *scratch_pool) { - node_revision_t *noderev; + 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, pool); + svn_string_t *idstr = svn_fs_x__id_unparse(&node->id, scratch_pool); return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, "Can't set mergeinfo flag on *immutable* node-revision %s", @@ -598,8 +644,7 @@ svn_fs_x__dag_set_has_mergeinfo(dag_node noderev->has_mergeinfo = has_mergeinfo; /* Flush it out. */ - return svn_fs_x__put_node_revision(node->fs, noderev->id, - noderev, FALSE, pool); + return svn_fs_x__put_node_revision(node->fs, noderev, FALSE, scratch_pool); } @@ -609,22 +654,23 @@ 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 *pool) + apr_pool_t *result_pool) { dag_node_t *new_node; /* Construct the node. */ - new_node = apr_pcalloc(pool, sizeof(*new_node)); + new_node = apr_pcalloc(result_pool, sizeof(*new_node)); new_node->fs = fs; - SVN_ERR(svn_fs_x__rev_get_root(&new_node->id, fs, rev, pool, pool)); + new_node->revision = rev; + svn_fs_x__init_rev_root(&new_node->id, rev); /* Grab the contents so we can inspect the node's kind and created path. */ - new_node->node_pool = pool; + new_node->node_pool = result_pool; /* Initialize the KIND and CREATED_PATH attributes */ new_node->kind = svn_node_dir; new_node->created_path = "/"; - new_node->fresh_root_predecessor_id = NULL; + new_node->hint = APR_SIZE_MAX; /* Return a fresh new node */ *node_p = new_node; @@ -636,12 +682,12 @@ 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 *pool) + apr_pool_t *result_pool) { - const svn_fs_id_t *root_id, *ignored; + svn_fs_x__id_t root_id; - SVN_ERR(svn_fs_x__get_txn_ids(&root_id, &ignored, fs, txn_id, pool)); - return svn_fs_x__dag_get_node(node_p, fs, root_id, pool); + svn_fs_x__init_txn_root(&root_id, txn_id); + return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool); } @@ -649,12 +695,16 @@ svn_error_t * svn_fs_x__dag_txn_base_root(dag_node_t **node_p, svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - const svn_fs_id_t *base_root_id, *ignored; + svn_fs_x__id_t base_root_id; + svn_revnum_t base_rev; + + SVN_ERR(svn_fs_x__get_base_rev(&base_rev, fs, txn_id, scratch_pool)); - SVN_ERR(svn_fs_x__get_txn_ids(&ignored, &base_root_id, fs, txn_id, pool)); - return svn_fs_x__dag_get_node(node_p, fs, base_root_id, pool); + svn_fs_x__init_rev_root(&base_root_id, base_rev); + return svn_fs_x__dag_get_node(node_p, fs, &base_root_id, result_pool); } @@ -663,15 +713,15 @@ svn_fs_x__dag_clone_child(dag_node_t **c dag_node_t *parent, const char *parent_path, const char *name, - const svn_fs_x__id_part_t *copy_id, + const svn_fs_x__id_t *copy_id, svn_fs_x__txn_id_t txn_id, svn_boolean_t is_parent_copyroot, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { dag_node_t *cur_entry; /* parent's current entry named NAME */ - const svn_fs_id_t *new_node_id; /* node id we'll put into NEW_NODE */ + const svn_fs_x__id_t *new_node_id; /* node id we'll put into NEW_NODE */ svn_fs_t *fs = svn_fs_x__dag_get_fs(parent); - apr_pool_t *subpool = svn_pool_create(pool); /* First check that the parent is mutable. */ if (! svn_fs_x__dag_check_mutable(parent)) @@ -686,7 +736,8 @@ svn_fs_x__dag_clone_child(dag_node_t **c "Attempted to make a child clone with an illegal name '%s'", name); /* Find the node named NAME in PARENT's entries list if it exists. */ - SVN_ERR(svn_fs_x__dag_open(&cur_entry, parent, name, pool, subpool)); + SVN_ERR(svn_fs_x__dag_open(&cur_entry, parent, name, scratch_pool, + scratch_pool)); if (! cur_entry) return svn_error_createf (SVN_ERR_FS_NOT_FOUND, NULL, @@ -697,11 +748,11 @@ svn_fs_x__dag_clone_child(dag_node_t **c if (svn_fs_x__dag_check_mutable(cur_entry)) { /* This has already been cloned */ - new_node_id = cur_entry->id; + new_node_id = svn_fs_x__dag_get_id(cur_entry); } else { - node_revision_t *noderev, *parent_noderev; + 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)); @@ -710,30 +761,33 @@ svn_fs_x__dag_clone_child(dag_node_t **c { SVN_ERR(get_node_revision(&parent_noderev, parent)); noderev->copyroot_rev = parent_noderev->copyroot_rev; - noderev->copyroot_path = apr_pstrdup(pool, + noderev->copyroot_path = apr_pstrdup(scratch_pool, parent_noderev->copyroot_path); } noderev->copyfrom_path = NULL; noderev->copyfrom_rev = SVN_INVALID_REVNUM; - noderev->predecessor_id = svn_fs_x__id_copy(cur_entry->id, pool); - if (noderev->predecessor_count != -1) - noderev->predecessor_count++; - noderev->created_path = svn_fspath__join(parent_path, name, pool); - - SVN_ERR(svn_fs_x__create_successor(&new_node_id, fs, cur_entry->id, - noderev, copy_id, txn_id, pool)); + noderev->predecessor_id = noderev->noderev_id; + noderev->predecessor_count++; + noderev->created_path = svn_fspath__join(parent_path, name, + scratch_pool); + + if (copy_id == NULL) + copy_id = &noderev->copy_id; + + SVN_ERR(svn_fs_x__create_successor(fs, noderev, copy_id, txn_id, + scratch_pool)); + new_node_id = &noderev->noderev_id; /* Replace the ID in the parent's ENTRY list with the ID which refers to the mutable clone of this child. */ SVN_ERR(set_entry(parent, name, new_node_id, noderev->kind, txn_id, - pool)); + scratch_pool)); } /* Initialize the youngster. */ - svn_pool_destroy(subpool); - return svn_fs_x__dag_get_node(child_p, fs, new_node_id, pool); + return svn_fs_x__dag_get_node(child_p, fs, new_node_id, result_pool); } @@ -742,26 +796,62 @@ svn_error_t * svn_fs_x__dag_clone_root(dag_node_t **root_p, svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *result_pool) { - const svn_fs_id_t *base_root_id, *root_id; - - /* Get the node ID's of the root directories of the transaction and - its base revision. */ - SVN_ERR(svn_fs_x__get_txn_ids(&root_id, &base_root_id, fs, txn_id, pool)); - - /* Oh, give me a clone... - (If they're the same, we haven't cloned the transaction's root - directory yet.) */ - SVN_ERR_ASSERT(!svn_fs_x__id_eq(root_id, base_root_id)); - - /* - * (Sung to the tune of "Home, Home on the Range", with thanks to - * Randall Garrett and Isaac Asimov.) - */ + svn_fs_x__id_t root_id; + svn_fs_x__init_txn_root(&root_id, txn_id); /* One way or another, root_id now identifies a cloned root node. */ - return svn_fs_x__dag_get_node(root_p, fs, root_id, pool); + return svn_fs_x__dag_get_node(root_p, fs, &root_id, result_pool); +} + + +/* Delete all mutable node revisions reachable from node ID, including + ID itself, from FS's `nodes' table. Also delete any mutable + representations and strings associated with that node revision. + ID may refer to a file or directory, which may be mutable or immutable. + + Use SCRATCH_POOL for temporary allocations. + */ +static svn_error_t * +delete_if_mutable(svn_fs_t *fs, + const svn_fs_x__id_t *id, + apr_pool_t *scratch_pool) +{ + dag_node_t *node; + + /* Get the node. */ + SVN_ERR(svn_fs_x__dag_get_node(&node, fs, id, scratch_pool)); + + /* If immutable, do nothing and return immediately. */ + if (! svn_fs_x__dag_check_mutable(node)) + return SVN_NO_ERROR; + + /* Else it's mutable. Recurse on directories... */ + if (node->kind == svn_node_dir) + { + apr_array_header_t *entries; + int i; + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + + /* Loop over directory entries */ + SVN_ERR(svn_fs_x__dag_dir_entries(&entries, node, scratch_pool, + iterpool)); + for (i = 0; i < entries->nelts; ++i) + { + const svn_fs_x__id_t *noderev_id + = &APR_ARRAY_IDX(entries, i, svn_fs_x__dirent_t *)->id; + + svn_pool_clear(iterpool); + SVN_ERR(delete_if_mutable(fs, noderev_id, iterpool)); + } + + svn_pool_destroy(iterpool); + } + + /* ... then delete the node itself, after deleting any mutable + representations and strings it points to. */ + return svn_fs_x__delete_node_revision(fs, id, scratch_pool); } @@ -769,12 +859,11 @@ svn_error_t * svn_fs_x__dag_delete(dag_node_t *parent, const char *name, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - node_revision_t *parent_noderev; + svn_fs_x__noderev_t *parent_noderev; svn_fs_t *fs = parent->fs; - svn_fs_dirent_t *dirent; - svn_fs_id_t *id; + svn_fs_x__dirent_t *dirent; apr_pool_t *subpool; /* Make sure parent is a directory. */ @@ -798,11 +887,12 @@ svn_fs_x__dag_delete(dag_node_t *parent, /* Get a fresh NODE-REVISION for the parent node. */ SVN_ERR(get_node_revision(&parent_noderev, parent)); - subpool = svn_pool_create(pool); + subpool = svn_pool_create(scratch_pool); /* Search this directory for a dirent with that NAME. */ SVN_ERR(svn_fs_x__rep_contents_dir_entry(&dirent, fs, parent_noderev, - name, subpool, subpool)); + name, &parent->hint, + subpool, subpool)); /* If we never found ID in ENTRIES (perhaps because there are no ENTRIES, perhaps because ID just isn't in the existing ENTRIES @@ -812,84 +902,29 @@ svn_fs_x__dag_delete(dag_node_t *parent, (SVN_ERR_FS_NO_SUCH_ENTRY, NULL, "Delete failed--directory has no entry '%s'", name); - /* Copy the ID out of the subpool and release the rest of the - directory listing. */ - id = svn_fs_x__id_copy(dirent->id, pool); - svn_pool_destroy(subpool); - /* If mutable, remove it and any mutable children from db. */ - SVN_ERR(svn_fs_x__dag_delete_if_mutable(parent->fs, id, pool)); + SVN_ERR(delete_if_mutable(parent->fs, &dirent->id, scratch_pool)); + svn_pool_destroy(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, pool); + NULL, svn_node_unknown, parent->node_pool, + scratch_pool); } svn_error_t * -svn_fs_x__dag_remove_node(svn_fs_t *fs, - const svn_fs_id_t *id, - apr_pool_t *pool) -{ - dag_node_t *node; - - /* Fetch the node. */ - SVN_ERR(svn_fs_x__dag_get_node(&node, fs, id, pool)); - - /* If immutable, do nothing and return immediately. */ - if (! svn_fs_x__dag_check_mutable(node)) - return svn_error_createf(SVN_ERR_FS_NOT_MUTABLE, NULL, - "Attempted removal of immutable node"); - - /* Delete the node revision. */ - return svn_fs_x__delete_node_revision(fs, id, pool); -} - - -svn_error_t * -svn_fs_x__dag_delete_if_mutable(svn_fs_t *fs, - const svn_fs_id_t *id, - apr_pool_t *pool) -{ - dag_node_t *node; - - /* Get the node. */ - SVN_ERR(svn_fs_x__dag_get_node(&node, fs, id, pool)); - - /* If immutable, do nothing and return immediately. */ - if (! svn_fs_x__dag_check_mutable(node)) - return SVN_NO_ERROR; - - /* Else it's mutable. Recurse on directories... */ - if (node->kind == svn_node_dir) - { - apr_array_header_t *entries; - int i; - - /* Loop over directory entries */ - SVN_ERR(svn_fs_x__dag_dir_entries(&entries, node, pool)); - if (entries) - for (i = 0; i < entries->nelts; ++i) - SVN_ERR(svn_fs_x__dag_delete_if_mutable(fs, - APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *)->id, - pool)); - } - - /* ... then delete the node itself, after deleting any mutable - representations and strings it points to. */ - return svn_fs_x__dag_remove_node(fs, id, pool); -} - -svn_error_t * svn_fs_x__dag_make_file(dag_node_t **child_p, dag_node_t *parent, const char *parent_path, const char *name, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { /* Call our little helper function */ - return make_entry(child_p, parent, parent_path, name, FALSE, txn_id, pool); + return make_entry(child_p, parent, parent_path, name, FALSE, txn_id, + result_pool, scratch_pool); } @@ -899,19 +934,21 @@ svn_fs_x__dag_make_dir(dag_node_t **chil const char *parent_path, const char *name, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { /* Call our little helper function */ - return make_entry(child_p, parent, parent_path, name, TRUE, txn_id, pool); + return make_entry(child_p, parent, parent_path, name, TRUE, txn_id, + result_pool, scratch_pool); } svn_error_t * svn_fs_x__dag_get_contents(svn_stream_t **contents_p, dag_node_t *file, - apr_pool_t *pool) + apr_pool_t *result_pool) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; svn_stream_t *contents; /* Make sure our node is a file. */ @@ -925,7 +962,7 @@ svn_fs_x__dag_get_contents(svn_stream_t /* Get a stream to the contents. */ SVN_ERR(svn_fs_x__get_contents(&contents, file->fs, - noderev->data_rep, TRUE, pool)); + noderev->data_rep, TRUE, result_pool)); *contents_p = contents; @@ -937,10 +974,11 @@ svn_error_t * svn_fs_x__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p, dag_node_t *source, dag_node_t *target, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - node_revision_t *src_noderev; - node_revision_t *tgt_noderev; + svn_fs_x__noderev_t *src_noderev; + svn_fs_x__noderev_t *tgt_noderev; /* Make sure our nodes are files. */ if ((source && source->kind != svn_node_file) @@ -958,7 +996,8 @@ svn_fs_x__dag_get_file_delta_stream(svn_ /* Get the delta stream. */ return svn_fs_x__get_file_delta_stream(stream_p, target->fs, - src_noderev, tgt_noderev, pool); + src_noderev, tgt_noderev, + result_pool, scratch_pool); } @@ -967,25 +1006,24 @@ svn_fs_x__dag_try_process_file_contents( dag_node_t *node, svn_fs_process_contents_func_t processor, void* baton, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - node_revision_t *noderev; + 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, - processor, baton, pool); + processor, baton, scratch_pool); } svn_error_t * svn_fs_x__dag_file_length(svn_filesize_t *length, - dag_node_t *file, - apr_pool_t *pool) + dag_node_t *file) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; /* Make sure our node is a file. */ if (file->kind != svn_node_file) @@ -996,7 +1034,7 @@ svn_fs_x__dag_file_length(svn_filesize_t /* Go get a fresh node-revision for FILE, and . */ SVN_ERR(get_node_revision(&noderev, file)); - return svn_fs_x__file_length(length, noderev, pool); + return svn_fs_x__file_length(length, noderev); } @@ -1004,9 +1042,9 @@ svn_error_t * svn_fs_x__dag_file_checksum(svn_checksum_t **checksum, dag_node_t *file, svn_checksum_kind_t kind, - apr_pool_t *pool) + apr_pool_t *result_pool) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; if (file->kind != svn_node_file) return svn_error_createf @@ -1015,16 +1053,16 @@ svn_fs_x__dag_file_checksum(svn_checksum SVN_ERR(get_node_revision(&noderev, file)); - return svn_fs_x__file_checksum(checksum, noderev, kind, pool); + return svn_fs_x__file_checksum(checksum, noderev, kind, result_pool); } svn_error_t * svn_fs_x__dag_get_edit_stream(svn_stream_t **contents, dag_node_t *file, - apr_pool_t *pool) + apr_pool_t *result_pool) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; svn_stream_t *ws; /* Make sure our node is a file. */ @@ -1042,7 +1080,7 @@ svn_fs_x__dag_get_edit_stream(svn_stream /* Get the node revision. */ SVN_ERR(get_node_revision(&noderev, file)); - SVN_ERR(svn_fs_x__set_contents(&ws, file->fs, noderev, pool)); + SVN_ERR(svn_fs_x__set_contents(&ws, file->fs, noderev, result_pool)); *contents = ws; @@ -1054,16 +1092,17 @@ svn_fs_x__dag_get_edit_stream(svn_stream svn_error_t * svn_fs_x__dag_finalize_edits(dag_node_t *file, const svn_checksum_t *checksum, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { if (checksum) { svn_checksum_t *file_checksum; SVN_ERR(svn_fs_x__dag_file_checksum(&file_checksum, file, - checksum->kind, pool)); + checksum->kind, scratch_pool)); if (!svn_checksum_match(checksum, file_checksum)) - return svn_checksum_mismatch_err(checksum, file_checksum, pool, + return svn_checksum_mismatch_err(checksum, file_checksum, + scratch_pool, _("Checksum mismatch for '%s'"), file->created_path); } @@ -1074,30 +1113,38 @@ svn_fs_x__dag_finalize_edits(dag_node_t dag_node_t * svn_fs_x__dag_dup(const dag_node_t *node, - apr_pool_t *pool) + apr_pool_t *result_pool) { /* Allocate our new node. */ - dag_node_t *new_node = apr_pcalloc(pool, sizeof(*new_node)); - - new_node->fs = node->fs; - new_node->id = svn_fs_x__id_copy(node->id, pool); - new_node->kind = node->kind; - new_node->created_path = apr_pstrdup(pool, node->created_path); + dag_node_t *new_node = apr_pmemdup(result_pool, node, sizeof(*new_node)); - /* Only copy cached node_revision_t for immutable nodes. */ + /* 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, pool); - new_node->node_revision->id = - svn_fs_x__id_copy(node->node_revision->id, pool); - new_node->node_revision->is_fresh_txn_root = - node->node_revision->is_fresh_txn_root; + 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); } - new_node->node_pool = 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, @@ -1116,20 +1163,20 @@ svn_fs_x__dag_serialize(void **data, /* 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); + { + 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__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); - /* serialize other sub-structures */ - svn_fs_x__id_serialize(context, (const svn_fs_id_t **)&node->id); - svn_fs_x__id_serialize(context, &node->fresh_root_predecessor_id); - svn_temp_serializer__add_string(context, &node->created_path); - /* return serialized data */ serialized = svn_temp_serializer__get(context); *data = serialized->data; @@ -1153,14 +1200,13 @@ svn_fs_x__dag_deserialize(void **out, node->fs = NULL; /* fixup all references to sub-structures */ - svn_fs_x__id_deserialize(node, &node->id, pool); - svn_fs_x__id_deserialize(node, - (svn_fs_id_t **)&node->fresh_root_predecessor_id, - pool); svn_fs_x__noderev_deserialize(node, &node->node_revision, pool); node->node_pool = pool; - svn_temp_deserializer__resolve(node, (void**)&node->created_path); + 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; @@ -1175,12 +1221,11 @@ svn_fs_x__dag_open(dag_node_t **child_p, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - const svn_fs_id_t *node_id; + 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, scratch_pool)); - if (! node_id) + SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, scratch_pool)); + if (! svn_fs_x__id_used(&node_id)) { *child_p = NULL; return SVN_NO_ERROR; @@ -1194,7 +1239,7 @@ svn_fs_x__dag_open(dag_node_t **child_p, /* Now get the node that was requested. */ return svn_fs_x__dag_get_node(child_p, svn_fs_x__dag_get_fs(parent), - node_id, result_pool); + &node_id, result_pool); } @@ -1206,41 +1251,39 @@ svn_fs_x__dag_copy(dag_node_t *to_node, svn_revnum_t from_rev, const char *from_path, svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - const svn_fs_id_t *id; + const svn_fs_x__id_t *id; if (preserve_history) { - node_revision_t *from_noderev, *to_noderev; - svn_fs_x__id_part_t copy_id; - const svn_fs_id_t *src_id = svn_fs_x__dag_get_id(from_node); + svn_fs_x__noderev_t *from_noderev, *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, pool); + to_noderev = copy_node_revision(from_noderev, scratch_pool); /* Reserve a copy ID for this new copy. */ - SVN_ERR(svn_fs_x__reserve_copy_id(©_id, fs, txn_id, pool)); + SVN_ERR(svn_fs_x__reserve_copy_id(©_id, fs, txn_id, scratch_pool)); /* Create a successor with its predecessor pointing at the copy source. */ - to_noderev->predecessor_id = svn_fs_x__id_copy(src_id, pool); - if (to_noderev->predecessor_count != -1) - to_noderev->predecessor_count++; + to_noderev->predecessor_id = to_noderev->noderev_id; + to_noderev->predecessor_count++; to_noderev->created_path = svn_fspath__join(svn_fs_x__dag_get_created_path(to_node), entry, - pool); - to_noderev->copyfrom_path = apr_pstrdup(pool, from_path); + scratch_pool); + to_noderev->copyfrom_path = apr_pstrdup(scratch_pool, from_path); to_noderev->copyfrom_rev = from_rev; /* Set the copyroot equal to our own id. */ to_noderev->copyroot_path = NULL; - SVN_ERR(svn_fs_x__create_successor(&id, fs, src_id, to_noderev, - ©_id, txn_id, pool)); - + SVN_ERR(svn_fs_x__create_successor(fs, to_noderev, + ©_id, txn_id, scratch_pool)); + id = &to_noderev->noderev_id; } else /* don't preserve history */ { @@ -1249,7 +1292,7 @@ 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, - txn_id, pool); + txn_id, scratch_pool); } @@ -1262,9 +1305,9 @@ svn_fs_x__dag_things_different(svn_boole dag_node_t *node1, dag_node_t *node2, svn_boolean_t strict, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - node_revision_t *noderev1, *noderev2; + svn_fs_x__noderev_t *noderev1, *noderev2; svn_fs_t *fs; svn_boolean_t same; @@ -1283,7 +1326,7 @@ svn_fs_x__dag_things_different(svn_boole if (props_changed != NULL) { SVN_ERR(svn_fs_x__prop_rep_equal(&same, fs, noderev1, noderev2, - strict, pool)); + strict, scratch_pool)); *props_changed = !same; } @@ -1300,7 +1343,7 @@ svn_fs_x__dag_get_copyroot(svn_revnum_t const char **path, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; /* Go get a fresh node-revision for NODE. */ SVN_ERR(get_node_revision(&noderev, node)); @@ -1315,7 +1358,7 @@ svn_error_t * svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; /* Go get a fresh node-revision for NODE. */ SVN_ERR(get_node_revision(&noderev, node)); @@ -1329,7 +1372,7 @@ svn_error_t * svn_fs_x__dag_get_copyfrom_path(const char **path, dag_node_t *node) { - node_revision_t *noderev; + svn_fs_x__noderev_t *noderev; /* Go get a fresh node-revision for NODE. */ SVN_ERR(get_node_revision(&noderev, node)); @@ -1342,9 +1385,9 @@ svn_fs_x__dag_get_copyfrom_path(const ch svn_error_t * svn_fs_x__dag_update_ancestry(dag_node_t *target, dag_node_t *source, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - node_revision_t *source_noderev, *target_noderev; + svn_fs_x__noderev_t *source_noderev, *target_noderev; if (! svn_fs_x__dag_check_mutable(target)) return svn_error_createf @@ -1354,11 +1397,10 @@ svn_fs_x__dag_update_ancestry(dag_node_t SVN_ERR(get_node_revision(&source_noderev, source)); SVN_ERR(get_node_revision(&target_noderev, target)); - target_noderev->predecessor_id = source->id; + target_noderev->predecessor_id = source_noderev->noderev_id; target_noderev->predecessor_count = source_noderev->predecessor_count; - if (target_noderev->predecessor_count != -1) - target_noderev->predecessor_count++; + target_noderev->predecessor_count++; - return svn_fs_x__put_node_revision(target->fs, target->id, target_noderev, - FALSE, pool); + return svn_fs_x__put_node_revision(target->fs, target_noderev, FALSE, + scratch_pool); }
Modified: subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.h URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.h?rev=1653578&r1=1653577&r2=1653578&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.h (original) +++ subversion/branches/pin-externals/subversion/libsvn_fs_x/dag.h Wed Jan 21 16:22:19 2015 @@ -27,6 +27,7 @@ #include "svn_delta.h" #include "private/svn_cache.h" +#include "fs.h" #include "id.h" #ifdef __cplusplus @@ -64,21 +65,27 @@ extern "C" { typedef struct dag_node_t dag_node_t; /* Fill *NODE with a dag_node_t representing node revision ID in FS, - allocating in POOL. */ + allocating in RESULT_POOL. */ svn_error_t * svn_fs_x__dag_get_node(dag_node_t **node, svn_fs_t *fs, - const svn_fs_id_t *id, - apr_pool_t *pool); + const svn_fs_x__id_t *id, + apr_pool_t *result_pool); /* Return a new dag_node_t object referring to the same node as NODE, - allocated in POOL. If you're trying to build a structure in a + allocated in RESULT_POOL. If you're trying to build a structure in a pool that wants to refer to dag nodes that may have been allocated elsewhere, you can call this function and avoid inter-pool pointers. */ dag_node_t * svn_fs_x__dag_dup(const dag_node_t *node, - apr_pool_t *pool); + apr_pool_t *result_pool); + +/* If NODE has been allocated in POOL, return NODE. Otherwise, return + a copy created in RESULT_POOL with svn_fs_fs__dag_dup. */ +dag_node_t * +svn_fs_x__dag_copy_into_pool(dag_node_t *node, + apr_pool_t *result_pool); /* Serialize a DAG node, except don't try to preserve the 'fs' member. Implements svn_cache__serialize_func_t */ @@ -97,50 +104,78 @@ svn_fs_x__dag_deserialize(void **out, apr_pool_t *pool); /* Return the filesystem containing NODE. */ -svn_fs_t *svn_fs_x__dag_get_fs(dag_node_t *node); +svn_fs_t * +svn_fs_x__dag_get_fs(dag_node_t *node); /* Changes the filesystem containing NODE to FS. (Used when pulling nodes out of a shared cache, say.) */ -void svn_fs_x__dag_set_fs(dag_node_t *node, svn_fs_t *fs); +void +svn_fs_x__dag_set_fs(dag_node_t *node, + svn_fs_t *fs); -/* Set *REV to NODE's revision number, allocating in POOL. If NODE - has never been committed as part of a revision, set *REV to - SVN_INVALID_REVNUM. */ -svn_error_t *svn_fs_x__dag_get_revision(svn_revnum_t *rev, - dag_node_t *node, - apr_pool_t *pool); +/* Return NODE's revision number. If NODE has never been committed as + part of a revision, set *REV to SVN_INVALID_REVNUM. */ +svn_revnum_t +svn_fs_x__dag_get_revision(const dag_node_t *node); /* Return the node revision ID of NODE. The value returned is shared with NODE, and will be deallocated when NODE is. */ -const svn_fs_id_t *svn_fs_x__dag_get_id(const dag_node_t *node); +const svn_fs_x__id_t * +svn_fs_x__dag_get_id(const dag_node_t *node); + +/* 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_get_node_id(svn_fs_x__id_t *node_id, + dag_node_t *node); + +/* Return the copy 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); + +/* Set *SAME to TRUE, if nodes LHS and RHS have the same node ID. */ +svn_error_t * +svn_fs_x__dag_related_node(svn_boolean_t *same, + dag_node_t *lhs, + dag_node_t *rhs); +/* Set *SAME to TRUE, if nodes LHS and RHS have the same node and copy IDs. + */ +svn_error_t * +svn_fs_x__dag_same_line_of_history(svn_boolean_t *same, + dag_node_t *lhs, + dag_node_t *rhs); /* Return the created path of NODE. The value returned is shared with NODE, and will be deallocated when NODE is. */ -const char *svn_fs_x__dag_get_created_path(dag_node_t *node); +const char * +svn_fs_x__dag_get_created_path(dag_node_t *node); -/* Set *ID_P to the node revision ID of NODE's immediate predecessor, - or NULL if NODE has no predecessor. +/* Set *ID_P to the node revision ID of NODE's immediate predecessor. */ -svn_error_t *svn_fs_x__dag_get_predecessor_id(const svn_fs_id_t **id_p, - dag_node_t *node); +svn_error_t * +svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p, + dag_node_t *node); -/* Set *COUNT to the number of predecessors NODE has (recursively), or - -1 if not known. +/* Set *COUNT to the number of predecessors NODE has (recursively). */ /* ### This function is currently only used by 'verify'. */ -svn_error_t *svn_fs_x__dag_get_predecessor_count(int *count, - dag_node_t *node); +svn_error_t * +svn_fs_x__dag_get_predecessor_count(int *count, + dag_node_t *node); /* Set *COUNT to the number of node under NODE (inclusive) with svn:mergeinfo properties. */ -svn_error_t *svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count, - dag_node_t *node); +svn_error_t * +svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count, + dag_node_t *node); /* Set *DO_THEY to a flag indicating whether or not NODE is a directory with at least one descendant (not including itself) with @@ -158,10 +193,12 @@ svn_fs_x__dag_has_mergeinfo(svn_boolean_ dag_node_t *node); /* Return non-zero IFF NODE is currently mutable. */ -svn_boolean_t svn_fs_x__dag_check_mutable(const dag_node_t *node); +svn_boolean_t +svn_fs_x__dag_check_mutable(const dag_node_t *node); /* Return the node kind of NODE. */ -svn_node_kind_t svn_fs_x__dag_node_kind(dag_node_t *node); +svn_node_kind_t +svn_fs_x__dag_node_kind(dag_node_t *node); /* Set *PROPLIST_P to a PROPLIST hash representing the entire property list of NODE, allocating from POOL. The hash has const char * @@ -171,38 +208,43 @@ svn_node_kind_t svn_fs_x__dag_node_kind( If properties do not exist on NODE, *PROPLIST_P will be set to NULL. - Use POOL for all allocations. + Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporaries. */ -svn_error_t *svn_fs_x__dag_get_proplist(apr_hash_t **proplist_p, - dag_node_t *node, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_get_proplist(apr_hash_t **proplist_p, + dag_node_t *node, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /* Set the property list of NODE to PROPLIST, allocating from POOL. The node being changed must be mutable. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_set_proplist(dag_node_t *node, - apr_hash_t *proplist, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_set_proplist(dag_node_t *node, + apr_hash_t *proplist, + apr_pool_t *scratch_pool); /* Increment the mergeinfo_count field on NODE by INCREMENT. The node being changed must be mutable. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node, - apr_int64_t increment, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node, + apr_int64_t increment, + apr_pool_t *scratch_pool); /* Set the has-mergeinfo flag on NODE to HAS_MERGEINFO. The node being changed must be mutable. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_set_has_mergeinfo(dag_node_t *node, - svn_boolean_t has_mergeinfo, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_set_has_mergeinfo(dag_node_t *node, + svn_boolean_t has_mergeinfo, + apr_pool_t *scratch_pool); @@ -210,42 +252,48 @@ svn_error_t *svn_fs_x__dag_set_has_merge /* Open the root of revision REV of filesystem FS, allocating from - POOL. Set *NODE_P to the new node. */ -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 *pool); + RESULT_POOL. Set *NODE_P to the new node. */ +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); /* Set *NODE_P to the root of transaction TXN_ID in FS, allocating - from POOL. + from RESULT_POOL. Note that the root node of TXN_ID is not necessarily mutable. If no changes have been made in the transaction, then it may share its root directory with its base revision. To get a mutable root node for a transaction, call svn_fs_x__dag_clone_root. */ -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 *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); /* Set *NODE_P to the base root of transaction TXN_ID in FS, - allocating from POOL. Allocate the node in TRAIL->pool. */ -svn_error_t *svn_fs_x__dag_txn_base_root(dag_node_t **node_p, - svn_fs_t *fs, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool); + allocating from RESULT_POOL. Allocate the node in TRAIL->pool. + Use SCRATCH_POOL for temporaries. */ +svn_error_t * +svn_fs_x__dag_txn_base_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); /* Clone the root directory of TXN_ID in FS, and update the `transactions' table entry to point to it, unless this has been done already. In either case, set *ROOT_P to a reference to the - root directory clone. Allocate *ROOT_P in POOL. */ -svn_error_t *svn_fs_x__dag_clone_root(dag_node_t **root_p, - svn_fs_t *fs, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool); + root directory clone. Allocate *ROOT_P in RESULT_POOL. */ +svn_error_t * +svn_fs_x__dag_clone_root(dag_node_t **root_p, + svn_fs_t *fs, + svn_fs_x__txn_id_t txn_id, + apr_pool_t *result_pool); @@ -266,24 +314,13 @@ svn_fs_x__dag_open(dag_node_t **child_p, /* Set *ENTRIES_P to an array of NODE's entries, sorted by entry names, - and the values are svn_fs_dirent_t's. The returned table (and elements) - is allocated in POOL, which is also used for temporary allocations. */ -svn_error_t *svn_fs_x__dag_dir_entries(apr_array_header_t **entries_p, - dag_node_t *node, - apr_pool_t *pool); - -/* Fetches the NODE's entries and returns a copy of the entry selected - by the key value given in NAME and set *DIRENT to a copy of that - entry. If such entry was found, the copy will be allocated in - RESULT_POOL. Temporary data will be used in SCRATCH_POOL. - Otherwise, the *DIRENT will be set to NULL. - */ -/* ### This function is currently only called from dag.c. */ -svn_error_t * svn_fs_x__dag_dir_entry(svn_fs_dirent_t **dirent, - dag_node_t *node, - const char* name, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); + and the values are svn_fs_x__dirent_t. The returned table (and elements) + is allocated in RESULT_POOL, temporaries in SCRATCH_POOL. */ +svn_error_t * +svn_fs_x__dag_dir_entries(apr_array_header_t **entries_p, + dag_node_t *node, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /* Set ENTRY_NAME in NODE to point to ID (with kind KIND), allocating from POOL. NODE must be a mutable directory. ID can refer to a @@ -291,15 +328,15 @@ svn_error_t * svn_fs_x__dag_dir_entry(sv be created. TXN_ID is the Subversion transaction under which this occurs. - Use POOL for all allocations, including to cache the node_revision in - NODE. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_set_entry(dag_node_t *node, - const char *entry_name, - const svn_fs_id_t *id, - svn_node_kind_t kind, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_set_entry(dag_node_t *node, + const char *entry_name, + const svn_fs_x__id_t *id, + svn_node_kind_t kind, + svn_fs_x__txn_id_t txn_id, + apr_pool_t *scratch_pool); /* Make a new mutable clone of the node named NAME in PARENT, and @@ -319,16 +356,18 @@ svn_error_t *svn_fs_x__dag_set_entry(dag TXN_ID is the Subversion transaction under which this occurs. - Use POOL for all allocations. + Allocate *CHILD_P in RESULT_POOL and use SCRATCH_POOL for temporaries. */ -svn_error_t *svn_fs_x__dag_clone_child(dag_node_t **child_p, - dag_node_t *parent, - const char *parent_path, - const char *name, - const svn_fs_x__id_part_t *copy_id, - svn_fs_x__txn_id_t txn_id, - svn_boolean_t is_parent_copyroot, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_clone_child(dag_node_t **child_p, + dag_node_t *parent, + const char *parent_path, + const char *name, + const svn_fs_x__id_t *copy_id, + svn_fs_x__txn_id_t txn_id, + svn_boolean_t is_parent_copyroot, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /* Delete the directory entry named NAME from PARENT, allocating from @@ -341,40 +380,17 @@ svn_error_t *svn_fs_x__dag_clone_child(d If return SVN_ERR_FS_NO_SUCH_ENTRY, then there is no entry NAME in PARENT. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_delete(dag_node_t *parent, - const char *name, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool); - - -/* Delete the node revision assigned to node ID from FS's `nodes' - table, allocating from POOL. Also delete any mutable - representations and strings associated with that node revision. ID - may refer to a file or directory, which must be mutable. - - NOTE: If ID represents a directory, and that directory has mutable - children, you risk orphaning those children by leaving them - dangling, disconnected from all DAG trees. It is assumed that - callers of this interface know what in the world they are doing. */ -svn_error_t *svn_fs_x__dag_remove_node(svn_fs_t *fs, - const svn_fs_id_t *id, - apr_pool_t *pool); - - -/* Delete all mutable node revisions reachable from node ID, including - ID itself, from FS's `nodes' table, allocating from POOL. Also - delete any mutable representations and strings associated with that - node revision. ID may refer to a file or directory, which may be - mutable or immutable. */ -svn_error_t *svn_fs_x__dag_delete_if_mutable(svn_fs_t *fs, - const svn_fs_id_t *id, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_delete(dag_node_t *parent, + const char *name, + svn_fs_x__txn_id_t txn_id, + apr_pool_t *scratch_pool); /* Create a new mutable directory named NAME in PARENT. Set *CHILD_P - to a reference to the new node, allocated in POOL. The new + to a reference to the new node, allocated in RESULT_POOL. The new directory has no contents, and no properties. PARENT must be mutable. NAME must be a single path component; it cannot be a slash-separated directory path. PARENT_PATH must be the @@ -382,14 +398,16 @@ svn_error_t *svn_fs_x__dag_delete_if_mut not currently have an entry named NAME. TXN_ID is the Subversion transaction under which this occurs. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_make_dir(dag_node_t **child_p, - dag_node_t *parent, - const char *parent_path, - const char *name, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_make_dir(dag_node_t **child_p, + dag_node_t *parent, + const char *parent_path, + const char *name, + svn_fs_x__txn_id_t txn_id, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); @@ -397,57 +415,56 @@ svn_error_t *svn_fs_x__dag_make_dir(dag_ /* Set *CONTENTS to a readable generic stream which yields the - contents of FILE. Allocate the stream in POOL. + contents of FILE. Allocate the stream in RESULT_POOL. If FILE is not a file, return SVN_ERR_FS_NOT_FILE. - - Use POOL for all allocations. */ -svn_error_t *svn_fs_x__dag_get_contents(svn_stream_t **contents, - dag_node_t *file, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_get_contents(svn_stream_t **contents, + dag_node_t *file, + apr_pool_t *result_pool); /* Attempt to fetch the contents of NODE and pass it along with the BATON to the PROCESSOR. Set *SUCCESS only of the data could be provided and the processor had been called. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ svn_error_t * svn_fs_x__dag_try_process_file_contents(svn_boolean_t *success, dag_node_t *node, svn_fs_process_contents_func_t processor, void* baton, - apr_pool_t *pool); + apr_pool_t *scratch_pool); /* Set *STREAM_P to a delta stream that will turn the contents of SOURCE into - the contents of TARGET, allocated in POOL. If SOURCE is null, the empty - string will be used. + the contents of TARGET, allocated in RESULT_POOL. If SOURCE is null, the + empty string will be used is its stead. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ svn_error_t * svn_fs_x__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p, dag_node_t *source, dag_node_t *target, - apr_pool_t *pool); + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /* Return a generic writable stream in *CONTENTS with which to set the - contents of FILE. Allocate the stream in POOL. + contents of FILE. Allocate the stream in RESULT_POOL. Any previous edits on the file will be deleted, and a new edit stream will be constructed. - - Use POOL for all allocations. */ -svn_error_t *svn_fs_x__dag_get_edit_stream(svn_stream_t **contents, - dag_node_t *file, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_get_edit_stream(svn_stream_t **contents, + dag_node_t *file, + apr_pool_t *result_pool); /* Signify the completion of edits to FILE made using the stream - returned by svn_fs_x__dag_get_edit_stream, allocating from POOL. + returned by svn_fs_x__dag_get_edit_stream. If CHECKSUM is non-null, it must match the checksum for FILE's contents (note: this is not recalculated, the recorded checksum is @@ -455,60 +472,57 @@ svn_error_t *svn_fs_x__dag_get_edit_stre This operation is a no-op if no edits are present. - Use POOL for all allocations, including to cache the node_revision in - FILE. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_finalize_edits(dag_node_t *file, - const svn_checksum_t *checksum, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_finalize_edits(dag_node_t *file, + const svn_checksum_t *checksum, + apr_pool_t *scratch_pool); /* Set *LENGTH to the length of the contents of FILE. - - Use POOL for all allocations. */ -svn_error_t *svn_fs_x__dag_file_length(svn_filesize_t *length, - dag_node_t *file, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_file_length(svn_filesize_t *length, + dag_node_t *file); /* Put the recorded checksum of type KIND for FILE into CHECKSUM, allocating - from POOL. + from RESULT_POOL. If no stored checksum is available, do not calculate the checksum, just put NULL into CHECKSUM. - - Use POOL for all allocations. */ svn_error_t * svn_fs_x__dag_file_checksum(svn_checksum_t **checksum, dag_node_t *file, svn_checksum_kind_t kind, - apr_pool_t *pool); + apr_pool_t *result_pool); /* Create a new mutable file named NAME in PARENT. Set *CHILD_P to a - reference to the new node, allocated in POOL. The new file's + reference to the new node, allocated in RESULT_POOL. The new file's contents are the empty string, and it has no properties. PARENT must be mutable. NAME must be a single path component; it cannot be a slash-separated directory path. PARENT_PATH must be the canonicalized absolute path of the parent directory. TXN_ID is the Subversion transaction under which this occurs. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_make_file(dag_node_t **child_p, - dag_node_t *parent, - const char *parent_path, - const char *name, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_make_file(dag_node_t **child_p, + dag_node_t *parent, + const char *parent_path, + const char *name, + svn_fs_x__txn_id_t txn_id, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /* Copies */ -/* Make ENTRY in TO_NODE be a copy of FROM_NODE, allocating from POOL. - TO_NODE must be mutable. TXN_ID is the Subversion transaction - under which this occurs. +/* Make ENTRY in TO_NODE be a copy of FROM_NODE. TO_NODE must be mutable. + TXN_ID is the Subversion transaction under which this occurs. If PRESERVE_HISTORY is true, the new node will record that it was copied from FROM_PATH in FROM_REV; therefore, FROM_NODE should be @@ -518,16 +532,17 @@ svn_error_t *svn_fs_x__dag_make_file(dag If PRESERVE_HISTORY is false, FROM_PATH and FROM_REV are ignored. - Use POOL for all allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_copy(dag_node_t *to_node, - const char *entry, - dag_node_t *from_node, - svn_boolean_t preserve_history, - svn_revnum_t from_rev, - const char *from_path, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_copy(dag_node_t *to_node, + const char *entry, + dag_node_t *from_node, + svn_boolean_t preserve_history, + svn_revnum_t from_rev, + const char *from_path, + svn_fs_x__txn_id_t txn_id, + apr_pool_t *scratch_pool); /* Comparison */ @@ -543,39 +558,45 @@ svn_error_t *svn_fs_x__dag_copy(dag_node two nodes have different contents, or to 0 if same. NODE1 and NODE2 must refer to files from the same filesystem. - Use POOL for temporary allocations. + Use SCRATCH_POOL for temporary allocations. */ -svn_error_t *svn_fs_x__dag_things_different(svn_boolean_t *props_changed, - svn_boolean_t *contents_changed, - dag_node_t *node1, - dag_node_t *node2, - svn_boolean_t strict, - apr_pool_t *pool); +svn_error_t * +svn_fs_x__dag_things_different(svn_boolean_t *props_changed, + svn_boolean_t *contents_changed, + dag_node_t *node1, + dag_node_t *node2, + svn_boolean_t strict, + apr_pool_t *scratch_pool); /* Set *REV and *PATH to the copyroot revision and path of node NODE, or to SVN_INVALID_REVNUM and NULL if no copyroot exists. */ -svn_error_t *svn_fs_x__dag_get_copyroot(svn_revnum_t *rev, - const char **path, - dag_node_t *node); +svn_error_t * +svn_fs_x__dag_get_copyroot(svn_revnum_t *rev, + const char **path, + dag_node_t *node); /* Set *REV to the copyfrom revision associated with NODE. */ -svn_error_t *svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev, - dag_node_t *node); +svn_error_t * +svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev, + dag_node_t *node); /* Set *PATH to the copyfrom path associated with NODE. */ -svn_error_t *svn_fs_x__dag_get_copyfrom_path(const char **path, - dag_node_t *node); +svn_error_t * +svn_fs_x__dag_get_copyfrom_path(const char **path, + dag_node_t *node); /* Update *TARGET so that SOURCE is it's predecessor. + + Use SCRATCH_POOL for temporary allocations. */ svn_error_t * svn_fs_x__dag_update_ancestry(dag_node_t *target, dag_node_t *source, - apr_pool_t *pool); + apr_pool_t *scratch_pool); #ifdef __cplusplus } #endif /* __cplusplus */
