You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/05/23 10:58:45 UTC

svn commit: r1341797 - in /subversion/trunk/subversion: libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c libsvn_wc/wc_db.h tests/libsvn_wc/wc-queries-test.c

Author: rhuijben
Date: Wed May 23 08:58:45 2012
New Revision: 1341797

URL: http://svn.apache.org/viewvc?rev=1341797&view=rev
Log:
Avoid a table scan of ACTUAL_NODES for every directory during wc copy
operations by splitting a query into two separate queries that each
use the right index.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_CONFLICT_MARKER_FILES): Split this query into ...
  (STMT_SELECT_CONFLICT_MARKER_FILES1): ... this, for the directory and ...
  (STMT_SELECT_CONFLICT_MARKER_FILES2): ... this, for the nodes within.

* subversion/libsvn_wc/wc_db.c
  (get_conflict_marker_files): New function. Using two queries. Extracted
    from ...
  (svn_wc__db_get_conflict_marker_files): ... this function.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_get_conflict_marker_files): Remove obsolete comment.

* subversion/tests/libsvn_wc/wc-queries-test.c
  (slow_statements): Remove yet another statement from the slow list.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h
    subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1341797&r1=1341796&r2=1341797&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed May 23 08:58:45 2012
@@ -741,10 +741,17 @@ WHERE wc_id = ?1 AND parent_relpath = ?2
        AND (conflict_new IS NULL) AND (conflict_working IS NULL)
        AND (tree_conflict_data IS NULL))
 
--- STMT_SELECT_CONFLICT_MARKER_FILES
-SELECT prop_reject, conflict_old, conflict_new, conflict_working
+-- STMT_SELECT_CONFLICT_MARKER_FILES1
+SELECT prop_reject
 FROM actual_node
-WHERE wc_id = ?1 AND (local_relpath = ?2 OR parent_relpath = ?2)
+WHERE wc_id = ?1 AND local_relpath = ?2
+  AND ((prop_reject IS NOT NULL) OR (conflict_old IS NOT NULL)
+       OR (conflict_new IS NOT NULL) OR (conflict_working IS NOT NULL))
+
+-- STMT_SELECT_CONFLICT_MARKER_FILES2
+SELECT prop_reject
+FROM actual_node
+WHERE wc_id = ?1 AND parent_relpath = ?2
   AND ((prop_reject IS NOT NULL) OR (conflict_old IS NOT NULL)
        OR (conflict_new IS NOT NULL) OR (conflict_working IS NOT NULL))
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1341797&r1=1341796&r2=1341797&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed May 23 08:58:45 2012
@@ -11409,49 +11409,71 @@ svn_wc__db_read_conflict_victims(const a
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_wc__db_get_conflict_marker_files(apr_hash_t **marker_files,
-                                     svn_wc__db_t *db,
-                                     const char *local_abspath,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool)
+/* Locked implementation for svn_wc__db_get_conflict_marker_files */
+static svn_error_t *
+get_conflict_marker_files(void *baton, svn_wc__db_wcroot_t *wcroot,
+                          const char *local_relpath, apr_pool_t *scratch_pool)
 {
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+  apr_hash_t *marker_files = baton;
+  apr_pool_t *result_pool = apr_hash_pool_get(marker_files);
 
-  /* The parent should be a working copy directory. */
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
-                              local_abspath, scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
-
-  /* Look for text and property conflicts in ACTUAL */
+  /* Look for property conflicts on the directory in ACTUAL.
+     (A directory can't have text conflicts) */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_SELECT_CONFLICT_MARKER_FILES));
+                                    STMT_SELECT_CONFLICT_MARKER_FILES1));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
   if (have_row)
-    *marker_files = apr_hash_make(result_pool);
-  else
-    *marker_files = NULL;
-
-  while (have_row)
     {
-      /* Collect the basenames of any conflict marker files. */
       const char *marker_relpath;
       const char *base_name;
+
+      marker_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+
+      base_name = svn_relpath_skip_ancestor(local_relpath, marker_relpath);
+
+      /* Verify if the marker file is directly within LOCAL_ABSPATH */
+      if (base_name && svn_path_is_single_path_component(base_name))
+        {
+          base_name = apr_pstrdup(result_pool, base_name);
+          apr_hash_set(marker_files, base_name, APR_HASH_KEY_STRING,
+                       base_name);
+        }
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  /* Look for property and text conflicts on the direct children of
+     LOCAL_RELPATH, as both directories and files can have conflict
+     files in their parent directory */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_CONFLICT_MARKER_FILES2));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  while (have_row)
+    {
       int i;
 
       for (i = 0; i < 4; i++)
         {
-          marker_relpath = svn_sqlite__column_text(stmt, i, scratch_pool);
-          if (marker_relpath)
+          const char *marker_relpath;
+          const char *base_name;
+
+          marker_relpath = svn_sqlite__column_text(stmt, i, NULL);
+
+          if (!marker_relpath)
+            continue;
+
+          base_name = svn_relpath_skip_ancestor(local_relpath, marker_relpath);
+
+          /* Verify if the marker file is directly within LOCAL_ABSPATH */
+          if (base_name && svn_path_is_single_path_component(base_name))
             {
-              base_name = svn_relpath_basename(marker_relpath, result_pool);
-              apr_hash_set(*marker_files, base_name, APR_HASH_KEY_STRING,
+              base_name = apr_pstrdup(result_pool, base_name);
+              apr_hash_set(marker_files, base_name, APR_HASH_KEY_STRING,
                            base_name);
             }
         }
@@ -11459,7 +11481,36 @@ svn_wc__db_get_conflict_marker_files(apr
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
 
-  return svn_sqlite__reset(stmt);
+  return svn_error_trace(svn_sqlite__reset(stmt));
+}
+
+svn_error_t *
+svn_wc__db_get_conflict_marker_files(apr_hash_t **marker_files,
+                                     svn_wc__db_t *db,
+                                     const char *local_abspath,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+  apr_hash_t *markers;
+
+  /* The parent should be a working copy directory. */
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  markers = apr_hash_make(result_pool);
+
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, get_conflict_marker_files,
+                              markers, scratch_pool));
+
+  if (apr_hash_count(markers))
+    *marker_files = markers;
+  else
+    *marker_files = NULL;
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1341797&r1=1341796&r2=1341797&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed May 23 08:58:45 2012
@@ -2118,7 +2118,6 @@ svn_wc__db_read_conflict_victims(const a
 
    Allocate *MARKER_FILES in RESULT_POOL and do temporary allocations
    in SCRATCH_POOL */
-/* ### This function will probably be removed. */
 svn_error_t *
 svn_wc__db_get_conflict_marker_files(apr_hash_t **markers,
                                      svn_wc__db_t *db,

Modified: subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1341797&r1=1341796&r2=1341797&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c Wed May 23 08:58:45 2012
@@ -95,7 +95,6 @@ static const int slow_statements[] =
   STMT_SELECT_COMMITTABLE_EXTERNALS_BELOW,
   STMT_SELECT_EXTERNALS_DEFINED,
   STMT_SELECT_EXTERNAL_PROPERTIES,
-  STMT_SELECT_CONFLICT_MARKER_FILES,
   STMT_DELETE_ACTUAL_EMPTIES,
 
   /* Upgrade statements? */