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