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 2014/03/13 19:24:11 UTC

svn commit: r1577269 - in /subversion/trunk/subversion: include/private/ libsvn_subr/ libsvn_wc/ tests/libsvn_wc/

Author: rhuijben
Date: Thu Mar 13 18:24:10 2014
New Revision: 1577269

URL: http://svn.apache.org/r1577269
Log:
Switch the pristine file install code in libsvn_wc to using the recently added
install streams.

On Windows these streams avoid opening and closing the same file a few times,
which avoids influence from outside processes such as indexers and
virusscanners on the intermediate operations. In many corporate environments
with strict on access virusscanners (as well as on network drives) this
will hugely improve checkout times.

* subversion/include/private/svn_io_private.h
  (svn_stream__install_delete,
   svn_stream__install_get_info): New functions.

* subversion/libsvn_subr/stream.c
  (svn_stream__install_get_info,
   svn_stream__install_delete): New function.

* subversion/libsvn_wc/adm_crawler.c
  (svn_wc__internal_transmit_text_deltas): Update caller.

* subversion/libsvn_wc/externals.c
  (edit_baton): Store install data instead of path.
  (apply_textdelta,
   close_file): Update caller.

* subversion/libsvn_wc/update_editor.c
  (handler_baton): Add install data.
  (window_handler): Update caller. Remove now unused variable.
  (lazy_open_target): Update caller.
  (apply_textdelta): Pass final path for error information instead of the now
    completely hidden intermediate path.
  (svn_wc_add_repos_file4): Update caller. Extract local file handling.
    Remove obsolete comment.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_install_data_t): New struct.
  (svn_wc__db_pristine_prepare_install): Update output state.
  (svn_wc__db_pristine_install): Use baton for input.
  (svn_wc__db_pristine_install_abort): New function.

* subversion/libsvn_wc/wc_db_pristine.c
  (includes): Add svn_io.h and private/svn_io_private.h
  (pristine_install_txn): Use install stream to avoid opening the files
    many times.
  (svn_wc__db_install_data_t): New struct.
  (svn_wc__db_pristine_prepare_install): Initialize svn_wc__db_install_data_t.

  (svn_wc__db_pristine_install): Install file using install stream.
  (svn_wc__db_pristine_install_abort): New function.

* subversion/tests/libsvn_wc/pristine-store-test.c
  (pristine_write_read,
   pristine_delete_while_open,
   reject_mismatching_text): Update caller.

Modified:
    subversion/trunk/subversion/include/private/svn_io_private.h
    subversion/trunk/subversion/libsvn_subr/stream.c
    subversion/trunk/subversion/libsvn_wc/adm_crawler.c
    subversion/trunk/subversion/libsvn_wc/externals.c
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h
    subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c
    subversion/trunk/subversion/tests/libsvn_wc/pristine-store-test.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=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_io_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_io_private.h Thu Mar 13 18:24:10 2014
@@ -128,6 +128,20 @@ svn_stream__install_stream(svn_stream_t 
                            svn_boolean_t make_parents,
                            apr_pool_t *scratch_pool);
 
+/* Deletes the install stream (when installing is not necessary after all) */
+svn_error_t *
+svn_stream__install_delete(svn_stream_t *install_stream,
+                           apr_pool_t *scratch_pool);
+
+/* Optimized apr_file_stat / apr_file_info_get operating on a closed
+   install stream */
+svn_error_t *
+svn_stream__install_get_info(apr_finfo_t *finfo,
+                             svn_stream_t *install_stream,
+                             apr_int32_t wanted,
+                             apr_pool_t *scratch_pool);
+
+
 #if defined(WIN32)
 
 /* ### Move to something like io.h or subr.h, to avoid making it

Modified: subversion/trunk/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/stream.c?rev=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/stream.c (original)
+++ subversion/trunk/subversion/libsvn_subr/stream.c Thu Mar 13 18:24:10 2014
@@ -2308,3 +2308,49 @@ svn_stream__install_stream(svn_stream_t 
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_stream__install_get_info(apr_finfo_t *finfo,
+                             svn_stream_t *install_stream,
+                             apr_int32_t wanted,
+                             apr_pool_t *scratch_pool)
+{
+  struct install_baton_t *ib = install_stream->baton;
+
+#ifdef WIN32
+  /* On WIN32 the file is still open, so we can obtain the information
+     from the handle without race conditions */
+  apr_status_t status;
+
+  status = apr_file_info_get(finfo, wanted, ib->baton_apr.file);
+
+  if (status)
+    return svn_error_wrap_apr(status, NULL);
+#else
+  SVN_ERR(svn_io_stat(finfo, ib->tmp_path, wanted, scratch_pool));
+#endif
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_stream__install_delete(svn_stream_t *install_stream,
+                           apr_pool_t *scratch_pool)
+{
+  struct install_baton_t *ib = install_stream->baton;
+
+  SVN_ERR(svn_stream_close(install_stream));
+
+#ifdef WIN32
+  /* ### TODO: Optimize windows case */
+  {
+    apr_file_t *file = svn_stream__aprfile(install_stream);
+
+    if (file)
+      SVN_ERR(svn_io_file_close(file, scratch_pool));
+  }
+#endif
+
+  return svn_error_trace(svn_io_remove_file2(ib->tmp_path, FALSE,
+                                             scratch_pool));
+}

