Author: stefan2
Date: Wed Feb 4 12:32:17 2015
New Revision: 1657156
URL: http://svn.apache.org/r1657156
Log:
In FSX, reduce the memory consumption of a DAG node construction by
explicitly fetching the noderev and providing it with a scratch pool.
Bubble-up along the caller chain.
* subversion/libsvn_fs_x/dag.h
(svn_fs_x__dag_get_node): Add SCRATCH_POOL parameter.
(svn_fs_x__dag_revision_root,
svn_fs_x__dag_txn_root): Do the same for its callers.
* subversion/libsvn_fs_x/dag.c
(svn_fs_x__dag_get_node): Fetch the noderev using both pools now.
Eliminate the unnecessary path duplication
because noderev will never be invalidated.
(make_entry): Update caller.
(svn_fs_x__dag_revision_root,
svn_fs_x__dag_txn_root): Pass through of the additional pool.
(svn_fs_x__dag_clone_child,
delete_if_mutable,
svn_fs_x__dag_open): Update callers.
* subversion/libsvn_fs_x/tree.c
(root_node,
mutable_root_node): Add SCRATCH_POOL as pass-through parameter.
(open_path,
make_path_mutable,
compare_dir_structure,
merge,
merge_changes,
history_prev,
verify_node,
svn_fs_x__verify_root): Update callers.
Modified:
subversion/trunk/subversion/libsvn_fs_x/dag.c
subversion/trunk/subversion/libsvn_fs_x/dag.h
subversion/trunk/subversion/libsvn_fs_x/tree.c
Modified: subversion/trunk/subversion/libsvn_fs_x/dag.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/dag.c?rev=1657156&r1=1657155&r2=1657156&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/dag.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/dag.c Wed Feb 4 12:32:17 2015
@@ -245,7 +245,8 @@ svn_error_t *
svn_fs_x__dag_get_node(dag_node_t **node,
svn_fs_t *fs,
const svn_fs_x__id_t *id,
- apr_pool_t *result_pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
dag_node_t *new_node;
svn_fs_x__noderev_t *noderev;
@@ -257,12 +258,14 @@ svn_fs_x__dag_get_node(dag_node_t **node
new_node->hint = APR_SIZE_MAX;
/* Grab the contents so we can inspect the node's kind and created path. */
+ SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id,
+ result_pool, scratch_pool));
new_node->node_pool = result_pool;
- SVN_ERR(get_node_revision(&noderev, new_node));
+ new_node->node_revision = noderev;
/* Initialize the KIND and CREATED_PATH attributes */
new_node->kind = noderev->kind;
- new_node->created_path = apr_pstrdup(result_pool, noderev->created_path);
+ 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. */
@@ -469,7 +472,8 @@ make_entry(dag_node_t **child_p,
/* 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_noderev.noderev_id, result_pool));
+ &new_noderev.noderev_id, result_pool,
+ scratch_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
@@ -654,12 +658,14 @@ 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 *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);
+ return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool,
+ scratch_pool);
}
@@ -667,12 +673,14 @@ 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 *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_fs_x__id_t root_id;
svn_fs_x__init_txn_root(&root_id, txn_id);
- return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool);
+ return svn_fs_x__dag_get_node(node_p, fs, &root_id, result_pool,
+ scratch_pool);
}
@@ -755,7 +763,8 @@ svn_fs_x__dag_clone_child(dag_node_t **c
}
/* Initialize the youngster. */
- return svn_fs_x__dag_get_node(child_p, fs, new_node_id, result_pool);
+ return svn_fs_x__dag_get_node(child_p, fs, new_node_id, result_pool,
+ scratch_pool);
}
@@ -774,7 +783,7 @@ delete_if_mutable(svn_fs_t *fs,
dag_node_t *node;
/* Get the node. */
- SVN_ERR(svn_fs_x__dag_get_node(&node, fs, id, scratch_pool));
+ SVN_ERR(svn_fs_x__dag_get_node(&node, fs, id, scratch_pool, scratch_pool));
/* If immutable, do nothing and return immediately. */
if (! svn_fs_x__dag_check_mutable(node))
@@ -1192,7 +1201,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, scratch_pool);
}
Modified: subversion/trunk/subversion/libsvn_fs_x/dag.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/dag.h?rev=1657156&r1=1657155&r2=1657156&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/dag.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/dag.h Wed Feb 4 12:32:17 2015
@@ -65,12 +65,13 @@ 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 RESULT_POOL. */
+ allocating in RESULT_POOL. Use SCRATCH_POOL for temporaries. */
svn_error_t *
svn_fs_x__dag_get_node(dag_node_t **node,
svn_fs_t *fs,
const svn_fs_x__id_t *id,
- apr_pool_t *result_pool);
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* Return a new dag_node_t object referring to the same node as NODE,
@@ -252,21 +253,24 @@ svn_fs_x__dag_set_has_mergeinfo(dag_node
/* Open the root of revision REV of filesystem FS, allocating from
- RESULT_POOL. Set *NODE_P to the new node. */
+ RESULT_POOL. Set *NODE_P to the new node. Use SCRATCH_POOL for
+ temporary allocations.*/
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 *result_pool,
+ apr_pool_t *scratch_pool);
/* Set *NODE_P to the root of transaction TXN_ID in FS, allocating
- from RESULT_POOL. */
+ from RESULT_POOL. Use SCRATCH_POOL for temporary allocations. */
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 *result_pool,
+ apr_pool_t *scratch_pool);
/* Directories. */
Modified: subversion/trunk/subversion/libsvn_fs_x/tree.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/tree.c?rev=1657156&r1=1657155&r2=1657156&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/tree.c Wed Feb 4 12:32:17 2015
@@ -564,42 +564,45 @@ root_txn_id(svn_fs_root_t *root)
}
/* Set *NODE_P to a freshly opened dag node referring to the root
- directory of ROOT, allocating from RESULT_POOL. */
+ directory of ROOT, allocating from RESULT_POOL. Use SCRATCH_POOL
+ for temporary allocations. */
static svn_error_t *
root_node(dag_node_t **node_p,
svn_fs_root_t *root,
- apr_pool_t *result_pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
if (root->is_txn_root)
{
/* It's a transaction root. Open a fresh copy. */
return svn_fs_x__dag_txn_root(node_p, root->fs, root_txn_id(root),
- result_pool);
+ result_pool, scratch_pool);
}
else
{
/* It's a revision root, so we already have its root directory
opened. */
return svn_fs_x__dag_revision_root(node_p, root->fs, root->rev,
- result_pool);
+ result_pool, scratch_pool);
}
}
/* Set *NODE_P to a mutable root directory for ROOT, cloning if
necessary, allocating in RESULT_POOL. ROOT must be a transaction root.
- Use ERROR_PATH in error messages. */
+ Use ERROR_PATH in error messages. Use SCRATCH_POOL for temporaries.*/
static svn_error_t *
mutable_root_node(dag_node_t **node_p,
svn_fs_root_t *root,
const char *error_path,
- apr_pool_t *result_pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
if (root->is_txn_root)
{
/* It's a transaction root. Open a fresh copy. */
return svn_fs_x__dag_txn_root(node_p, root->fs, root_txn_id(root),
- result_pool);
+ result_pool, scratch_pool);
}
else
/* If it's not a transaction root, we can't change its contents. */
@@ -969,7 +972,7 @@ open_path(parent_path_t **parent_path_p,
{
/* Make a parent_path item for the root node, using its own current
copy id. */
- SVN_ERR(root_node(&here, root, pool));
+ SVN_ERR(root_node(&here, root, pool, iterpool));
rest = path + 1; /* skip the leading '/', it saves in iteration */
}
@@ -1186,7 +1189,8 @@ make_path_mutable(svn_fs_root_t *root,
else
{
/* We're trying to clone the root directory. */
- SVN_ERR(mutable_root_node(&clone, root, error_path, result_pool));
+ SVN_ERR(mutable_root_node(&clone, root, error_path, result_pool,
+ scratch_pool));
}
/* Update the PARENT_PATH link to refer to the clone. */
@@ -1698,9 +1702,9 @@ compare_dir_structure(svn_boolean_t *cha
/* Modified but not copied / replaced or anything? */
SVN_ERR(svn_fs_x__dag_get_node(&lhs_node, fs, &lhs_entry->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(svn_fs_x__dag_get_node(&rhs_node, fs, &rhs_entry->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(svn_fs_x__dag_same_line_of_history(&same_history,
lhs_node, rhs_node));
if (same_history)
@@ -1949,7 +1953,7 @@ merge(svn_stringbuf_t *conflict_p,
dag_node_t *t_ent_node;
SVN_ERR(svn_fs_x__dag_get_node(&t_ent_node, fs, &t_entry->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&mergeinfo_start,
t_ent_node));
mergeinfo_increment -= mergeinfo_start;
@@ -1958,7 +1962,7 @@ merge(svn_stringbuf_t *conflict_p,
{
dag_node_t *s_ent_node;
SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs, &s_entry->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&mergeinfo_end,
s_ent_node));
@@ -2007,11 +2011,11 @@ merge(svn_stringbuf_t *conflict_p,
/* Fetch DAG nodes to efficiently access ID parts. */
SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs, &s_entry->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(svn_fs_x__dag_get_node(&t_ent_node, fs, &t_entry->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(svn_fs_x__dag_get_node(&a_ent_node, fs, &a_entry->id,
- iterpool));
+ iterpool, iterpool));
/* If either SOURCE-ENTRY or TARGET-ENTRY is not a direct
modification of ANCESTOR-ENTRY, declare a conflict. */
@@ -2063,7 +2067,7 @@ merge(svn_stringbuf_t *conflict_p,
iterpool));
SVN_ERR(svn_fs_x__dag_get_node(&s_ent_node, fs, &s_entry->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&mergeinfo_s, s_ent_node));
mergeinfo_increment += mergeinfo_s;
@@ -2107,14 +2111,15 @@ merge_changes(dag_node_t *ancestor_node,
svn_fs_x__txn_id_t txn_id = svn_fs_x__txn_get_id(txn);
svn_boolean_t related;
- SVN_ERR(svn_fs_x__dag_txn_root(&txn_root_node, fs, txn_id, scratch_pool));
+ SVN_ERR(svn_fs_x__dag_txn_root(&txn_root_node, fs, txn_id, scratch_pool,
+ scratch_pool));
if (ancestor_node == NULL)
{
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__dag_revision_root(&ancestor_node, fs, base_rev,
- scratch_pool));
+ scratch_pool, scratch_pool));
}
SVN_ERR(svn_fs_x__dag_related_node(&related, ancestor_node, txn_root_node));
@@ -3627,7 +3632,8 @@ history_prev(svn_fs_history_t **prev_his
/* Replace NODE and friends with the information from its
predecessor. */
- SVN_ERR(svn_fs_x__dag_get_node(&node, fs, &pred_id, scratch_pool));
+ SVN_ERR(svn_fs_x__dag_get_node(&node, fs, &pred_id, scratch_pool,
+ scratch_pool));
commit_path = svn_fs_x__dag_get_created_path(node);
commit_rev = svn_fs_x__dag_get_revision(node);
}
@@ -4353,7 +4359,8 @@ verify_node(dag_node_t *node,
{
dag_node_t *pred;
int pred_pred_count;
- SVN_ERR(svn_fs_x__dag_get_node(&pred, fs, &pred_id, iterpool));
+ SVN_ERR(svn_fs_x__dag_get_node(&pred, fs, &pred_id, iterpool,
+ iterpool));
SVN_ERR(svn_fs_x__dag_get_predecessor_count(&pred_pred_count, pred));
if (pred_pred_count+1 != pred_count)
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
@@ -4404,7 +4411,7 @@ verify_node(dag_node_t *node,
if (svn_fs_x__get_revnum(dirent->id.change_set) == rev)
{
SVN_ERR(svn_fs_x__dag_get_node(&child, fs, &dirent->id,
- iterpool));
+ iterpool, iterpool));
SVN_ERR(verify_node(child, rev, parent_nodes, iterpool));
SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&child_mergeinfo,
child));
@@ -4454,7 +4461,7 @@ svn_fs_x__verify_root(svn_fs_root_t *roo
When this code is called in the library, we want to ensure we
use the on-disk data --- rather than some data that was read
in the possibly-distance past and cached since. */
- SVN_ERR(root_node(&root_dir, root, scratch_pool));
+ SVN_ERR(root_node(&root_dir, root, scratch_pool, scratch_pool));
/* Recursively verify ROOT_DIR. */
parent_nodes = apr_array_make(scratch_pool, 16, sizeof(dag_node_t *));