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 2013/01/19 13:25:27 UTC
svn commit: r1435527 - in /subversion/trunk/subversion: include/svn_io.h
libsvn_subr/deprecated.c libsvn_subr/io.c libsvn_subr/sysinfo.c
libsvn_wc/status.c
Author: rhuijben
Date: Sat Jan 19 12:25:27 2013
New Revision: 1435527
URL: http://svn.apache.org/viewvc?rev=1435527&view=rev
Log:
Optimize a few truename checks on Windows to use a far more efficient code
path.
* subversion/include/svn_io.h
(svn_io_stat_dirent2): New function, allowing optional truename check.
(svn_io_stat_dirent): Deprecate function.
* subversion/libsvn_subr/deprecated.c
(svn_io_stat_dirent): New function.
* subversion/libsvn_subr/io.c
(svn_io_stat_dirent): Rename to ...
(svn_io_stat_dirent2): ... this and use the existing stat call to perform
a truename check.
* subversion/libsvn_subr/sysinfo.c
(includes): Add path handling.
(win32_shared_libs): Just use our own apis instead of the apr ones, that
perform a lot of unnecessary IO for the TRUENAME question that we don't
even need.
* subversion/libsvn_wc/status.c
(stat_wc_dirent_case_sensitive): Use svn_io_stat_dirent2 for a cheaper
truename check.
Modified:
subversion/trunk/subversion/include/svn_io.h
subversion/trunk/subversion/libsvn_subr/deprecated.c
subversion/trunk/subversion/libsvn_subr/io.c
subversion/trunk/subversion/libsvn_subr/sysinfo.c
subversion/trunk/subversion/libsvn_wc/status.c
Modified: subversion/trunk/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_io.h?rev=1435527&r1=1435526&r2=1435527&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_io.h (original)
+++ subversion/trunk/subversion/include/svn_io.h Sat Jan 19 12:25:27 2013
@@ -1553,10 +1553,31 @@ svn_io_get_dirents(apr_hash_t **dirents,
/** Create a svn_io_dirent2_t instance for path. Specialized variant of
* svn_io_stat() that directly translates node_kind and special.
*
+ * If @a verify_truename is @c TRUE, an additional check is performed to
+ * verify the truename of the last path component on case insensitive
+ * filesystems. This check is expensive compared to a just a stat,
+ * but certainly cheaper than a full truename calculation using
+ * apr_filepath_merge() which verifies all path components.
+ *
* If @a ignore_enoent is set to @c TRUE, set *dirent_p->kind to
* svn_node_none instead of returning an error.
*
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_io_stat_dirent2(const svn_io_dirent2_t **dirent_p,
+ const char *path,
+ svn_boolean_t verify_truename,
+ svn_boolean_t ignore_enoent,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+
+/** Similar to svn_io_stat_dirent2, but always passes FALSE for
+ * verify_truename.
+ *
* @since New in 1.7.
+ * @deprecated Provided for backwards compatibility with the 1.7 API.
*/
svn_error_t *
svn_io_stat_dirent(const svn_io_dirent2_t **dirent_p,
Modified: subversion/trunk/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/deprecated.c?rev=1435527&r1=1435526&r2=1435527&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_subr/deprecated.c Sat Jan 19 12:25:27 2013
@@ -878,6 +878,22 @@ svn_io_dir_walk(const char *dirname,
&baton, pool));
}
+svn_error_t *
+svn_io_stat_dirent(const svn_io_dirent2_t **dirent_p,
+ const char *path,
+ svn_boolean_t ignore_enoent,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(
+ svn_io_stat_dirent2(dirent_p,
+ path,
+ FALSE,
+ ignore_enoent,
+ result_pool,
+ scratch_pool));
+}
+
/*** From constructors.c ***/
svn_log_changed_path_t *
svn_log_changed_path_dup(const svn_log_changed_path_t *changed_path,
Modified: subversion/trunk/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/io.c?rev=1435527&r1=1435526&r2=1435527&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/io.c (original)
+++ subversion/trunk/subversion/libsvn_subr/io.c Sat Jan 19 12:25:27 2013
@@ -2493,20 +2493,25 @@ svn_io_get_dirents3(apr_hash_t **dirents
}
svn_error_t *
-svn_io_stat_dirent(const svn_io_dirent2_t **dirent_p,
- const char *path,
- svn_boolean_t ignore_enoent,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_io_stat_dirent2(const svn_io_dirent2_t **dirent_p,
+ const char *path,
+ svn_boolean_t verify_truename,
+ svn_boolean_t ignore_enoent,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_finfo_t finfo;
svn_io_dirent2_t *dirent;
svn_error_t *err;
+ apr_int32_t wanted = APR_FINFO_TYPE | APR_FINFO_LINK
+ | APR_FINFO_SIZE | APR_FINFO_MTIME;
- err = svn_io_stat(&finfo, path,
- APR_FINFO_TYPE | APR_FINFO_LINK
- | APR_FINFO_SIZE | APR_FINFO_MTIME,
- scratch_pool);
+#if defined(WIN32) || defined(__OS2__) || defined(DARWIN)
+ if (verify_truename)
+ wanted |= APR_FINFO_NAME;
+#endif
+
+ err = svn_io_stat(&finfo, path, wanted, scratch_pool);
if (err && ignore_enoent &&
(APR_STATUS_IS_ENOENT(err->apr_err)
@@ -2521,6 +2526,76 @@ svn_io_stat_dirent(const svn_io_dirent2_
}
SVN_ERR(err);
+#if defined(WIN32) || defined(__OS2__) || defined(DARWIN)
+ if (verify_truename)
+ {
+ const char *requested_name = svn_dirent_basename(path, NULL);
+
+ if (requested_name[0] == '\0')
+ {
+ /* No parent directory. No need to stat/verify */
+ }
+ else if (finfo.name)
+ {
+ const char *name_on_disk;
+ SVN_ERR(entry_name_to_utf8(&name_on_disk, finfo.name, path,
+ scratch_pool));
+
+ if (strcmp(name_on_disk, requested_name) /* != 0 */)
+ {
+ if (ignore_enoent)
+ {
+ *dirent_p = svn_io_dirent2_create(result_pool);
+ return SVN_NO_ERROR;
+ }
+ else
+ return svn_error_createf(APR_ENOENT, NULL,
+ _("Path '%s' not found, case obstructed by '%s'"),
+ svn_dirent_local_style(path, scratch_pool),
+ name_on_disk);
+ }
+ }
+#if defined(DARWIN)
+ /* Currently apr doesn't set finfo.name on DARWIN.
+ ### Can we optimize this in another way? */
+ else
+ {
+ apr_hash_t *dirents;
+
+ err = svn_io_get_dirents3(&dirents,
+ svn_dirent_dirname(path, scratch_pool),
+ TRUE /* only_check_type */,
+ scratch_pool, scratch_pool);
+
+ if (err && ignore_enoent
+ && (APR_STATUS_IS_ENOENT(err->apr_err)
+ || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)))
+ {
+ svn_error_clear(err);
+
+ *dirent_p = svn_io_dirent2_create(result_pool);
+ return SVN_NO_ERROR;
+ }
+ else
+ SVN_ERR(err);
+
+ if (! apr_hash_get(dirents, requested_name, APR_HASH_KEY_STRING))
+ {
+ if (ignore_enoent)
+ {
+ *dirent_p = svn_io_dirent2_create(result_pool);
+ return SVN_NO_ERROR;
+ }
+ else
+ return svn_error_createf(APR_ENOENT, NULL,
+ _("Path '%s' not found"),
+ svn_dirent_local_style(path, scratch_pool));
+ }
+ }
+#endif
+ }
+#endif
+
dirent = svn_io_dirent2_create(result_pool);
map_apr_finfo_to_node_kind(&(dirent->kind), &(dirent->special), &finfo);
Modified: subversion/trunk/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/sysinfo.c?rev=1435527&r1=1435526&r2=1435527&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/trunk/subversion/libsvn_subr/sysinfo.c Sat Jan 19 12:25:27 2013
@@ -42,7 +42,9 @@
#include <apr_version.h>
#include <apu_version.h>
+#include "svn_pools.h"
#include "svn_ctype.h"
+#include "svn_dirent_uri.h"
#include "svn_error.h"
#include "svn_io.h"
#include "svn_string.h"
@@ -831,25 +833,19 @@ win32_shared_libs(apr_pool_t *pool)
if (GetModuleFileNameW(*module, buffer, MAX_PATH))
{
buffer[MAX_PATH] = 0;
+
version = file_version_number(buffer, pool);
filename = wcs_to_utf8(buffer, pool);
if (filename)
{
svn_version_ext_loaded_lib_t *lib;
- char *truename;
-
- if (0 == apr_filepath_merge(&truename, "", filename,
- APR_FILEPATH_NATIVE
- | APR_FILEPATH_TRUENAME,
- pool))
- filename = truename;
if (!array)
{
array = apr_array_make(pool, 32, sizeof(*lib));
}
lib = &APR_ARRAY_PUSH(array, svn_version_ext_loaded_lib_t);
- lib->name = filename;
+ lib->name = svn_dirent_local_style(filename, pool);
lib->version = version;
}
}
Modified: subversion/trunk/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/status.c?rev=1435527&r1=1435526&r2=1435527&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/status.c (original)
+++ subversion/trunk/subversion/libsvn_wc/status.c Sat Jan 19 12:25:27 2013
@@ -2702,6 +2702,7 @@ stat_wc_dirent_case_sensitive(const svn_
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
+ svn_boolean_t verify_truename = FALSE;
#if defined(WIN32) || defined(DARWIN)
svn_boolean_t is_wcroot;
/* We only need this code on systems with case insensitive filesystem
@@ -2712,43 +2713,13 @@ stat_wc_dirent_case_sensitive(const svn_
SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
scratch_pool));
- if (! is_wcroot)
- {
- apr_hash_t *dirents;
- svn_error_t *err;
- const char *parent_abspath;
- const char *name;
-
- svn_dirent_split(&parent_abspath, &name, local_abspath, scratch_pool);
-
- /* Obtain the name of the node, as stored in the directory.
- Do this to avoid case insensitivity differences */
-
- err = svn_io_get_dirents3(&dirents, parent_abspath, FALSE,
- scratch_pool, scratch_pool);
-
- if (err
- && (APR_STATUS_IS_ENOENT(err->apr_err)
- || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)))
- {
- svn_error_clear(err);
- dirents = NULL;
- }
- else
- SVN_ERR(err);
-
- *dirent = dirents ? apr_hash_get(dirents, name, APR_HASH_KEY_STRING)
- : NULL;
-
- if (!*dirent)
- *dirent = svn_io_dirent2_create(scratch_pool);
-
- return SVN_NO_ERROR;
- }
+ verify_truename = ! is_wcroot;
#endif
- return svn_error_trace(svn_io_stat_dirent(dirent, local_abspath, TRUE,
- result_pool, scratch_pool));
+ return svn_error_trace(svn_io_stat_dirent2(dirent, local_abspath,
+ verify_truename,
+ TRUE /* ignore_enoent */,
+ result_pool, scratch_pool));
}
svn_error_t *
@@ -2800,8 +2771,8 @@ svn_wc__internal_walk_status(svn_wc__db_
wb.externals = apr_hash_make(scratch_pool);
- SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE, scratch_pool,
- scratch_pool));
+ SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath, FALSE, TRUE,
+ scratch_pool, scratch_pool));
}
else
{