Author: rhuijben
Date: Thu May 12 12:01:16 2011
New Revision: 1102257
URL: http://svn.apache.org/viewvc?rev=1102257&view=rev
Log:
Following up on r1102242, improve svnversion performance by another 40-50%
(tested on a hot filesystem cache. Result is at least better than before
in other scenarios.).
Instead of doing a broad query to retrieve all nodes and then call a modcheck
on a subset of these nodes, query only the file and their recorded information.
(And as we already checked that there are no working layers we can even limit
it to op_depth 0, to remove another subquery per file).
With that information we can do a filestat and immediately stop checking
for further changes if the recorded information matches.
This avoids two queries for every unmodified file in a working copy that
is checked before the first modification is found.
* subversion/libsvn_wc/wc-queries.sql
(STMT_SELECT_CURRENT_NODES_RECURSIVE): Rename to ...
(STMT_SELECT_BASE_FILES_RECURSIVE): ... this and specialize the result
for its only user.
* subversion/libsvn_wc/wc_db.c
(has_local_mods): Don't filter on kind. Perform a recorded information
check directly instead of only after we do a svn_wc__db_read_info().
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1102257&r1=1102256&r2=1102257&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu May 12 12:01:16
2011
@@ -1161,11 +1161,13 @@ WHERE wc_id = ?1 AND local_relpath != ""
AND file_external IS NULL
LIMIT 1
--- STMT_SELECT_CURRENT_NODES_RECURSIVE
-SELECT local_relpath, kind FROM nodes_current
+-- STMT_SELECT_BASE_FILES_RECURSIVE
+SELECT local_relpath, translated_size, last_mod_time FROM nodes AS n
WHERE wc_id = ?1
- AND (?2 = '' OR local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
- AND presence IN ('normal', 'incomplete')
+ AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
+ AND op_depth = 0
+ AND kind='file'
+ AND presence='normal'
AND file_external IS NULL
/* ------------------------------------------------------------------------- */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1102257&r1=1102256&r2=1102257&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu May 12 12:01:16 2011
@@ -11980,7 +11980,7 @@ has_local_mods(svn_boolean_t *is_modifie
/* Check for text modifications. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_CURRENT_NODES_RECURSIVE));
+ STMT_SELECT_BASE_FILES_RECURSIVE));
SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
construct_like_arg(local_relpath,
scratch_pool)));
@@ -11990,7 +11990,9 @@ has_local_mods(svn_boolean_t *is_modifie
while (have_row)
{
const char *node_abspath;
- svn_wc__db_kind_t node_kind;
+ svn_filesize_t recorded_size;
+ apr_time_t recorded_mod_time;
+ svn_boolean_t skip_check = FALSE;
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
@@ -12001,8 +12003,32 @@ has_local_mods(svn_boolean_t *is_modifie
svn_sqlite__column_text(stmt, 0,
iterpool),
iterpool);
- node_kind = svn_sqlite__column_token(stmt, 1, kind_map);
- if (node_kind == svn_wc__db_kind_file)
+
+ recorded_size = get_recorded_size(stmt, 1);
+ recorded_mod_time = svn_sqlite__column_int64(stmt, 2);
+
+ if (recorded_size != SVN_INVALID_FILESIZE
+ && recorded_mod_time != 0)
+ {
+ const svn_io_dirent2_t *dirent;
+
+ SVN_ERR(svn_io_stat_dirent(&dirent, node_abspath, TRUE,
+ iterpool, iterpool));
+
+ if (dirent->kind != svn_node_file)
+ {
+ *is_modified = TRUE; /* Missing or obstruction */
+ break;
+ }
+ else if (dirent->filesize == recorded_size
+ && dirent->mtime == recorded_mod_time)
+ {
+ /* The file is not modified */
+ skip_check = TRUE;
+ }
+ }
+
+ if (! skip_check)
{
SVN_ERR(svn_wc__internal_file_modified_p(is_modified,
db, node_abspath,