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/06/01 22:55:31 UTC
svn commit: r1345346 - in /subversion/trunk/subversion/libsvn_wc: copy.c
wc_db.h wc_db_pristine.c
Author: rhuijben
Date: Fri Jun 1 20:55:31 2012
New Revision: 1345346
URL: http://svn.apache.org/viewvc?rev=1345346&view=rev
Log:
Following up on r1345317, move the pristine transfer between working copies
in the wc_db pristine api, to allow using just two sqlite locks instead of
the four that it used to take.
* subversion/libsvn_wc/copy.c
(copy_pristine_text_if_necessary): Remove function.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_pristine_transfer): New function.
* subversion/libsvn_wc/wc_db_pristine.c
(pristine_transfer_baton): New struct.
(pristine_transfer): New function.
(svn_wc__db_pristine_transfer): New function.
Modified:
subversion/trunk/subversion/libsvn_wc/copy.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c
Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1345346&r1=1345345&r2=1345346&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Fri Jun 1 20:55:31 2012
@@ -119,57 +119,6 @@ copy_to_tmpdir(const char **dst_abspath,
return SVN_NO_ERROR;
}
-
-/* If SRC_ABSPATH and DST_ABSPATH use different pristine stores, copy the
- pristine text of SRC_ABSPATH (if there is one) into the pristine text
- store connected to DST_ABSPATH. This will only happen when copying into
- a separate WC such as an external directory.
- */
-static svn_error_t *
-copy_pristine_text_if_necessary(svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_abspath,
- const char *tmpdir_abspath,
- const svn_checksum_t *checksum,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *scratch_pool)
-{
- svn_boolean_t present;
- svn_stream_t *src_pristine, *tmp_pristine;
- const char *tmp_pristine_abspath;
- const svn_checksum_t *sha1_checksum, *md5_checksum;
-
- SVN_ERR_ASSERT(checksum->kind == svn_checksum_sha1);
-
- /* If it's already in DST_ABSPATH's pristine store, we're done. */
- SVN_ERR(svn_wc__db_pristine_check(&present, db, dst_abspath, checksum,
- scratch_pool));
- if (present)
- return SVN_NO_ERROR;
-
- sha1_checksum = checksum;
- SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db,
- src_abspath, checksum,
- scratch_pool, scratch_pool));
-
- SVN_ERR(svn_wc__db_pristine_read(&src_pristine, NULL, db,
- src_abspath, sha1_checksum,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_stream_open_unique(&tmp_pristine, &tmp_pristine_abspath,
- tmpdir_abspath, svn_io_file_del_none,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_stream_copy3(src_pristine, tmp_pristine,
- cancel_func, cancel_baton,
- scratch_pool));
- SVN_ERR(svn_wc__db_pristine_install(db, tmp_pristine_abspath,
- sha1_checksum, md5_checksum,
- scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-
/* Copy the versioned file SRC_ABSPATH in DB to the path DST_ABSPATH in DB.
If METADATA_ONLY is true, copy only the versioned metadata,
otherwise copy both the versioned metadata and the filesystem node (even
@@ -210,23 +159,10 @@ copy_versioned_file(svn_wc__db_t *db,
ensure the destination WC has a copy of the pristine text. */
if (copy_pristine_file)
- {
- const svn_checksum_t *checksum;
- SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, &checksum, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- db, src_abspath,
- scratch_pool, scratch_pool));
-
- /* Checksum is NULL for local additions, but that should be handled
- by our caller*/
- if (checksum != NULL)
- SVN_ERR(copy_pristine_text_if_necessary(db, src_abspath, dst_abspath,
- tmpdir_abspath, checksum,
- cancel_func, cancel_baton,
- scratch_pool));
- }
+ SVN_ERR(svn_wc__db_pristine_transfer(db, src_abspath, NULL,
+ dst_op_root_abspath,
+ cancel_func, cancel_baton,
+ scratch_pool));
/* Prepare a temp copy of the filesystem node. It is usually a file, but
copy recursively if it's a dir. */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1345346&r1=1345345&r2=1345346&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri Jun 1 20:55:31 2012
@@ -941,6 +941,18 @@ svn_wc__db_pristine_get_sha1(const svn_c
apr_pool_t *scratch_pool);
+/* If necessary transfers the PRISTINE file of SRC_LOCAL_ABSPATH to the
+ working copy identified by DST_WRI_ABSPATH. If CHECKSUM is not NULL, use
+ CHECKSUM to identify which pristine file to transfer. */
+svn_error_t *
+svn_wc__db_pristine_transfer(svn_wc__db_t *db,
+ const char *src_local_abspath,
+ const svn_checksum_t *checksum,
+ const char *dst_wri_abspath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool);
+
/* Remove the pristine text with SHA-1 checksum SHA1_CHECKSUM from the
* pristine store, iff it is not referenced by any of the (other) WC DB
* tables. */
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=1345346&r1=1345345&r2=1345346&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_pristine.c Fri Jun 1 20:55:31 2012
@@ -523,6 +523,176 @@ svn_wc__db_pristine_get_sha1(const svn_c
return svn_error_trace(svn_sqlite__reset(stmt));
}
+/* Baton for pristine_transfer() */
+struct pristine_transfer_baton
+{
+ svn_wc__db_wcroot_t *src_wcroot;
+ svn_wc__db_wcroot_t *dst_wcroot;
+ svn_cancel_func_t cancel_func;
+ void * cancel_baton;
+
+ /* pristine install baton, filled from pristine_transfer() */
+ struct pristine_install_baton_t ib;
+};
+
+/* Transaction implementation of svn_wc__db_pristine_transfer().
+ Calls itself again to obtain locks in both working copies */
+static svn_error_t *
+pristine_transfer(void *baton, svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath, apr_pool_t *scratch_pool)
+{
+ struct pristine_transfer_baton *tb = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+
+ /* Is this the initial call or the recursive call? */
+ if (wcroot == tb->dst_wcroot)
+ {
+ /* The initial call: */
+
+ /* Get all the info within a src wcroot lock */
+ SVN_ERR(svn_wc__db_with_txn(tb->src_wcroot, local_relpath,
+ pristine_transfer, tb, scratch_pool));
+
+ /* And do the final install, while we still have the dst lock */
+ if (tb->ib.tempfile_abspath)
+ SVN_ERR(pristine_install_txn(&(tb->ib), tb->dst_wcroot->sdb,
+ scratch_pool));
+ return SVN_NO_ERROR;
+ }
+
+ /* We have a lock on tb->dst_wcroot and tb->src_wcroot */
+
+ /* Get the right checksum if it wasn't passed */
+ if (!tb->ib.sha1_checksum)
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, tb->src_wcroot->sdb,
+ STMT_SELECT_NODE_INFO));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ tb->src_wcroot->wc_id, local_relpath));
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (have_row)
+ SVN_ERR(svn_sqlite__column_checksum(&(tb->ib.sha1_checksum), stmt, 6,
+ scratch_pool));
+
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (!tb->ib.sha1_checksum)
+ return SVN_NO_ERROR; /* Nothing to transfer */
+ }
+
+ /* Check if we have the pristine in the destination wcroot */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, tb->dst_wcroot->sdb,
+ STMT_SELECT_PRISTINE));
+ SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, tb->ib.sha1_checksum,
+ scratch_pool));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ /* Destination repository already has this pristine. We're done */
+ if (have_row)
+ return SVN_NO_ERROR;
+
+ /* Verify if the pristine actually exists and get the MD5 in one query */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, tb->src_wcroot->sdb,
+ STMT_SELECT_PRISTINE));
+ SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, tb->ib.sha1_checksum,
+ scratch_pool));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (!have_row)
+ {
+ return svn_error_createf(SVN_ERR_WC_DB_ERROR, svn_sqlite__reset(stmt),
+ _("The pristine text with checksum '%s' was "
+ "not found"),
+ svn_checksum_to_cstring_display(
+ tb->ib.sha1_checksum, scratch_pool));
+ }
+ SVN_ERR(svn_sqlite__column_checksum(&(tb->ib.md5_checksum), stmt, 0,
+ scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ /* We now have read locks in both working copies, so we can safely copy the
+ file to the temp location of the destination working copy */
+ {
+ svn_stream_t *src_stream;
+ svn_stream_t *dst_stream;
+ const char *tmp_abspath;
+ const char *src_abspath;
+
+ SVN_ERR(svn_stream_open_unique(&dst_stream, &tmp_abspath,
+ pristine_get_tempdir(tb->dst_wcroot,
+ scratch_pool,
+ scratch_pool),
+ svn_io_file_del_on_pool_cleanup,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(get_pristine_fname(&src_abspath, tb->src_wcroot->abspath,
+ tb->ib.sha1_checksum,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_stream_open_readonly(&src_stream, src_abspath,
+ scratch_pool, scratch_pool));
+
+ /* ### Should we verify the SHA1 or MD5 here, or is that too expensive? */
+ SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
+ tb->cancel_func, tb->cancel_baton,
+ scratch_pool));
+
+ /* And now set the right information to install once we leave the
+ src transaction */
+
+ SVN_ERR(get_pristine_fname(&(tb->ib.pristine_abspath),
+ tb->dst_wcroot->abspath,
+ tb->ib.sha1_checksum,
+ scratch_pool, scratch_pool));
+ tb->ib.tempfile_abspath = tmp_abspath;
+ }
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_pristine_transfer(svn_wc__db_t *db,
+ const char *src_local_abspath,
+ const svn_checksum_t *checksum,
+ const char *dst_wri_abspath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ const char *src_relpath;
+ const char *dst_relpath;
+ struct pristine_transfer_baton tb;
+ memset(&tb, 0, sizeof(tb));
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&tb.src_wcroot, &src_relpath,
+ db, src_local_abspath,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(tb.src_wcroot);
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&tb.dst_wcroot, &dst_relpath,
+ db, dst_wri_abspath,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(tb.dst_wcroot);
+
+ if (tb.src_wcroot == tb.dst_wcroot
+ || tb.src_wcroot->sdb == tb.dst_wcroot->sdb)
+ {
+ return SVN_NO_ERROR; /* Nothing to transfer */
+ }
+
+ tb.cancel_func = cancel_func;
+ tb.cancel_baton = cancel_baton;
+
+ return svn_error_trace(svn_wc__db_with_txn(tb.dst_wcroot, src_relpath,
+ pristine_transfer, &tb,
+ scratch_pool));
+}
+
+
+
/* Remove the file at FILE_ABSPATH in such a way that we could re-create a
* new file of the same name at any time thereafter.
@@ -708,7 +878,6 @@ pristine_cleanup_wcroot(svn_wc__db_wcroo
return SVN_NO_ERROR;
}
-
svn_error_t *
svn_wc__db_pristine_cleanup(svn_wc__db_t *db,
const char *wri_abspath,