You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/04/12 02:23:00 UTC
svn commit: r1091261 - in /subversion/trunk/subversion/libsvn_wc: adm_ops.c
wc_db.c wc_db.h
Author: hwright
Date: Tue Apr 12 00:22:59 2011
New Revision: 1091261
URL: http://svn.apache.org/viewvc?rev=1091261&view=rev
Log:
Do changelist filtering in the database, rather than outside of it, when
setting changelists. This is not yet a recursive query, so there may be a
smidge of additional overhead.
* subversion/libsvn_wc/adm_ops.c
(svn_wc_set_changelist2): Don't filter by changelist, just pass the filter
list down to wc_db.
* subversion/libsvn_wc/wc_db.c
(construct_filter): New.
(set_changelist_baton_t): New.
(set_changelist_txn): If the list of changelists to filter on is of non-zero
length, add an additional clause to to the update statement to filter via
changelist.
(svn_wc__db_op_set_changelist): Update the type of the changelist filter,
and use the new baton.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_op_set_changelist): Update param type.
Modified:
subversion/trunk/subversion/libsvn_wc/adm_ops.c
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1091261&r1=1091260&r2=1091261&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue Apr 12 00:22:59 2011
@@ -2123,17 +2123,6 @@ svn_wc_set_changelist2(svn_wc_context_t
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- if (changelists && changelists->nelts)
- {
- apr_hash_t *changelist_hash;
-
- SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists,
- scratch_pool));
- if (! svn_wc__changelist_match(wc_ctx, local_abspath, changelist_hash,
- scratch_pool))
- return SVN_NO_ERROR;
- }
-
SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&existing_changelist,
@@ -2150,7 +2139,8 @@ svn_wc_set_changelist2(svn_wc_context_t
/* Set the changelist. */
SVN_ERR(svn_wc__db_op_set_changelist(wc_ctx->db, local_abspath, changelist,
- NULL, svn_depth_empty, scratch_pool));
+ changelists, svn_depth_empty,
+ scratch_pool));
/* And tell someone what we've done. */
if (notify_func)
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1091261&r1=1091260&r2=1091261&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Apr 12 00:22:59 2011
@@ -55,6 +55,8 @@
#define NOT_IMPLEMENTED() SVN__NOT_IMPLEMENTED()
+WC_QUERIES_SQL_DECLARE_STATEMENTS(statements);
+
/*
* Some filename constants.
@@ -427,6 +429,31 @@ static const char *construct_like_arg(co
}
+/* Construct a clause to be used as a filter, of the form:
+ * COLUMN in (LIST[0], LIST[1], LIST[2], ..., LIST[N]).
+ *
+ * Allocate the result either statically or in RESULT_POOL. */
+static const char *
+construct_filter(const char *column_name,
+ const apr_array_header_t *list,
+ apr_pool_t *result_pool)
+{
+ svn_stringbuf_t *clause;
+ int i;
+
+ if (!list || list->nelts == 0)
+ return "";
+
+ clause = svn_stringbuf_createf(result_pool, "%s IN (?", column_name);
+
+ for (i = 1; i < list->nelts; i++)
+ svn_stringbuf_appendcstr(clause, ", ?");
+ svn_stringbuf_appendcstr(clause, ")");
+
+ return clause->data;
+}
+
+
/* Look up REPOS_ID in SDB and set *REPOS_ROOT_URL and/or *REPOS_UUID to
its root URL and UUID respectively. If REPOS_ID is INVALID_REPOS_ID,
use NULL for both URL and UUID. Either or both output parameters may be
@@ -3385,6 +3412,13 @@ svn_wc__db_op_modified(svn_wc__db_t *db,
}
+struct set_changelist_baton_t
+{
+ const char *new_changelist;
+ const apr_array_header_t *changelists;
+};
+
+
/* */
static svn_error_t *
set_changelist_txn(void *baton,
@@ -3392,21 +3426,28 @@ set_changelist_txn(void *baton,
const char *local_relpath,
apr_pool_t *scratch_pool)
{
- const char *new_changelist = baton;
+ struct set_changelist_baton_t *scb = baton;
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_ACTUAL_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- SVN_ERR(svn_sqlite__reset(stmt));
+ /* If we are filtering based on changelists, we *must* already have nodes,
+ * so we can skip this check. */
+ if (scb->changelists && scb->changelists->nelts > 0)
+ have_row = TRUE;
+ else
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_ACTUAL_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
+ }
if (!have_row)
{
/* We need to insert an ACTUAL node, but only if we're not attempting
to remove a (non-existent) changelist. */
- if (new_changelist == NULL)
+ if (scb->new_changelist == NULL)
return SVN_NO_ERROR;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -3421,16 +3462,42 @@ set_changelist_txn(void *baton,
}
else
{
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_UPDATE_ACTUAL_CHANGELIST));
+ const char *stmt_text = statements[STMT_UPDATE_ACTUAL_CHANGELIST];
+ const char *filter = construct_filter("changelist",
+ scb->changelists,
+ scratch_pool);
+
+ if (*filter)
+ stmt_text = apr_pstrcat(scratch_pool, stmt_text, " AND ", filter,
+ NULL);
+
+ SVN_ERR(svn_sqlite__prepare(&stmt, wcroot->sdb, stmt_text,
+ scratch_pool));
+
+ /* If we have a filter, it means we need to bind the changelist
+ params. */
+ if (*filter)
+ {
+ int i;
+
+ for (i = 0; i < scb->changelists->nelts; i++)
+ {
+ const char *cl = APR_ARRAY_IDX(scb->changelists, i,
+ const char *);
+
+ /* The magic number '4' here is the number of existing params,
+ plus 1, in the statement, which will be bound below. */
+ SVN_ERR(svn_sqlite__bind_text(stmt, i+4, cl));
+ }
+ }
}
/* Run the update or insert query */
SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
- new_changelist));
+ scb->new_changelist));
SVN_ERR(svn_sqlite__step_done(stmt));
- if (new_changelist == NULL)
+ if (scb->new_changelist == NULL)
{
/* When removing a changelist, we may have left an empty ACTUAL node, so
remove it. */
@@ -3448,13 +3515,14 @@ svn_error_t *
svn_wc__db_op_set_changelist(svn_wc__db_t *db,
const char *local_abspath,
const char *changelist,
- const apr_hash_t *changelists,
+ const apr_array_header_t *changelists,
svn_depth_t depth,
apr_pool_t *scratch_pool)
{
svn_wc__db_txn_callback_t txn_func;
svn_wc__db_wcroot_t *wcroot;
const char *local_relpath;
+ struct set_changelist_baton_t scb = { changelist, changelists };
svn_error_t *err;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -3483,7 +3551,7 @@ svn_wc__db_op_set_changelist(svn_wc__db_
STMT_DROP_CHANGELIST_LIST_TRIGGERS));
err = svn_wc__db_with_txn(wcroot, local_relpath, set_changelist_txn,
- (void *) changelist, scratch_pool);
+ &scb, scratch_pool);
err = svn_error_compose_create(err,
svn_sqlite__exec_statements(wcroot->sdb,
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1091261&r1=1091260&r2=1091261&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Tue Apr 12 00:22:59 2011
@@ -1203,7 +1203,7 @@ svn_error_t *
svn_wc__db_op_set_changelist(svn_wc__db_t *db,
const char *local_abspath,
const char *changelist,
- const apr_hash_t *changelists,
+ const apr_array_header_t *changelists,
svn_depth_t depth,
apr_pool_t *scratch_pool);