diff options
Diffstat (limited to 'subversion/libsvn_fs_fs/dag.c')
-rw-r--r-- | subversion/libsvn_fs_fs/dag.c | 178 |
1 files changed, 97 insertions, 81 deletions
diff --git a/subversion/libsvn_fs_fs/dag.c b/subversion/libsvn_fs_fs/dag.c index 2bd7f14..3c51ffd 100644 --- a/subversion/libsvn_fs_fs/dag.c +++ b/subversion/libsvn_fs_fs/dag.c @@ -70,6 +70,9 @@ struct dag_node_t things for you. */ node_revision_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; }; @@ -139,7 +142,7 @@ copy_node_revision(node_revision_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 POOL. + 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 @@ -150,16 +153,15 @@ copy_node_revision(node_revision_t *noderev, the structure at all. */ static svn_error_t * get_node_revision(node_revision_t **noderev_p, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { - node_revision_t *noderev; - /* If we've already got a copy, there's no need to read it in. */ if (! node->node_revision) { + node_revision_t *noderev; + SVN_ERR(svn_fs_fs__get_node_revision(&noderev, node->fs, - node->id, pool)); + node->id, node->node_pool)); node->node_revision = noderev; } @@ -190,7 +192,8 @@ svn_fs_fs__dag_get_node(dag_node_t **node, new_node->id = svn_fs_fs__id_copy(id, pool); /* Grab the contents so we can inspect the node's kind and created path. */ - SVN_ERR(get_node_revision(&noderev, new_node, pool)); + new_node->node_pool = pool; + SVN_ERR(get_node_revision(&noderev, new_node)); /* Initialize the KIND and CREATED_PATH attributes */ new_node->kind = noderev->kind; @@ -227,12 +230,11 @@ svn_fs_fs__dag_get_revision(svn_revnum_t *rev, svn_error_t * svn_fs_fs__dag_get_predecessor_id(const svn_fs_id_t **id_p, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); *id_p = noderev->predecessor_id; return SVN_NO_ERROR; } @@ -240,44 +242,40 @@ svn_fs_fs__dag_get_predecessor_id(const svn_fs_id_t **id_p, svn_error_t * svn_fs_fs__dag_get_predecessor_count(int *count, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); *count = noderev->predecessor_count; return SVN_NO_ERROR; } svn_error_t * svn_fs_fs__dag_get_mergeinfo_count(apr_int64_t *count, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); *count = noderev->mergeinfo_count; return SVN_NO_ERROR; } svn_error_t * svn_fs_fs__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); *has_mergeinfo = noderev->has_mergeinfo; return SVN_NO_ERROR; } svn_error_t * svn_fs_fs__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; @@ -287,7 +285,7 @@ svn_fs_fs__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they, return SVN_NO_ERROR; } - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); if (noderev->mergeinfo_count > 1) *do_they = TRUE; else if (noderev->mergeinfo_count == 1 && !noderev->has_mergeinfo) @@ -309,15 +307,13 @@ static svn_error_t * dir_entry_id_from_node(const svn_fs_id_t **id_p, dag_node_t *parent, const char *name, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { svn_fs_dirent_t *dirent; - apr_pool_t *subpool = svn_pool_create(pool); - - SVN_ERR(svn_fs_fs__dag_dir_entry(&dirent, parent, name, subpool, pool)); - *id_p = dirent ? svn_fs_fs__id_copy(dirent->id, pool) : NULL; - svn_pool_destroy(subpool); + SVN_ERR(svn_fs_fs__dag_dir_entry(&dirent, parent, name, scratch_pool)); + *id_p = dirent ? svn_fs_fs__id_copy(dirent->id, result_pool) : NULL; return SVN_NO_ERROR; } @@ -342,7 +338,7 @@ set_entry(dag_node_t *parent, node_revision_t *parent_noderev; /* Get the parent's node-revision. */ - SVN_ERR(get_node_revision(&parent_noderev, parent, pool)); + SVN_ERR(get_node_revision(&parent_noderev, parent)); /* Set the new entry. */ return svn_fs_fs__set_entry(parent->fs, txn_id, parent_noderev, name, id, @@ -355,7 +351,7 @@ set_entry(dag_node_t *parent, will be a file. The new node will be allocated in POOL. PARENT must be mutable, and must not have an entry named NAME. - Use POOL for all allocations including caching the node_revision in PARENT. + Use POOL for all allocations, except caching the node_revision in PARENT. */ static svn_error_t * make_entry(dag_node_t **child_p, @@ -392,7 +388,7 @@ 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, pool); - SVN_ERR(get_node_revision(&parent_noderev, parent, pool)); + SVN_ERR(get_node_revision(&parent_noderev, parent)); new_noderev.copyroot_path = apr_pstrdup(pool, parent_noderev->copyroot_path); new_noderev.copyroot_rev = parent_noderev->copyroot_rev; @@ -419,12 +415,11 @@ make_entry(dag_node_t **child_p, svn_error_t * svn_fs_fs__dag_dir_entries(apr_hash_t **entries, dag_node_t *node, - apr_pool_t *pool, - apr_pool_t *node_pool) + apr_pool_t *pool) { node_revision_t *noderev; - SVN_ERR(get_node_revision(&noderev, node, node_pool)); + SVN_ERR(get_node_revision(&noderev, node)); if (noderev->kind != svn_node_dir) return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL, @@ -437,11 +432,10 @@ svn_error_t * svn_fs_fs__dag_dir_entry(svn_fs_dirent_t **dirent, dag_node_t *node, const char* name, - apr_pool_t *pool, - apr_pool_t *node_pool) + apr_pool_t *pool) { node_revision_t *noderev; - SVN_ERR(get_node_revision(&noderev, node, node_pool)); + SVN_ERR(get_node_revision(&noderev, node)); if (noderev->kind != svn_node_dir) return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL, @@ -449,7 +443,7 @@ svn_fs_fs__dag_dir_entry(svn_fs_dirent_t **dirent, /* Get a dirent hash for this directory. */ return svn_fs_fs__rep_contents_dir_entry(dirent, node->fs, - noderev, name, pool); + noderev, name, pool, pool); } @@ -488,7 +482,7 @@ svn_fs_fs__dag_get_proplist(apr_hash_t **proplist_p, node_revision_t *noderev; apr_hash_t *proplist = NULL; - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); SVN_ERR(svn_fs_fs__get_proplist(&proplist, node->fs, noderev, pool)); @@ -517,7 +511,7 @@ svn_fs_fs__dag_set_proplist(dag_node_t *node, } /* Go get a fresh NODE-REVISION for this node. */ - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); /* Set the new proplist. */ return svn_fs_fs__set_proplist(node->fs, noderev, proplist, pool); @@ -545,7 +539,7 @@ svn_fs_fs__dag_increment_mergeinfo_count(dag_node_t *node, return SVN_NO_ERROR; /* Go get a fresh NODE-REVISION for this node. */ - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); noderev->mergeinfo_count += increment; if (noderev->mergeinfo_count < 0) @@ -594,7 +588,7 @@ svn_fs_fs__dag_set_has_mergeinfo(dag_node_t *node, } /* Go get a fresh NODE-REVISION for this node. */ - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); noderev->has_mergeinfo = has_mergeinfo; @@ -658,6 +652,7 @@ svn_fs_fs__dag_clone_child(dag_node_t **child_p, 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 */ svn_fs_t *fs = svn_fs_fs__dag_get_fs(parent); + apr_pool_t *subpool = svn_pool_create(pool); /* First check that the parent is mutable. */ if (! svn_fs_fs__dag_check_mutable(parent)) @@ -672,7 +667,7 @@ svn_fs_fs__dag_clone_child(dag_node_t **child_p, "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_fs__dag_open(&cur_entry, parent, name, pool)); + SVN_ERR(svn_fs_fs__dag_open(&cur_entry, parent, name, pool, subpool)); /* Check for mutability in the node we found. If it's mutable, we don't need to clone it. */ @@ -686,11 +681,11 @@ svn_fs_fs__dag_clone_child(dag_node_t **child_p, node_revision_t *noderev, *parent_noderev; /* Go get a fresh NODE-REVISION for current child node. */ - SVN_ERR(get_node_revision(&noderev, cur_entry, pool)); + SVN_ERR(get_node_revision(&noderev, cur_entry)); if (is_parent_copyroot) { - SVN_ERR(get_node_revision(&parent_noderev, parent, pool)); + SVN_ERR(get_node_revision(&parent_noderev, parent)); noderev->copyroot_rev = parent_noderev->copyroot_rev; noderev->copyroot_path = apr_pstrdup(pool, parent_noderev->copyroot_path); @@ -714,6 +709,7 @@ svn_fs_fs__dag_clone_child(dag_node_t **child_p, } /* Initialize the youngster. */ + svn_pool_destroy(subpool); return svn_fs_fs__dag_get_node(child_p, fs, new_node_id, pool); } @@ -753,7 +749,6 @@ svn_fs_fs__dag_delete(dag_node_t *parent, apr_pool_t *pool) { node_revision_t *parent_noderev; - apr_hash_t *entries; svn_fs_t *fs = parent->fs; svn_fs_dirent_t *dirent; svn_fs_id_t *id; @@ -778,15 +773,13 @@ svn_fs_fs__dag_delete(dag_node_t *parent, "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, pool)); + SVN_ERR(get_node_revision(&parent_noderev, parent)); subpool = svn_pool_create(pool); - /* Get a dirent hash for this directory. */ - SVN_ERR(svn_fs_fs__rep_contents_dir(&entries, fs, parent_noderev, subpool)); - - /* Find name in the ENTRIES hash. */ - dirent = apr_hash_get(entries, name, APR_HASH_KEY_STRING); + /* Search this directory for a dirent with that NAME. */ + SVN_ERR(svn_fs_fs__rep_contents_dir_entry(&dirent, fs, parent_noderev, + name, 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 @@ -851,7 +844,7 @@ svn_fs_fs__dag_delete_if_mutable(svn_fs_t *fs, apr_hash_index_t *hi; /* Loop over hash entries */ - SVN_ERR(svn_fs_fs__dag_dir_entries(&entries, node, pool, pool)); + SVN_ERR(svn_fs_fs__dag_dir_entries(&entries, node, pool)); if (entries) { for (hi = apr_hash_first(pool, entries); @@ -912,7 +905,7 @@ svn_fs_fs__dag_get_contents(svn_stream_t **contents_p, "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, pool)); + SVN_ERR(get_node_revision(&noderev, file)); /* Get a stream to the contents. */ SVN_ERR(svn_fs_fs__get_contents(&contents, file->fs, @@ -942,10 +935,10 @@ svn_fs_fs__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p, /* Go get fresh node-revisions for the nodes. */ if (source) - SVN_ERR(get_node_revision(&src_noderev, source, pool)); + SVN_ERR(get_node_revision(&src_noderev, source)); else src_noderev = NULL; - SVN_ERR(get_node_revision(&tgt_noderev, target, pool)); + SVN_ERR(get_node_revision(&tgt_noderev, target)); /* Get the delta stream. */ return svn_fs_fs__get_file_delta_stream(stream_p, target->fs, @@ -954,6 +947,24 @@ svn_fs_fs__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p, svn_error_t * +svn_fs_fs__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) +{ + node_revision_t *noderev; + + /* Go get fresh node-revisions for the nodes. */ + SVN_ERR(get_node_revision(&noderev, node)); + + return svn_fs_fs__try_process_file_contents(success, node->fs, + noderev, + processor, baton, pool); +} + + +svn_error_t * svn_fs_fs__dag_file_length(svn_filesize_t *length, dag_node_t *file, apr_pool_t *pool) @@ -967,7 +978,7 @@ svn_fs_fs__dag_file_length(svn_filesize_t *length, "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, pool)); + SVN_ERR(get_node_revision(&noderev, file)); return svn_fs_fs__file_length(length, noderev, pool); } @@ -986,7 +997,7 @@ svn_fs_fs__dag_file_checksum(svn_checksum_t **checksum, (SVN_ERR_FS_NOT_FILE, NULL, "Attempted to get checksum of a *non*-file node"); - SVN_ERR(get_node_revision(&noderev, file, pool)); + SVN_ERR(get_node_revision(&noderev, file)); return svn_fs_fs__file_checksum(checksum, noderev, kind, pool); } @@ -1013,7 +1024,7 @@ svn_fs_fs__dag_get_edit_stream(svn_stream_t **contents, "Attempted to set textual contents of an immutable node"); /* Get the node revision. */ - SVN_ERR(get_node_revision(&noderev, file, pool)); + SVN_ERR(get_node_revision(&noderev, file)); SVN_ERR(svn_fs_fs__set_contents(&ws, file->fs, noderev, pool)); @@ -1066,11 +1077,13 @@ svn_fs_fs__dag_dup(const dag_node_t *node, new_node->node_revision->is_fresh_txn_root = node->node_revision->is_fresh_txn_root; } + new_node->node_pool = pool; + return new_node; } svn_error_t * -svn_fs_fs__dag_serialize(char **data, +svn_fs_fs__dag_serialize(void **data, apr_size_t *data_len, void *in, apr_pool_t *pool) @@ -1082,7 +1095,7 @@ svn_fs_fs__dag_serialize(char **data, svn_temp_serializer__context_t *context = svn_temp_serializer__init(node, sizeof(*node), - 503, + 1024 - SVN_TEMP_SERIALIZER__OVERHEAD, pool); /* for mutable nodes, we will _never_ cache the noderev */ @@ -1092,6 +1105,10 @@ svn_fs_fs__dag_serialize(char **data, svn_temp_serializer__set_null(context, (const void * const *)&node->node_revision); + /* 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_fs__id_serialize(context, (const svn_fs_id_t **)&node->id); svn_fs_fs__id_serialize(context, &node->fresh_root_predecessor_id); @@ -1107,7 +1124,7 @@ svn_fs_fs__dag_serialize(char **data, svn_error_t * svn_fs_fs__dag_deserialize(void **out, - char *data, + void *data, apr_size_t data_len, apr_pool_t *pool) { @@ -1124,6 +1141,7 @@ svn_fs_fs__dag_deserialize(void **out, svn_fs_fs__id_deserialize(node, (svn_fs_id_t **)&node->fresh_root_predecessor_id); svn_fs_fs__noderev_deserialize(node, &node->node_revision); + node->node_pool = pool; svn_temp_deserializer__resolve(node, (void**)&node->created_path); @@ -1137,12 +1155,14 @@ svn_error_t * svn_fs_fs__dag_open(dag_node_t **child_p, dag_node_t *parent, const char *name, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { const svn_fs_id_t *node_id; /* Ensure that NAME exists in PARENT's entry list. */ - SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, pool)); + SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, + scratch_pool, scratch_pool)); if (! node_id) return svn_error_createf (SVN_ERR_FS_NOT_FOUND, NULL, @@ -1156,7 +1176,7 @@ svn_fs_fs__dag_open(dag_node_t **child_p, /* Now get the node that was requested. */ return svn_fs_fs__dag_get_node(child_p, svn_fs_fs__dag_get_fs(parent), - node_id, pool); + node_id, result_pool); } @@ -1180,7 +1200,7 @@ svn_fs_fs__dag_copy(dag_node_t *to_node, svn_fs_t *fs = svn_fs_fs__dag_get_fs(from_node); /* Make a copy of the original node revision. */ - SVN_ERR(get_node_revision(&from_noderev, from_node, pool)); + SVN_ERR(get_node_revision(&from_noderev, from_node)); to_noderev = copy_node_revision(from_noderev, pool); /* Reserve a copy ID for this new copy. */ @@ -1222,8 +1242,7 @@ svn_error_t * svn_fs_fs__dag_things_different(svn_boolean_t *props_changed, svn_boolean_t *contents_changed, dag_node_t *node1, - dag_node_t *node2, - apr_pool_t *pool) + dag_node_t *node2) { node_revision_t *noderev1, *noderev2; @@ -1233,8 +1252,8 @@ svn_fs_fs__dag_things_different(svn_boolean_t *props_changed, return SVN_NO_ERROR; /* The node revision skels for these two nodes. */ - SVN_ERR(get_node_revision(&noderev1, node1, pool)); - SVN_ERR(get_node_revision(&noderev2, node2, pool)); + SVN_ERR(get_node_revision(&noderev1, node1)); + SVN_ERR(get_node_revision(&noderev2, node2)); /* Compare property keys. */ if (props_changed != NULL) @@ -1253,13 +1272,12 @@ svn_fs_fs__dag_things_different(svn_boolean_t *props_changed, svn_error_t * svn_fs_fs__dag_get_copyroot(svn_revnum_t *rev, const char **path, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; /* Go get a fresh node-revision for NODE. */ - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); *rev = noderev->copyroot_rev; *path = noderev->copyroot_path; @@ -1269,13 +1287,12 @@ svn_fs_fs__dag_get_copyroot(svn_revnum_t *rev, svn_error_t * svn_fs_fs__dag_get_copyfrom_rev(svn_revnum_t *rev, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; /* Go get a fresh node-revision for NODE. */ - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); *rev = noderev->copyfrom_rev; @@ -1284,13 +1301,12 @@ svn_fs_fs__dag_get_copyfrom_rev(svn_revnum_t *rev, svn_error_t * svn_fs_fs__dag_get_copyfrom_path(const char **path, - dag_node_t *node, - apr_pool_t *pool) + dag_node_t *node) { node_revision_t *noderev; /* Go get a fresh node-revision for NODE. */ - SVN_ERR(get_node_revision(&noderev, node, pool)); + SVN_ERR(get_node_revision(&noderev, node)); *path = noderev->copyfrom_path; @@ -1309,8 +1325,8 @@ svn_fs_fs__dag_update_ancestry(dag_node_t *target, (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to update ancestry of non-mutable node")); - SVN_ERR(get_node_revision(&source_noderev, source, pool)); - SVN_ERR(get_node_revision(&target_noderev, target, pool)); + 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_count = source_noderev->predecessor_count; |