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/10/16 14:12:57 UTC
svn commit: r1632284 - /subversion/trunk/subversion/libsvn_wc/copy.c
Author: rhuijben
Date: Thu Oct 16 12:12:57 2014
New Revision: 1632284
URL: http://svn.apache.org/r1632284
Log:
When performing a recursive 'svn cp DIR NEW-DIR' avoid a db transaction
per copied unmodified file and a filestat on all descendants.
* subversion/libsvn_wc/copy.c
(copy_to_tmpdir,
copy_versioned_file): Add a few arguments, to optionally allow testing
if the on-disk information matches the recorded information without
performing a filestat and a db transaction.
(copy_versioned_dir): Update caller.
(copy_or_move): Update caller.
Modified:
subversion/trunk/subversion/libsvn_wc/copy.c
Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1632284&r1=1632283&r2=1632284&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Thu Oct 16 12:12:57 2014
@@ -50,7 +50,14 @@
TMPDIR_ABSPATH and return the absolute path of the copy in
*DST_ABSPATH. Return the node kind of SRC_ABSPATH in *KIND. If
SRC_ABSPATH doesn't exist then set *DST_ABSPATH to NULL to indicate
- that no copy was made. */
+ that no copy was made.
+
+ If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH.
+ RECORDED_SIZE (if not SVN_INVALID_FILESIZE) contains the recorded size of
+ SRC_ABSPATH, and RECORDED_TIME the recorded size or 0.
+
+ These values will be used to avoid unneeded work.
+ */
static svn_error_t *
copy_to_tmpdir(svn_skel_t **work_item,
svn_node_kind_t *kind,
@@ -60,6 +67,9 @@ copy_to_tmpdir(svn_skel_t **work_item,
const char *tmpdir_abspath,
svn_boolean_t file_copy,
svn_boolean_t unversioned,
+ const svn_io_dirent2_t *dirent,
+ svn_filesize_t recorded_size,
+ apr_time_t recorded_time,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *result_pool,
@@ -74,8 +84,14 @@ copy_to_tmpdir(svn_skel_t **work_item,
*work_item = NULL;
- SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special,
- scratch_pool));
+ if (dirent)
+ {
+ *kind = dirent->kind;
+ is_special = dirent->special;
+ }
+ else
+ SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special,
+ scratch_pool));
if (*kind == svn_node_none)
{
return SVN_NO_ERROR;
@@ -104,9 +120,21 @@ copy_to_tmpdir(svn_skel_t **work_item,
the timestamp might match, than to examine the
destination later as the destination timestamp will
never match. */
- SVN_ERR(svn_wc__internal_file_modified_p(&modified,
- db, src_abspath,
- FALSE, scratch_pool));
+
+ if (dirent
+ && dirent->kind == svn_node_file
+ && recorded_size != SVN_INVALID_FILESIZE
+ && recorded_size == dirent->filesize
+ && recorded_time == dirent->mtime)
+ {
+ modified = FALSE; /* Recorded matches on-disk. Easy out */
+ }
+ else
+ {
+ SVN_ERR(svn_wc__internal_file_modified_p(&modified, db, src_abspath,
+ FALSE, scratch_pool));
+ }
+
if (!modified)
{
/* Why create a temp copy if we can just reinstall from pristine? */
@@ -172,7 +200,14 @@ copy_to_tmpdir(svn_skel_t **work_item,
versioned file itself.
This also works for versioned symlinks that are stored in the db as
- svn_node_file with svn:special set. */
+ svn_node_file with svn:special set.
+
+ If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH.
+ RECORDED_SIZE (if not SVN_INVALID_FILESIZE) contains the recorded size of
+ SRC_ABSPATH, and RECORDED_TIME the recorded size or 0.
+
+ These values will be used to avoid unneeded work.
+*/
static svn_error_t *
copy_versioned_file(svn_wc__db_t *db,
const char *src_abspath,
@@ -182,6 +217,9 @@ copy_versioned_file(svn_wc__db_t *db,
svn_boolean_t metadata_only,
svn_boolean_t conflicted,
svn_boolean_t is_move,
+ const svn_io_dirent2_t *dirent,
+ svn_filesize_t recorded_size,
+ apr_time_t recorded_time,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -248,6 +286,7 @@ copy_versioned_file(svn_wc__db_t *db,
dst_abspath, tmpdir_abspath,
TRUE /* file_copy */,
handle_as_unversioned /* unversioned */,
+ dirent, recorded_size, recorded_time,
cancel_func, cancel_baton,
scratch_pool, scratch_pool));
}
@@ -314,6 +353,7 @@ copy_versioned_dir(svn_wc__db_t *db,
tmpdir_abspath,
FALSE /* file_copy */,
FALSE /* unversioned */,
+ NULL, SVN_INVALID_FILESIZE, 0,
cancel_func, cancel_baton,
scratch_pool, scratch_pool));
}
@@ -395,6 +435,12 @@ copy_versioned_dir(svn_wc__db_t *db,
tmpdir_abspath,
metadata_only, info->conflicted,
is_move,
+ disk_children
+ ? svn_hash_gets(disk_children,
+ child_name)
+ : NULL,
+ info->recorded_size,
+ info->recorded_time,
cancel_func, cancel_baton,
NULL, NULL,
iterpool));
@@ -489,6 +535,7 @@ copy_versioned_dir(svn_wc__db_t *db,
SVN_ERR(copy_to_tmpdir(&work_item, NULL, db, unver_src_abspath,
unver_dst_abspath, tmpdir_abspath,
TRUE /* recursive */, TRUE /* unversioned */,
+ NULL, SVN_INVALID_FILESIZE, 0,
cancel_func, cancel_baton,
scratch_pool, iterpool));
@@ -534,6 +581,8 @@ copy_or_move(svn_boolean_t *move_degrade
svn_boolean_t within_one_wc;
svn_wc__db_status_t src_status;
svn_error_t *err;
+ svn_filesize_t recorded_size;
+ apr_time_t recorded_time;
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -551,7 +600,8 @@ copy_or_move(svn_boolean_t *move_degrade
err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL,
&src_repos_relpath, &src_repos_root_url,
&src_repos_uuid, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ &recorded_size, &recorded_time,
NULL, &conflicted, NULL, NULL, NULL, NULL,
NULL, NULL,
db, src_abspath, scratch_pool, scratch_pool);
@@ -775,6 +825,7 @@ copy_or_move(svn_boolean_t *move_degrade
err = copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
tmpdir_abspath,
metadata_only, conflicted, is_move,
+ NULL, recorded_size, recorded_time,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool);