Author: rhuijben
Date: Sun Feb 24 20:36:40 2013
New Revision: 1449546

URL: http://svn.apache.org/r1449546
Log:
Allow workqueue items to queue the recording of timestamps and sizes
until we already have a db write transaction open to mark the current
item as completed.

This saves at least 5% of every checkout on my testruns, which run on
a ramdrive. On harddisks or network drives the difference would be much
larger. (Assuming a very fast and/or local repository).

* subversion/libsvn_wc/workqueue.c
  (work_item_baton_t): Add typedef.
  (work_item_dispatch): Add argument to all workqueue functions.
  (get_and_record_fileinfo): Change into prototype of function later
    in the file. Take baton instead of db argument.

  (run_base_remove,
   run_file_commit,
   run_postupgrade): Update arguments.

  (run_file_install): Update arguments. Update caller.

  (run_file_remove,
   run_dir_remove,
   run_file_move,
   run_file_copy_translated,
   run_dir_install,
   run_sync_file_flags,
   run_prej_install): Update arguments.

  (run_record_fileinfo): Update arguments. Update caller.

  (run_set_text_conflict_markers,
   run_set_property_conflict_marker): Update arguments.

  (dispatch_work_item): Update caller.
  (svn_wc__wq_run): Create baton. Check if we should call the normal or the
    extended svn_wc__db_wq_fetch_next. Update caller.

  (get_and_record_fileinfo): New function.

Modified:
    subversion/trunk/subversion/libsvn_wc/workqueue.c

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1449546&r1=1449545&r2=1449546&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Sun Feb 24 20:36:40 2013
@@ -63,10 +63,12 @@
 /* For work queue debugging. Generates output about its operation.  */
 /* #define SVN_DEBUG_WORK_QUEUE */
 
+typedef struct work_item_baton_t work_item_baton_t;
 
 struct work_item_dispatch {
   const char *name;
-  svn_error_t *(*func)(svn_wc__db_t *db,
+  svn_error_t *(*func)(work_item_baton_t *wqb,
+                       svn_wc__db_t *db,
                        const svn_skel_t *work_item,
                        const char *wri_abspath,
                        svn_cancel_func_t cancel_func,
@@ -74,30 +76,12 @@ struct work_item_dispatch {
                        apr_pool_t *scratch_pool);
 };
 
-
+/* Forward definition */
 static svn_error_t *
-get_and_record_fileinfo(svn_wc__db_t *db,
+get_and_record_fileinfo(work_item_baton_t *wqb,
                         const char *local_abspath,
                         svn_boolean_t ignore_enoent,
-                        apr_pool_t *scratch_pool)
-{
-  const svn_io_dirent2_t *dirent;
-
-  SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, ignore_enoent,
-                             scratch_pool, scratch_pool));
-
-  if (dirent->kind == svn_node_none)
-    {
-      /* Skip file not found if ignore_enoent */
-      return SVN_NO_ERROR;
-    }
-
-  return svn_error_trace(svn_wc__db_global_record_fileinfo(
-                           db, local_abspath,
-                           dirent->filesize, dirent->mtime,
-                           scratch_pool));
-}
-
+                        apr_pool_t *scratch_pool);
 
 /* ------------------------------------------------------------------------ */
 /* OP_REMOVE_BASE  */
