subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1559758 - in /subversion/trunk/subversion: include/private/svn_io_private.h libsvn_subr/stream.c libsvn_wc/workqueue.c
Date Mon, 20 Jan 2014 16:00:34 GMT
Author: rhuijben
Date: Mon Jan 20 16:00:33 2014
New Revision: 1559758

URL: http://svn.apache.org/r1559758
Log:
For issue #4450 "Windows checkouts much slower then Unix" create a private api
around installing a file, to prepare for an optimized Windows implementation
that reduces a lot of disk IO delays during update and checkout.

* subversion/include/private/svn_io_private.h
  (svn_stream__create_for_install): New function.
  (svn_stream__install_stream): New function.

* subversion/libsvn_subr/stream.c
  (install_baton_t): New struct.
  (svn_stream__create_for_install): New function.
  (svn_stream__install_stream): New function.

* subversion/libsvn_wc/workqueue.c
  (includes): Add private/svn_io_private.h.
  (run_file_install): Update caller.

Modified:
    subversion/trunk/subversion/include/private/svn_io_private.h
    subversion/trunk/subversion/libsvn_subr/stream.c
    subversion/trunk/subversion/libsvn_wc/workqueue.c

Modified: subversion/trunk/subversion/include/private/svn_io_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_io_private.h?rev=1559758&r1=1559757&r2=1559758&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_io_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_io_private.h Mon Jan 20 16:00:33 2014
@@ -105,6 +105,29 @@ svn_stream__is_buffered(svn_stream_t *st
 apr_file_t *
 svn_stream__aprfile(svn_stream_t *stream);
 
+/* Creates as *INSTALL_STREAM a stream that once completed can be installed
+   using Windows checkouts much slower then Unix.
+
+   While writing the stream is temporarily stored in TMP_ABSPATH.
+ */
+svn_error_t *
+svn_stream__create_for_install(svn_stream_t **install_stream,
+                               const char *tmp_abspath,
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool);
+
+/* Installs a stream created with svn_stream__create_for_install in its final
+   location FINAL_ABSPATH, potentially using platform specific optimizations.
+
+   If MAKE_PARENTS is TRUE, this function will create missing parent
+   directories if needed.
+ */
+svn_error_t *
+svn_stream__install_stream(svn_stream_t *install_stream,
+                           const char *final_abspath,
+                           svn_boolean_t make_parents,
+                           apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/trunk/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/stream.c?rev=1559758&r1=1559757&r2=1559758&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/stream.c (original)
+++ subversion/trunk/subversion/libsvn_subr/stream.c Mon Jan 20 16:00:33 2014
@@ -1860,3 +1860,78 @@ svn_stream_lazyopen_create(svn_stream_la
 
   return stream;
 }
+
+/* Baton for install streams */
+struct install_baton_t
+{
+  struct baton_apr baton_apr;
+  const char *tmp_path;
+};
+
+svn_error_t *
+svn_stream__create_for_install(svn_stream_t **install_stream,
+                               const char *tmp_abspath,
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
+{
+  apr_file_t *file;
+  struct install_baton_t *ib;
+  const char *tmp_path;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(tmp_abspath));
+
+  SVN_ERR(svn_io_open_unique_file3(&file, &tmp_path, tmp_abspath,
+                                   svn_io_file_del_none,
+                                   result_pool, scratch_pool));
+  *install_stream = svn_stream_from_aprfile2(file, FALSE, result_pool);
+
+  ib = apr_pcalloc(result_pool, sizeof(*ib));
+  ib->baton_apr = *(struct baton_apr*)(*install_stream)->baton;
+
+  assert((void*)&ib->baton_apr == (void*)ib);
+
+  (*install_stream)->baton = ib;
+
+  ib->tmp_path = tmp_path;
+
+  /* ### Install pool cleanup handler for tempfile? */
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_stream__install_stream(svn_stream_t *install_stream,
+                           const char *final_abspath,
+                           svn_boolean_t make_parents,
+                           apr_pool_t *scratch_pool)
+{
+  struct install_baton_t *ib = install_stream->baton;
+  svn_error_t *err;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(final_abspath));
+
+  err = svn_io_file_rename(ib->tmp_path, final_abspath, scratch_pool);
+
+  /* A missing directory is too common to not cover here. */
+  if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
+    {
+      svn_error_t *err2;
+
+      err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
+                                                            scratch_pool),
+                                         scratch_pool);
+
+      if (err2)
+        /* Creating directory didn't work: Return all errors */
+        return svn_error_trace(svn_error_compose_create(err, err2));
+      else
+        /* We could create a directory: retry install */
+        svn_error_clear(err);
+
+      SVN_ERR(svn_io_file_rename(ib->tmp_path, final_abspath, scratch_pool));
+    }
+  else
+    SVN_ERR(err);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1559758&r1=1559757&r2=1559758&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Mon Jan 20 16:00:33 2014
@@ -38,6 +38,7 @@
 #include "conflicts.h"
 #include "translate.h"
 
+#include "private/svn_io_private.h"
 #include "private/svn_skel.h"
 
 
@@ -469,7 +470,6 @@ run_file_install(work_item_baton_t *wqb,
   apr_hash_t *keywords;
   const char *temp_dir_abspath;
   svn_stream_t *dst_stream;
-  const char *dst_abspath;
   apr_int64_t val;
   const char *wcroot_abspath;
   const char *source_abspath;
@@ -572,10 +572,8 @@ run_file_install(work_item_baton_t *wqb,
   /* Translate to a temporary file. We don't want the user seeing a partial
      file, nor let them muck with it while we translate. We may also need to
      get its TRANSLATED_SIZE before the user can monkey it.  */
-  SVN_ERR(svn_stream_open_unique(&dst_stream, &dst_abspath,
-                                 temp_dir_abspath,
-                                 svn_io_file_del_none,
-                                 scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream__create_for_install(&dst_stream, temp_dir_abspath,
+                                         scratch_pool, scratch_pool));
 
   /* Copy from the source to the dest, translating as we go. This will also
      close both streams.  */
@@ -584,35 +582,11 @@ run_file_install(work_item_baton_t *wqb,
                            scratch_pool));
 
   /* All done. Move the file into place.  */
-
-  {
-    svn_error_t *err;
-
-    err = svn_io_file_rename(dst_abspath, local_abspath, scratch_pool);
-
-    /* With a single db we might want to install files in a missing directory.
-       Simply trying this scenario on error won't do any harm and at least
-       one user reported this problem on IRC. */
-    if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-      {
-        svn_error_t *err2;
-
-        err2 = svn_io_make_dir_recursively(svn_dirent_dirname(local_abspath,
-                                                              scratch_pool),
-                                           scratch_pool);
-
-        if (err2)
-          /* Creating directory didn't work: Return all errors */
-          return svn_error_trace(svn_error_compose_create(err, err2));
-        else
-          /* We could create a directory: retry install */
-          svn_error_clear(err);
-
-        SVN_ERR(svn_io_file_rename(dst_abspath, local_abspath, scratch_pool));
-      }
-    else
-      SVN_ERR(err);
-  }
+  /* With a single db we might want to install files in a missing directory.
+     Simply trying this scenario on error won't do any harm and at least
+     one user reported this problem on IRC. */
+  SVN_ERR(svn_stream__install_stream(dst_stream, local_abspath,
+                                     TRUE /* make_parents*/, scratch_pool));
 
   /* Tweak the on-disk file according to its properties.  */
 #ifndef WIN32



Mime
View raw message