Author: julianfoad
Date: Mon Oct 4 15:11:45 2010
New Revision: 1004280
URL: http://svn.apache.org/viewvc?rev=1004280&view=rev
Log:
Vastly simplify the WC-DB function 'gather_children()', removing the row-
counting DB queries and several subroutines.
Indicative timing measurements showed an improvement in typical queries and
a slight penalty in some queries when the number of children is huge.
* subversion/libsvn_wc/wc_db.c
(count_children, union_children, single_table_children): Delete.
(gather_children): Don't count the children first and make special cases
depending on the counts, just add the children directly into a hash and
return an array of the hash's keys, like union_children() did.
* subversion/libsvn_wc/wc-queries.sql
(STMT_COUNT_BASE_NODE_CHILDREN, STMT_COUNT_BASE_NODE_CHILDREN_1,
STMT_COUNT_WORKING_NODE_CHILDREN, STMT_COUNT_WORKING_NODE_CHILDREN_1):
Delete.
* subversion/tests/cmdline/diff_tests.py
(diff_repos_wc_add_with_props): Tweak to ignore output ordering.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/tests/cmdline/diff_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1004280&r1=1004279&r2=1004280&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon Oct 4 15:11:45
2010
@@ -129,23 +129,6 @@ INSERT OR IGNORE INTO working_node (
wc_id, local_relpath, parent_relpath, presence, kind)
VALUES (?1, ?2, ?3, 'incomplete', 'unknown');
--- STMT_COUNT_BASE_NODE_CHILDREN
-SELECT COUNT(*) FROM base_node
-WHERE wc_id = ?1 AND parent_relpath = ?2;
-
--- STMT_COUNT_BASE_NODE_CHILDREN_1
-SELECT COUNT(*) FROM nodes
-WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0;
-
--- STMT_COUNT_WORKING_NODE_CHILDREN
-SELECT COUNT(*) FROM working_node
-WHERE wc_id = ?1 AND parent_relpath = ?2;
-
--- STMT_COUNT_WORKING_NODE_CHILDREN_1
-SELECT COUNT(*) FROM (SELECT DISTINCT local_relpath FROM nodes
- WHERE wc_id = ?1 AND parent_relpath = ?2
- AND op_depth > 0);
-
-- STMT_SELECT_BASE_NODE_CHILDREN
SELECT local_relpath FROM base_node
WHERE wc_id = ?1 AND parent_relpath = ?2;
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1004280&r1=1004279&r2=1004280&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon Oct 4 15:11:45 2010
@@ -1238,25 +1238,6 @@ insert_working_node(void *baton,
}
-/* Return the number of children under PARENT_RELPATH in the given WC_ID.
- The table is implicitly defined by the STMT_IDX query. */
-static svn_error_t *
-count_children(int *count,
- int stmt_idx,
- svn_sqlite__db_t *sdb,
- apr_int64_t wc_id,
- const char *parent_relpath)
-{
- svn_sqlite__stmt_t *stmt;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, stmt_idx));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, parent_relpath));
- SVN_ERR(svn_sqlite__step_row(stmt));
- *count = svn_sqlite__column_int(stmt, 0);
- return svn_error_return(svn_sqlite__reset(stmt));
-}
-
-
/* Each name is allocated in RESULT_POOL and stored into CHILDREN as a key
pointed to the same name. */
static svn_error_t *
@@ -1287,94 +1268,6 @@ add_children_to_hash(apr_hash_t *childre
}
-/* When children of PARENT_RELPATH are in both BASE_NODE and WORKING_NODE,
- this function can be used to union those two sets, returning the set
- in *CHILDREN (allocated in RESULT_POOL). */
-static svn_error_t *
-union_children(const apr_array_header_t **children,
- svn_sqlite__db_t *sdb,
- apr_int64_t wc_id,
- const char *parent_relpath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- /* ### it would be nice to pre-size this hash table. */
- apr_hash_t *names = apr_hash_make(scratch_pool);
-#ifdef SVN_WC__NODES
- apr_hash_t *names_nodes = apr_hash_make(scratch_pool);
-#endif
- apr_array_header_t *names_array;
-
- /* All of the names get allocated in RESULT_POOL. */
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR(add_children_to_hash(names, STMT_SELECT_BASE_NODE_CHILDREN,
- sdb, wc_id, parent_relpath, result_pool));
- SVN_ERR(add_children_to_hash(names, STMT_SELECT_WORKING_NODE_CHILDREN,
- sdb, wc_id, parent_relpath, result_pool));
-#endif
-#ifdef SVN_WC__NODES
- SVN_ERR(add_children_to_hash(names_nodes, STMT_SELECT_BASE_NODE_CHILDREN_1,
- sdb, wc_id, parent_relpath, result_pool));
- SVN_ERR(add_children_to_hash(names_nodes,
STMT_SELECT_WORKING_NODE_CHILDREN_1,
- sdb, wc_id, parent_relpath, result_pool));
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR_ASSERT(apr_hash_count(names) == apr_hash_count(names_nodes));
-#else
- names = names_nodes;
-#endif
-#endif
-
- SVN_ERR(svn_hash_keys(&names_array, names, result_pool));
- *children = names_array;
-
- return SVN_NO_ERROR;
-}
-
-
-/* Return all the children of PARENT_RELPATH from a single table, implicitly
- defined by STMT_IDX. If the caller happens to know the count of children,
- it should be passed as START_SIZE to pre-allocate space in the *CHILDREN
- return value.
-
- If the caller doesn't know the count, then it should pass a reasonable
- idea of how many children may be present. */
-static svn_error_t *
-single_table_children(const apr_array_header_t **children,
- int stmt_idx,
- int start_size,
- svn_sqlite__db_t *sdb,
- apr_int64_t wc_id,
- const char *parent_relpath,
- apr_pool_t *result_pool)
-{
- svn_sqlite__stmt_t *stmt;
- apr_array_header_t *child_names;
- svn_boolean_t have_row;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, stmt_idx));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, parent_relpath));
-
- /* ### should test the node to ensure it is a directory */
-
- child_names = apr_array_make(result_pool, start_size, sizeof(const char *));
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- while (have_row)
- {
- const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
-
- APR_ARRAY_PUSH(child_names, const char *) =
- svn_relpath_basename(child_relpath, result_pool);
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- }
-
- *children = child_names;
-
- return svn_sqlite__reset(stmt);
-}
-
-
/* Return in *CHILDREN all of the children of the directory LOCAL_ABSPATH.
If BASE_ONLY is true, then *only* the children from BASE_NODE are
returned (those in WORKING_NODE are ignored). The result children are
@@ -1389,12 +1282,13 @@ gather_children(const apr_array_header_t
{
svn_wc__db_pdh_t *pdh;
const char *local_relpath;
- int base_count;
- int working_count;
+ apr_hash_t *names_hash = apr_hash_make(scratch_pool);
+#ifndef SVN_WC__NODES_ONLY
+#endif
#ifdef SVN_WC__NODES
- int base_count_nodes, working_count_nodes;
- const apr_array_header_t *children_nodes;
+ apr_hash_t *names_hash_1 = apr_hash_make(scratch_pool);
#endif
+ apr_array_header_t *names_array;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1404,111 +1298,35 @@ gather_children(const apr_array_header_t
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- if (base_only)
- {
- /* 10 is based on Subversion's average of 8.7 files per versioned
- directory in its repository.
-
- ### note "files". should redo count with subdirs included */
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR(single_table_children(children, STMT_SELECT_BASE_NODE_CHILDREN,
- 10 /* start_size */,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
-#endif
-#ifdef SVN_WC__NODES
- SVN_ERR(single_table_children(&children_nodes,
- STMT_SELECT_BASE_NODE_CHILDREN_1,
- 10 /* start_size */,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
+ /* All of the names get allocated in RESULT_POOL. */
#ifndef SVN_WC__NODES_ONLY
- SVN_ERR_ASSERT((*children)->nelts == children_nodes->nelts);
-#else
- *children = children_nodes;
-#endif
-#endif
- return SVN_NO_ERROR;
- }
+ SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_BASE_NODE_CHILDREN,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+ if (! base_only)
+ SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_WORKING_NODE_CHILDREN,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR(count_children(&base_count, STMT_COUNT_BASE_NODE_CHILDREN,
- pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
- SVN_ERR(count_children(&working_count, STMT_COUNT_WORKING_NODE_CHILDREN,
- pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
#endif
#ifdef SVN_WC__NODES
- SVN_ERR(count_children(&base_count_nodes, STMT_COUNT_BASE_NODE_CHILDREN_1,
- pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
- SVN_ERR(count_children(&working_count_nodes,
- STMT_COUNT_WORKING_NODE_CHILDREN_1,
- pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(add_children_to_hash(names_hash_1, STMT_SELECT_BASE_NODE_CHILDREN_1,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+ if (! base_only)
+ SVN_ERR(add_children_to_hash(names_hash_1,
STMT_SELECT_WORKING_NODE_CHILDREN_1,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
#ifndef SVN_WC__NODES_ONLY
- SVN_ERR_ASSERT(base_count == base_count_nodes);
- SVN_ERR_ASSERT(working_count == working_count_nodes);
+ SVN_ERR_ASSERT(apr_hash_count(names_hash) == apr_hash_count(names_hash_1));
#else
- base_count = base_count_nodes;
- working_count = working_count_nodes;
+ names_hash = names_hash_1;
#endif
#endif
- if (base_count == 0)
- {
- if (working_count == 0)
- {
- *children = apr_array_make(result_pool, 0, sizeof(const char *));
- return SVN_NO_ERROR;
- }
-
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR(single_table_children(children,
STMT_SELECT_WORKING_NODE_CHILDREN,
- working_count,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
-#endif
-#ifdef SVN_WC__NODES
- SVN_ERR(single_table_children(&children_nodes,
- STMT_SELECT_WORKING_NODE_CHILDREN_1,
- working_count,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR_ASSERT((*children)->nelts == children_nodes->nelts);
-#else
- *children = children_nodes;
-#endif
-#endif
- return SVN_NO_ERROR;
- }
- if (working_count == 0)
- {
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR(single_table_children(children, STMT_SELECT_BASE_NODE_CHILDREN,
- base_count,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
-#endif
-#ifdef SVN_WC__NODES
- SVN_ERR(single_table_children(&children_nodes,
- STMT_SELECT_BASE_NODE_CHILDREN_1,
- base_count,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
-#ifndef SVN_WC__NODES_ONLY
- SVN_ERR_ASSERT((*children)->nelts == children_nodes->nelts);
-#else
- *children = children_nodes;
-#endif
-#endif
- return SVN_NO_ERROR;
- }
-
- /* ### it would be nice to pass BASE_COUNT and WORKING_COUNT, but there is
- ### nothing union_children() can do with those. */
- return svn_error_return(union_children(children,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath,
- result_pool, scratch_pool));
+ SVN_ERR(svn_hash_keys(&names_array, names_hash, result_pool));
+ *children = names_array;
+ return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/cmdline/diff_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/diff_tests.py?rev=1004280&r1=1004279&r2=1004280&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/diff_tests.py Mon Oct 4 15:11:45
2010
@@ -2409,8 +2409,12 @@ def diff_repos_wc_add_with_props(sbox):
diff_X_bar_base_r3 = make_diff_header("X/bar", "revision 0",
"revision 3") + diff_X_bar
- expected_output_r1_base = diff_X_r1_base + diff_X_bar_r1_base +
diff_foo_r1_base
- expected_output_base_r3 = diff_foo_base_r3 + diff_X_bar_base_r3 +
diff_X_base_r3
+ expected_output_r1_base = svntest.verify.UnorderedOutput(diff_X_r1_base +
+ diff_X_bar_r1_base +
+ diff_foo_r1_base)
+ expected_output_base_r3 = svntest.verify.UnorderedOutput(diff_foo_base_r3 +
+ diff_X_bar_base_r3 +
+ diff_X_base_r3)
os.chdir(sbox.wc_dir)