@@ -111,7 +95,8 @@ get_and_record_fileinfo(svn_wc__db_t *db
  * See svn_wc__wq_build_remove_base() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_base_remove(svn_wc__db_t *db,
+run_base_remove(work_item_baton_t *wqb,
+                svn_wc__db_t *db,
                 const svn_skel_t *work_item,
                 const char *wri_abspath,
                 svn_cancel_func_t cancel_func,
@@ -349,7 +334,8 @@ process_commit_file_install(svn_wc__db_t
 
 
 static svn_error_t *
-run_file_commit(svn_wc__db_t *db,
+run_file_commit(work_item_baton_t *wqb,
+                svn_wc__db_t *db,
                 const svn_skel_t *work_item,
                 const char *wri_abspath,
                 svn_cancel_func_t cancel_func,
@@ -397,7 +383,8 @@ svn_wc__wq_build_file_commit(svn_skel_t 
 /* OP_POSTUPGRADE  */
 
 static svn_error_t *
-run_postupgrade(svn_wc__db_t *db,
+run_postupgrade(work_item_baton_t *wqb,
+                svn_wc__db_t *db,
                 const svn_skel_t *work_item,
                 const char *wri_abspath,
                 svn_cancel_func_t cancel_func,
@@ -465,7 +452,8 @@ svn_wc__wq_build_postupgrade(svn_skel_t 
  * See svn_wc__wq_build_file_install() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_file_install(svn_wc__db_t *db,
+run_file_install(work_item_baton_t *wqb,
+                 svn_wc__db_t *db,
                  const svn_skel_t *work_item,
                  const char *wri_abspath,
                  svn_cancel_func_t cancel_func,
@@ -665,7 +653,7 @@ run_file_install(svn_wc__db_t *db,
   /* ### this should happen before we rename the file into place.  */
   if (record_fileinfo)
     {
-      SVN_ERR(get_and_record_fileinfo(db, local_abspath,
+      SVN_ERR(get_and_record_fileinfo(wqb, local_abspath,
                                       FALSE /* ignore_enoent */,
                                       scratch_pool));
     }
@@ -717,12 +705,13 @@ svn_wc__wq_build_file_install(svn_skel_t
  * See svn_wc__wq_build_file_remove() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_file_remove(svn_wc__db_t *db,
-                 const svn_skel_t *work_item,
-                 const char *wri_abspath,
-                 svn_cancel_func_t cancel_func,
-                 void *cancel_baton,
-                 apr_pool_t *scratch_pool)
+run_file_remove(work_item_baton_t *wqb,
+                svn_wc__db_t *db,
+                const svn_skel_t *work_item,
+                const char *wri_abspath,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg1 = work_item->children->next;
   const char *local_relpath;
@@ -766,7 +755,8 @@ svn_wc__wq_build_file_remove(svn_skel_t 
  * See svn_wc__wq_build_file_remove() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_dir_remove(svn_wc__db_t *db,
+run_dir_remove(work_item_baton_t *wqb,
+               svn_wc__db_t *db,
                const svn_skel_t *work_item,
                const char *wri_abspath,
                svn_cancel_func_t cancel_func,
@@ -847,12 +837,13 @@ svn_wc__wq_build_dir_remove(svn_skel_t *
  * See svn_wc__wq_build_file_move() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_file_move(svn_wc__db_t *db,
-                 const svn_skel_t *work_item,
-                 const char *wri_abspath,
-                 svn_cancel_func_t cancel_func,
-                 void *cancel_baton,
-                 apr_pool_t *scratch_pool)
+run_file_move(work_item_baton_t *wqb,
+              svn_wc__db_t *db,
+              const svn_skel_t *work_item,
+              const char *wri_abspath,
+              svn_cancel_func_t cancel_func,
+              void *cancel_baton,
+              apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg1 = work_item->children->next;
   const char *src_abspath, *dst_abspath;
@@ -929,7 +920,8 @@ svn_wc__wq_build_file_move(svn_skel_t **
  * See run_file_copy_translated() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_file_copy_translated(svn_wc__db_t *db,
+run_file_copy_translated(work_item_baton_t *wqb,
+                         svn_wc__db_t *db,
                          const svn_skel_t *work_item,
                          const char *wri_abspath,
                          svn_cancel_func_t cancel_func,
@@ -1023,12 +1015,13 @@ svn_wc__wq_build_file_copy_translated(sv
 /* OP_DIRECTORY_INSTALL  */
 
 static svn_error_t *
-run_dir_install(svn_wc__db_t *db,
-                    const svn_skel_t *work_item,
-                    const char *wri_abspath,
-                    svn_cancel_func_t cancel_func,
-                    void *cancel_baton,
-                    apr_pool_t *scratch_pool)
+run_dir_install(work_item_baton_t *wqb,
+                svn_wc__db_t *db,
+                const svn_skel_t *work_item,
+                const char *wri_abspath,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg1 = work_item->children->next;
   const char *local_relpath;
@@ -1072,7 +1065,8 @@ svn_wc__wq_build_dir_install(svn_skel_t 
  * See svn_wc__wq_build_sync_file_flags() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_sync_file_flags(svn_wc__db_t *db,
+run_sync_file_flags(work_item_baton_t *wqb,
+                    svn_wc__db_t *db,
                     const svn_skel_t *work_item,
                     const char *wri_abspath,
                     svn_cancel_func_t cancel_func,
@@ -1117,7 +1111,8 @@ svn_wc__wq_build_sync_file_flags(svn_ske
 /* OP_PREJ_INSTALL  */
 
 static svn_error_t *
-run_prej_install(svn_wc__db_t *db,
+run_prej_install(work_item_baton_t *wqb,
+                 svn_wc__db_t *db,
                  const svn_skel_t *work_item,
                  const char *wri_abspath,
                  svn_cancel_func_t cancel_func,
@@ -1196,7 +1191,8 @@ svn_wc__wq_build_prej_install(svn_skel_t
 
 
 static svn_error_t *
-run_record_fileinfo(svn_wc__db_t *db,
+run_record_fileinfo(work_item_baton_t *wqb,
+                    svn_wc__db_t *db,
                     const svn_skel_t *work_item,
                     const char *wri_abspath,
                     svn_cancel_func_t cancel_func,
@@ -1241,7 +1237,7 @@ run_record_fileinfo(svn_wc__db_t *db,
     }
 
 
-  return svn_error_trace(get_and_record_fileinfo(db, local_abspath,
+  return svn_error_trace(get_and_record_fileinfo(wqb, local_abspath,
                                                  TRUE /* ignore_enoent */,
                                                  scratch_pool));
 }
@@ -1252,12 +1248,13 @@ run_record_fileinfo(svn_wc__db_t *db,
 
 
 static svn_error_t *
-run_set_text_conflict_markers(svn_wc__db_t *db,
-                    const svn_skel_t *work_item,
-                    const char *wri_abspath,
-                    svn_cancel_func_t cancel_func,
-                    void *cancel_baton,
-                    apr_pool_t *scratch_pool)
+run_set_text_conflict_markers(work_item_baton_t *wqb,
+                              svn_wc__db_t *db,
+                              const svn_skel_t *work_item,
+                              const char *wri_abspath,
+                              svn_cancel_func_t cancel_func,
+                              void *cancel_baton,
+                              apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg = work_item->children->next;
   const char *local_relpath;
@@ -1346,7 +1343,8 @@ run_set_text_conflict_markers(svn_wc__db
 /* OP_TMP_SET_PROPERTY_CONFLICT_MARKER  */
 
 static svn_error_t *
-run_set_property_conflict_marker(svn_wc__db_t *db,
+run_set_property_conflict_marker(work_item_baton_t *wqb,
+                                 svn_wc__db_t *db,
                                  const svn_skel_t *work_item,
                                  const char *wri_abspath,
                                  svn_cancel_func_t cancel_func,
@@ -1432,9 +1430,19 @@ static const struct work_item_dispatch d
   { NULL }
 };
 
+struct work_item_baton_t
+{
+  apr_pool_t *result_pool; /* Pool to allocate result in */
+
+  svn_boolean_t used; /* needs reset */
+
+  apr_hash_t *record_map; /* const char * -> svn_io_dirent2_t map */
+};
+
 
 static svn_error_t *
-dispatch_work_item(svn_wc__db_t *db,
+dispatch_work_item(work_item_baton_t *wqb,
+                   svn_wc__db_t *db,
                    const char *wri_abspath,
                    const svn_skel_t *work_item,
                    svn_cancel_func_t cancel_func,
@@ -1452,7 +1460,7 @@ dispatch_work_item(svn_wc__db_t *db,
 #ifdef SVN_DEBUG_WORK_QUEUE
           SVN_DBG(("dispatch: operation='%s'\n", scan->name));
 #endif
-          SVN_ERR((*scan->func)(db, work_item, wri_abspath,
+          SVN_ERR((*scan->func)(wqb, db, work_item, wri_abspath,
                                 cancel_func, cancel_baton,
                                 scratch_pool));
 
@@ -1497,6 +1505,8 @@ svn_wc__wq_run(svn_wc__db_t *db,
 {
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_uint64_t last_id = 0;
+  work_item_baton_t wib = { 0 };
+  wib.result_pool = svn_pool_create(scratch_pool);
 
 #ifdef SVN_DEBUG_WORK_QUEUE
   SVN_DBG(("wq_run: wri='%s'\n", wri_abspath));
@@ -1517,11 +1527,29 @@ svn_wc__wq_run(svn_wc__db_t *db,
 
       svn_pool_clear(iterpool);
 
-      /* Make sure to do this *early* in the loop iteration. There may
-         be a LAST_ID that needs to be marked as completed, *before* we
-         start worrying about anything else.  */
-      SVN_ERR(svn_wc__db_wq_fetch_next(&id, &work_item, db, wri_abspath,
-                                       last_id, iterpool, iterpool));
+      if (! wib.used)
+        {
+          /* Make sure to do this *early* in the loop iteration. There may
+             be a LAST_ID that needs to be marked as completed, *before* we
+             start worrying about anything else.  */
+          SVN_ERR(svn_wc__db_wq_fetch_next(&id, &work_item, db, wri_abspath,
+                                           last_id, iterpool, iterpool));
+        }
+      else
+        {
+          /* Make sure to do this *early* in the loop iteration. There may
+             be a LAST_ID that needs to be marked as completed, *before* we
+             start worrying about anything else.  */
+          SVN_ERR(svn_wc__db_wq_record_and_fetch_next(&id, &work_item,
+                                                      db, wri_abspath,
+                                                      last_id, wib.record_map,
+                                                      iterpool,
+                                                      wib.result_pool));
+
+          svn_pool_clear(wib.result_pool);
+          wib.record_map = NULL;
+          wib.used = FALSE;
+        }
 
       /* Stop work queue processing, if requested. A future 'svn cleanup'
          should be able to continue the processing. Note that we may
@@ -1534,7 +1562,7 @@ svn_wc__wq_run(svn_wc__db_t *db,
       if (work_item == NULL)
         break;
 
-      err = dispatch_work_item(db, wri_abspath, work_item,
+      err = dispatch_work_item(&wib, db, wri_abspath, work_item,
                                cancel_func, cancel_baton, iterpool);
       if (err)
         {
@@ -1604,3 +1632,29 @@ svn_wc__wq_merge(svn_skel_t *work_item1,
   svn_skel__append(work_item1, work_item2->children);
   return work_item1;
 }
+
+
+static svn_error_t *
+get_and_record_fileinfo(work_item_baton_t *wqb,
+                        const char *local_abspath,
+                        svn_boolean_t ignore_enoent,
+                        apr_pool_t *scratch_pool)
+{
+  const svn_io_dirent2_t *dirent;
+
+  SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath, FALSE, ignore_enoent,
+                              wqb->result_pool, scratch_pool));
+
+  if (dirent->kind != svn_node_file)
+    return SVN_NO_ERROR;
+
+  wqb->used = TRUE;
+
+  if (! wqb->record_map)
+    wqb->record_map = apr_hash_make(wqb->result_pool);
+
+  svn_hash_sets(wqb->record_map, apr_pstrdup(wqb->result_pool, local_abspath),
+                dirent);
+
+  return SVN_NO_ERROR;
+}


Reply via email to