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 *));


Reply via email to