Modified: subversion/trunk/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_crawler.c?rev=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_crawler.c Thu Mar 13 18:24:10 2014
@@ -1000,7 +1000,7 @@ svn_wc__internal_transmit_text_deltas(co
   svn_checksum_t *verify_checksum;  /* calc'd MD5 of BASE_STREAM */
   svn_checksum_t *local_md5_checksum;  /* calc'd MD5 of LOCAL_STREAM */
   svn_checksum_t *local_sha1_checksum;  /* calc'd SHA1 of LOCAL_STREAM */
-  const char *new_pristine_tmp_abspath;
+  svn_wc__db_install_data_t *install_data = NULL;
   svn_error_t *err;
   svn_stream_t *base_stream;  /* delta source */
   svn_stream_t *local_stream;  /* delta target: LOCAL_ABSPATH transl. to NF */
@@ -1039,7 +1039,7 @@ svn_wc__internal_transmit_text_deltas(co
       svn_stream_t *new_pristine_stream;
 
       SVN_ERR(svn_wc__db_pristine_prepare_install(&new_pristine_stream,
-                                                  &new_pristine_tmp_abspath,
+                                                  &install_data,
                                                   &local_sha1_checksum, NULL,
                                                   db, local_abspath,
                                                   scratch_pool, scratch_pool));
@@ -1146,7 +1146,7 @@ svn_wc__internal_transmit_text_deltas(co
                                                    result_pool);
   if (new_text_base_sha1_checksum)
     {
-      SVN_ERR(svn_wc__db_pristine_install(db, new_pristine_tmp_abspath,
+      SVN_ERR(svn_wc__db_pristine_install(install_data,
                                           local_sha1_checksum,
                                           local_md5_checksum,
                                           scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/externals.c (original)
+++ subversion/trunk/subversion/libsvn_wc/externals.c Thu Mar 13 18:24:10 2014
@@ -431,7 +431,7 @@ struct edit_baton
   const svn_checksum_t *original_checksum;
 
   /* What we are installing now */
-  const char *new_pristine_abspath;
+  svn_wc__db_install_data_t *install_data;
   svn_checksum_t *new_sha1_checksum;
   svn_checksum_t *new_md5_checksum;
 
@@ -580,7 +580,7 @@ apply_textdelta(void *file_baton,
     src_stream = svn_stream_empty(pool);
 
   SVN_ERR(svn_wc__db_pristine_prepare_install(&dest_stream,
-                                              &eb->new_pristine_abspath,
+                                              &eb->install_data,
                                               &eb->new_sha1_checksum,
                                               &eb->new_md5_checksum,
                                               eb->db, eb->wri_abspath,
@@ -657,11 +657,11 @@ close_file(void *file_baton,
      behavior to the pristine store. */
   if (eb->new_sha1_checksum)
     {
-      SVN_ERR(svn_wc__db_pristine_install(eb->db, eb->new_pristine_abspath,
+      SVN_ERR(svn_wc__db_pristine_install(eb->install_data,
                                           eb->new_sha1_checksum,
                                           eb->new_md5_checksum, pool));
 
-      eb->new_pristine_abspath = NULL;
+      eb->install_data = NULL;
     }
 
   /* Merge the changes */

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Thu Mar 13 18:24:10 2014
@@ -401,7 +401,7 @@ struct handler_baton
   struct file_baton *fb;
 
   /* Where we are assembling the new file. */
-  const char *new_text_base_tmp_abspath;
+  svn_wc__db_install_data_t *install_data;
 
     /* The expected source checksum of the text source or NULL if no base
      checksum is available (MD5 if the server provides a checksum, SHA1 if
@@ -954,7 +954,6 @@ window_handler(svn_txdelta_window_t *win
 {
   struct handler_baton *hb = baton;
   struct file_baton *fb = hb->fb;
-  svn_wc__db_t *db = fb->edit_baton->db;
   svn_error_t *err;
 
   /* Apply this window.  We may be done at that point.  */
@@ -994,10 +993,10 @@ window_handler(svn_txdelta_window_t *win
     {
       /* We failed to apply the delta; clean up the temporary file if it
          already created by lazy_open_target(). */
-      if (hb->new_text_base_tmp_abspath)
+      if (hb->install_data)
         {
-          svn_error_clear(svn_io_remove_file2(hb->new_text_base_tmp_abspath,
-                                              TRUE, hb->pool));
+          svn_error_clear(svn_wc__db_pristine_install_abort(hb->install_data,
+                                                            hb->pool));
         }
     }
   else
@@ -1011,7 +1010,7 @@ window_handler(svn_txdelta_window_t *win
       /* Store the new pristine text in the pristine store now.  Later, in a
          single transaction we will update the BASE_NODE to include a
          reference to this pristine text's checksum. */
-      SVN_ERR(svn_wc__db_pristine_install(db, hb->new_text_base_tmp_abspath,
+      SVN_ERR(svn_wc__db_pristine_install(hb->install_data,
                                           fb->new_text_base_sha1_checksum,
                                           fb->new_text_base_md5_checksum,
                                           hb->pool));
@@ -3626,7 +3625,7 @@ lazy_open_target(svn_stream_t **stream,
   struct handler_baton *hb = baton;
 
   SVN_ERR(svn_wc__db_pristine_prepare_install(stream,
-                                              &hb->new_text_base_tmp_abspath,
+                                              &hb->install_data,
                                               &hb->new_text_base_sha1_checksum,
                                               NULL,
                                               hb->fb->edit_baton->db,
@@ -3749,7 +3748,7 @@ apply_textdelta(void *file_baton,
   /* Prepare to apply the delta.  */
   svn_txdelta_apply(source, target,
                     hb->new_text_base_md5_digest,
-                    hb->new_text_base_tmp_abspath /* error_info */,
+                    fb->local_abspath /* error_info */,
                     handler_pool,
                     &hb->apply_handler, &hb->apply_baton);
 
@@ -5219,6 +5218,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   apr_time_t changed_date;
   const char *changed_author;
   svn_stream_t *tmp_base_contents;
+  svn_wc__db_install_data_t *install_data;
   svn_error_t *err;
   apr_pool_t *pool = scratch_pool;
 
@@ -5340,12 +5340,33 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   /* Copy NEW_BASE_CONTENTS into a temporary file so our log can refer to
      it, and set TMP_TEXT_BASE_ABSPATH to its path.  Compute its
      NEW_TEXT_BASE_MD5_CHECKSUM and NEW_TEXT_BASE_SHA1_CHECKSUM as we copy. */
-  SVN_ERR(svn_wc__db_pristine_prepare_install(&tmp_base_contents,
-                                              &tmp_text_base_abspath,
-                                              &new_text_base_sha1_checksum,
-                                              &new_text_base_md5_checksum,
-                                              wc_ctx->db, local_abspath,
-                                              scratch_pool, scratch_pool));
+  if (copyfrom_url)
+    {
+      SVN_ERR(svn_wc__db_pristine_prepare_install(&tmp_base_contents,
+                                                  &install_data,
+                                                  &new_text_base_sha1_checksum,
+                                                  &new_text_base_md5_checksum,
+                                                  wc_ctx->db, local_abspath,
+                                                  scratch_pool, scratch_pool));
+    }
+  else
+    {
+      const char *tmp_dir_abspath;
+
+      /* We are not installing a PRISTINE file, but we use the same code to
+         create whatever we want to install */
+
+      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmp_dir_abspath,
+                                             db, dir_abspath,
+                                             scratch_pool, scratch_pool));
+
+      SVN_ERR(svn_stream_open_unique(&tmp_base_contents, &tmp_text_base_abspath,
+                                     tmp_dir_abspath, svn_io_file_del_none,
+                                     scratch_pool, scratch_pool));
+
+      new_text_base_sha1_checksum = NULL;
+      new_text_base_md5_checksum = NULL;
+    }
   SVN_ERR(svn_stream_copy3(new_base_contents, tmp_base_contents,
                            cancel_func, cancel_baton, pool));
 
@@ -5370,7 +5391,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
      text base.  */
   if (copyfrom_url != NULL)
     {
-      SVN_ERR(svn_wc__db_pristine_install(db, tmp_text_base_abspath,
+      SVN_ERR(svn_wc__db_pristine_install(install_data,
                                           new_text_base_sha1_checksum,
                                           new_text_base_md5_checksum, pool));
     }
@@ -5437,9 +5458,6 @@ svn_wc_add_repos_file4(svn_wc_context_t 
       }
   }
 
-  /* ### ideally, we would have a single DB operation, and queue the work
-     ### items on that. for now, we'll queue them with the second call.  */
-
   SVN_ERR(svn_wc__db_op_copy_file(db, local_abspath,
                                   new_base_props,
                                   changed_rev,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Thu Mar 13 18:24:10 2014
@@ -953,10 +953,14 @@ svn_wc__db_pristine_read(svn_stream_t **
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
 
+/* Baton for svn_wc__db_pristine_install */
+typedef struct svn_wc__db_install_data_t
+               svn_wc__db_install_data_t;
+
 /* Open a writable stream to a temporary text base, ready for installing
-   into the pristine store.  Set *STREAM to the opened stream and
-   *TEMP_BASE_ABSPATH to the path to the temporary file.  The temporary
-   file will have an arbitrary unique name.
+   into the pristine store.  Set *STREAM to the opened stream.  The temporary
+   file will have an arbitrary unique name. Return as *INSTALL_DATA a baton
+   for eiter installing or removing the file
 
    Arrange that, on stream closure, *MD5_CHECKSUM and *SHA1_CHECKSUM will be
    set to the MD-5 and SHA-1 checksums respectively of that file.
@@ -966,7 +970,7 @@ svn_wc__db_pristine_read(svn_stream_t **
  */
 svn_error_t *
 svn_wc__db_pristine_prepare_install(svn_stream_t **stream,
-                                    const char **temp_base_abspath,
+                                    svn_wc__db_install_data_t **install_data,
                                     svn_checksum_t **sha1_checksum,
                                     svn_checksum_t **md5_checksum,
                                     svn_wc__db_t *db,
@@ -974,17 +978,21 @@ svn_wc__db_pristine_prepare_install(svn_
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool);
 
-/* Install the file TEMPFILE_ABSPATH (which is sitting in a directory given by
-   svn_wc__db_pristine_get_tempdir()) into the pristine data store, to be
-   identified by the SHA-1 checksum of its contents, SHA1_CHECKSUM, and whose
-   MD-5 checksum is MD5_CHECKSUM. */
+/* Install the file created via svn_wc__db_pristine_prepare_install() into
+   the pristine data store, to be identified by the SHA-1 checksum of its
+   contents, SHA1_CHECKSUM, and whose MD-5 checksum is MD5_CHECKSUM. */
 svn_error_t *
-svn_wc__db_pristine_install(svn_wc__db_t *db,
-                            const char *tempfile_abspath,
+svn_wc__db_pristine_install(svn_wc__db_install_data_t *install_data,
                             const svn_checksum_t *sha1_checksum,
                             const svn_checksum_t *md5_checksum,
                             apr_pool_t *scratch_pool);
 
+/* Removes the temporary data created by svn_wc__db_pristine_prepare_install
+   when the pristine won't be installed. */
+svn_error_t *
+svn_wc__db_pristine_install_abort(svn_wc__db_install_data_t *install_data,
+                                  apr_pool_t *scratch_pool);
+
 
 /* Set *MD5_CHECKSUM to the MD-5 checksum of a pristine text
    identified by its SHA-1 checksum SHA1_CHECKSUM. Return an error

Modified: subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c?rev=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c Thu Mar 13 18:24:10 2014
@@ -26,8 +26,11 @@
 #define SVN_WC__I_AM_WC_DB
 
 #include "svn_pools.h"
+#include "svn_io.h"
 #include "svn_dirent_uri.h"
 
+#include "private/svn_io_private.h"
+
 #include "wc.h"
 #include "wc_db.h"
 #include "wc-queries.h"
@@ -268,7 +271,7 @@ pristine_get_tempdir(svn_wc__db_wcroot_t
 static svn_error_t *
 pristine_install_txn(svn_sqlite__db_t *sdb,
                      /* The path to the source file that is to be moved into place. */
-                     const char *tempfile_abspath,
+                     svn_stream_t *install_stream,
                      /* The target path for the file (within the pristine store). */
                      const char *pristine_abspath,
                      /* The pristine text's SHA-1 checksum. */
@@ -277,10 +280,8 @@ pristine_install_txn(svn_sqlite__db_t *s
                      const svn_checksum_t *md5_checksum,
                      apr_pool_t *scratch_pool)
 {
-  apr_finfo_t finfo;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
-  svn_error_t *err;
 
   /* If this pristine text is already present in the store, just keep it:
    * delete the new one and return. */
@@ -288,6 +289,7 @@ pristine_install_txn(svn_sqlite__db_t *s
   SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   SVN_ERR(svn_sqlite__reset(stmt));
+
   if (have_row)
     {
 #ifdef SVN_DEBUG
@@ -295,8 +297,10 @@ pristine_install_txn(svn_sqlite__db_t *s
        * ### We could check much more. */
       {
         apr_finfo_t finfo1, finfo2;
-        SVN_ERR(svn_io_stat(&finfo1, tempfile_abspath, APR_FINFO_SIZE,
-                            scratch_pool));
+
+        SVN_ERR(svn_stream__install_get_info(&finfo1, install_stream, APR_FINFO_SIZE,
+                                             scratch_pool));
+
         SVN_ERR(svn_io_stat(&finfo2, pristine_abspath, APR_FINFO_SIZE,
                             scratch_pool));
         if (finfo1.size != finfo2.size)
@@ -311,54 +315,39 @@ pristine_install_txn(svn_sqlite__db_t *s
 #endif
 
       /* Remove the temp file: it's already there */
-      SVN_ERR(svn_io_remove_file2(tempfile_abspath,
-                                  FALSE /* ignore_enoent */, scratch_pool));
+      SVN_ERR(svn_stream__install_delete(install_stream, scratch_pool));
       return SVN_NO_ERROR;
     }
 
   /* Move the file to its target location.  (If it is already there, it is
    * an orphan file and it doesn't matter if we overwrite it.) */
-  err = svn_io_file_rename(tempfile_abspath, pristine_abspath,
-                           scratch_pool);
-
-  /* Maybe the directory doesn't exist yet? */
-  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      svn_error_t *err2;
-
-      err2 = svn_io_dir_make(svn_dirent_dirname(pristine_abspath,
-                                                scratch_pool),
-                             APR_OS_DEFAULT, 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(tempfile_abspath, pristine_abspath,
-                           scratch_pool));
-    }
-  else
-    SVN_ERR(err);
-
-  SVN_ERR(svn_io_stat(&finfo, pristine_abspath, APR_FINFO_SIZE,
-                      scratch_pool));
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                    STMT_INSERT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
-  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+  {
+    apr_finfo_t finfo;
+    SVN_ERR(svn_stream__install_get_info(&finfo, install_stream, APR_FINFO_SIZE,
+                                         scratch_pool));
+    SVN_ERR(svn_stream__install_stream(install_stream, pristine_abspath,
+                                        TRUE, scratch_pool));
+
+    SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                      STMT_INSERT_PRISTINE));
+    SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
+    SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
+    SVN_ERR(svn_sqlite__insert(NULL, stmt));
+  }
 
   return SVN_NO_ERROR;
 }
 
+struct svn_wc__db_install_data_t
+{
+  svn_wc__db_wcroot_t *wcroot;
+  svn_stream_t *inner_stream;
+};
+
 svn_error_t *
 svn_wc__db_pristine_prepare_install(svn_stream_t **stream,
-                                    const char **temp_base_abspath,
+                                    svn_wc__db_install_data_t **install_data,
                                     svn_checksum_t **sha1_checksum,
                                     svn_checksum_t **md5_checksum,
                                     svn_wc__db_t *db,
@@ -378,11 +367,15 @@ svn_wc__db_pristine_prepare_install(svn_
 
   temp_dir_abspath = pristine_get_tempdir(wcroot, scratch_pool, scratch_pool);
 
-  SVN_ERR(svn_stream_open_unique(stream,
-                                 temp_base_abspath,
-                                 temp_dir_abspath,
-                                 svn_io_file_del_none,
-                                 result_pool, scratch_pool));
+  *install_data = apr_pcalloc(result_pool, sizeof(**install_data));
+  (*install_data)->wcroot = wcroot;
+
+  SVN_ERR(svn_stream__create_for_install(stream,
+                                         temp_dir_abspath,
+                                         result_pool, scratch_pool));
+
+  (*install_data)->inner_stream = *stream;
+
   if (md5_checksum)
     *stream = svn_stream_checksummed2(*stream, NULL, md5_checksum,
                                       svn_checksum_md5, FALSE, result_pool);
@@ -394,37 +387,19 @@ svn_wc__db_pristine_prepare_install(svn_
 }
 
 svn_error_t *
-svn_wc__db_pristine_install(svn_wc__db_t *db,
-                            const char *tempfile_abspath,
+svn_wc__db_pristine_install(svn_wc__db_install_data_t *install_data,
                             const svn_checksum_t *sha1_checksum,
                             const svn_checksum_t *md5_checksum,
                             apr_pool_t *scratch_pool)
 {
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
-  const char *wri_abspath;
+  svn_wc__db_wcroot_t *wcroot = install_data->wcroot;
   const char *pristine_abspath;
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(tempfile_abspath));
   SVN_ERR_ASSERT(sha1_checksum != NULL);
   SVN_ERR_ASSERT(sha1_checksum->kind == svn_checksum_sha1);
   SVN_ERR_ASSERT(md5_checksum != NULL);
   SVN_ERR_ASSERT(md5_checksum->kind == svn_checksum_md5);
 
-  /* ### this logic assumes that TEMPFILE_ABSPATH follows this pattern:
-     ###   WCROOT_ABSPATH/COMPONENT/COMPONENT/TEMPFNAME
-     ### if we change this (see PRISTINE_TEMPDIR_RELPATH), then this
-     ### logic should change.  */
-  wri_abspath = svn_dirent_dirname(
-                    svn_dirent_dirname(
-                        svn_dirent_dirname(tempfile_abspath, scratch_pool),
-                        scratch_pool),
-                    scratch_pool);
-
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
-                              wri_abspath, scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
-
   SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
                              sha1_checksum,
                              scratch_pool, scratch_pool));
@@ -433,7 +408,7 @@ svn_wc__db_pristine_install(svn_wc__db_t
    * at the disk, to ensure no concurrent pristine install/delete txn. */
   SVN_SQLITE__WITH_IMMEDIATE_TXN(
     pristine_install_txn(wcroot->sdb,
-                         tempfile_abspath, pristine_abspath,
+                         install_data->inner_stream, pristine_abspath,
                          sha1_checksum, md5_checksum,
                          scratch_pool),
     wcroot->sdb);
@@ -441,6 +416,14 @@ svn_wc__db_pristine_install(svn_wc__db_t
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc__db_pristine_install_abort(svn_wc__db_install_data_t *install_data,
+                                  apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_stream__install_delete(install_data->inner_stream,
+                                                    scratch_pool));
+}
+
 
 svn_error_t *
 svn_wc__db_pristine_get_md5(const svn_checksum_t **md5_checksum,

Modified: subversion/trunk/subversion/tests/libsvn_wc/pristine-store-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/pristine-store-test.c?rev=1577269&r1=1577268&r2=1577269&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/pristine-store-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/pristine-store-test.c Thu Mar 13 18:24:10 2014
@@ -78,7 +78,7 @@ pristine_write_read(const svn_test_opts_
   svn_wc__db_t *db;
   const char *wc_abspath;
 
-  const char *pristine_tmp_abspath;
+  svn_wc__db_install_data_t *install_data;
   svn_stream_t *pristine_stream;
   apr_size_t sz;
 
@@ -92,7 +92,7 @@ pristine_write_read(const svn_test_opts_
   /* Write DATA into a new temporary pristine file, set PRISTINE_TMP_ABSPATH
    * to its path and set DATA_SHA1 and DATA_MD5 to its checksums. */
   SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
-                                              &pristine_tmp_abspath,
+                                              &install_data,
                                               &data_sha1, &data_md5,
                                               db, wc_abspath,
                                               pool, pool));
@@ -111,7 +111,7 @@ pristine_write_read(const svn_test_opts_
   }
 
   /* Install the new pristine file, referenced by its checksum. */
-  SVN_ERR(svn_wc__db_pristine_install(db, pristine_tmp_abspath,
+  SVN_ERR(svn_wc__db_pristine_install(install_data,
                                       data_sha1, data_md5, pool));
 
   /* Ensure it is now found in the store. */
@@ -177,7 +177,7 @@ pristine_delete_while_open(const svn_tes
 {
   svn_wc__db_t *db;
   const char *wc_abspath;
-  const char *pristine_tmp_abspath;
+  svn_wc__db_install_data_t *install_data;
   svn_stream_t *pristine_stream;
   svn_stream_t *contents;
   apr_size_t sz;
@@ -189,7 +189,7 @@ pristine_delete_while_open(const svn_tes
                               "pristine_delete_while_open", opts, pool));
 
   SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
-                                              &pristine_tmp_abspath,
+                                              &install_data,
                                               &data_sha1, &data_md5,
                                               db, wc_abspath,
                                               pool, pool));
@@ -197,7 +197,7 @@ pristine_delete_while_open(const svn_tes
   sz = strlen(data);
   SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
   SVN_ERR(svn_stream_close(pristine_stream));
-  SVN_ERR(svn_wc__db_pristine_install(db, pristine_tmp_abspath,
+  SVN_ERR(svn_wc__db_pristine_install(install_data,
                                       data_sha1, data_md5, pool));
 
   /* Open it for reading */
@@ -257,12 +257,12 @@ reject_mismatching_text(const svn_test_o
 
   /* Install a pristine text. */
   {
-    const char *pristine_abspath;
+    svn_wc__db_install_data_t *install_data;
     svn_stream_t *pristine_stream;
     apr_size_t sz;
 
     SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
-                                                &pristine_abspath,
+                                                &install_data,
                                                 &data_sha1, &data_md5,
                                                 db, wc_abspath,
                                                 pool, pool));
@@ -271,7 +271,7 @@ reject_mismatching_text(const svn_test_o
     SVN_ERR(svn_stream_write(pristine_stream, data, &sz));
     SVN_ERR(svn_stream_close(pristine_stream));
 
-    SVN_ERR(svn_wc__db_pristine_install(db, pristine_abspath,
+    SVN_ERR(svn_wc__db_pristine_install(install_data,
                                         data_sha1, data_md5,
                                         pool));
   }
@@ -279,12 +279,12 @@ reject_mismatching_text(const svn_test_o
   /* Try to install the wrong pristine text against the same checksum.
    * Should fail. */
   {
-    const char *pristine_abspath;
+    svn_wc__db_install_data_t *install_data;
     svn_stream_t *pristine_stream;
     apr_size_t sz;
 
     SVN_ERR(svn_wc__db_pristine_prepare_install(&pristine_stream,
-                                                &pristine_abspath,
+                                                &install_data,
                                                 &data_sha1, &data_md5,
                                                 db, wc_abspath,
                                                 pool, pool));
@@ -293,7 +293,7 @@ reject_mismatching_text(const svn_test_o
     SVN_ERR(svn_stream_write(pristine_stream, data2, &sz));
     SVN_ERR(svn_stream_close(pristine_stream));
 
-    SVN_ERR(svn_wc__db_pristine_install(db, pristine_abspath,
+    SVN_ERR(svn_wc__db_pristine_install(install_data,
                                         data_sha1, data_md5,
                                         pool));
   }