Author: rhuijben
Date: Wed May 18 16:30:07 2011
New Revision: 1124331
URL: http://svn.apache.org/viewvc?rev=1124331&view=rev
Log:
Optimize the conflict resolver code a bit by reducing the number of database
queries used while walking the tree for conflicts.
* subversion/libsvn_wc/conflicts.c
(recursive_resolve_conflict): Add this_is_conflicted boolean. Use a single
read in the loop instead of two and pass information to the callee, to
avoid another db operation.
(svn_wc_resolved_conflict5): Update caller. Add a single read to call
recursive_resolve_conflict with its initial information.
Modified:
subversion/trunk/subversion/libsvn_wc/conflicts.c
Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1124331&r1=1124330&r2=1124331&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_wc/conflicts.c Wed May 18 16:30:07 2011
@@ -459,6 +459,7 @@ resolve_one_conflict(svn_wc__db_t *db,
static svn_error_t *
recursive_resolve_conflict(svn_wc__db_t *db,
const char *local_abspath,
+ svn_boolean_t this_is_conflicted,
svn_depth_t depth,
svn_boolean_t resolve_text,
const char *resolve_prop,
@@ -470,33 +471,16 @@ recursive_resolve_conflict(svn_wc__db_t
void *notify_baton,
apr_pool_t *scratch_pool)
{
- svn_boolean_t conflicted;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
const apr_array_header_t *children;
apr_hash_t *visited = apr_hash_make(scratch_pool);
svn_depth_t child_depth;
- svn_error_t *err;
int i;
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
- err = svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, &conflicted, NULL, NULL,
- NULL, NULL, NULL, NULL,
- db, local_abspath, iterpool, iterpool);
-
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
- { /* Would be nice if we could just call svn_wc__db_read_info on
- conflict victims */
- svn_error_clear(err);
- conflicted = TRUE; /* Just resolve it */
- }
- else
- SVN_ERR(err);
-
- if (conflicted)
+ if (this_is_conflicted)
{
SVN_ERR(resolve_one_conflict(db,
local_abspath,
@@ -513,14 +497,16 @@ recursive_resolve_conflict(svn_wc__db_t
child_depth = (depth < svn_depth_infinity) ? svn_depth_empty : depth;
- SVN_ERR(svn_wc__db_read_conflict_victims(&children, db, local_abspath,
- scratch_pool, iterpool));
+ SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
+ scratch_pool, iterpool));
for (i = 0; i < children->nelts; i++)
{
const char *name = APR_ARRAY_IDX(children, i, const char *);
const char *child_abspath;
+ svn_wc__db_status_t status;
svn_wc__db_kind_t kind;
+ svn_boolean_t conflicted;
svn_pool_clear(iterpool);
@@ -529,33 +515,52 @@ recursive_resolve_conflict(svn_wc__db_t
child_abspath = svn_dirent_join(local_abspath, name, iterpool);
- apr_hash_set(visited, name, APR_HASH_KEY_STRING, name);
+ SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &conflicted, NULL, NULL, NULL, NULL, NULL,
+ NULL,
+ db, child_abspath, iterpool, iterpool));
+
+ if (status == svn_wc__db_status_not_present
+ || status == svn_wc__db_status_excluded
+ || status == svn_wc__db_status_absent)
+ continue;
- SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, TRUE, iterpool));
+ apr_hash_set(visited, name, APR_HASH_KEY_STRING, name);
if (kind == svn_wc__db_kind_dir && depth < svn_depth_immediates)
continue;
- SVN_ERR(recursive_resolve_conflict(db,
- child_abspath,
- child_depth,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- iterpool));
+ if (kind == svn_wc__db_kind_dir)
+ SVN_ERR(recursive_resolve_conflict(db,
+ child_abspath,
+ conflicted,
+ child_depth,
+ resolve_text,
+ resolve_prop,
+ resolve_tree,
+ conflict_choice,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ iterpool));
+ else if (conflicted)
+ SVN_ERR(resolve_one_conflict(db,
+ child_abspath,
+ resolve_text,
+ resolve_prop,
+ resolve_tree,
+ conflict_choice,
+ notify_func, notify_baton,
+ iterpool));
}
- SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
- scratch_pool, iterpool));
+ SVN_ERR(svn_wc__db_read_conflict_victims(&children, db, local_abspath,
+ scratch_pool, iterpool));
for (i = 0; i < children->nelts; i++)
{
const char *name = APR_ARRAY_IDX(children, i, const char *);
const char *child_abspath;
- svn_wc__db_kind_t kind;
- svn_boolean_t hidden;
svn_pool_clear(iterpool);
@@ -567,26 +572,19 @@ recursive_resolve_conflict(svn_wc__db_t
child_abspath = svn_dirent_join(local_abspath, name, iterpool);
- SVN_ERR(svn_wc__db_node_hidden(&hidden, db, child_abspath, iterpool));
- if (hidden)
- continue;
-
- SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, TRUE, iterpool));
- if (kind == svn_wc__db_kind_dir && depth < svn_depth_immediates)
- continue;
-
- SVN_ERR(recursive_resolve_conflict(db,
- child_abspath,
- child_depth,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- iterpool));
+ /* We only have to resolve one level of tree conflicts. All other
+ conflicts are resolved in the other loop */
+ SVN_ERR(resolve_one_conflict(db,
+ child_abspath,
+ FALSE /*resolve_text*/,
+ FALSE /*resolve_prop*/,
+ resolve_tree,
+ conflict_choice,
+ notify_func, notify_baton,
+ iterpool));
}
+
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
@@ -607,6 +605,8 @@ svn_wc_resolved_conflict5(svn_wc_context
void *notify_baton,
apr_pool_t *scratch_pool)
{
+ svn_wc__db_kind_t kind;
+ svn_boolean_t conflicted;
/* ### the underlying code does NOT support resolving individual
### properties. bail out if the caller tries it. */
if (resolve_prop != NULL && *resolve_prop != '\0')
@@ -614,14 +614,24 @@ svn_wc_resolved_conflict5(svn_wc_context
U_("Resolving a single property is not (yet) "
"supported."));
+ SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ wc_ctx->db, local_abspath,
+ scratch_pool, scratch_pool));
+
/* When the implementation still used the entry walker, depth
unknown was translated to infinity. */
- if (depth == svn_depth_unknown)
+ if (kind != svn_wc__db_kind_dir)
+ depth = svn_depth_empty;
+ else if (depth == svn_depth_unknown)
depth = svn_depth_infinity;
return svn_error_return(recursive_resolve_conflict(
wc_ctx->db,
local_abspath,
+ conflicted,
depth,
resolve_text,
resolve_prop,