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/02/05 17:36:02 UTC
svn commit: r1442652 -
/subversion/trunk/subversion/libsvn_client/locking_commands.c
Author: rhuijben
Date: Tue Feb 5 16:36:01 2013
New Revision: 1442652
URL: http://svn.apache.org/viewvc?rev=1442652&view=rev
Log:
In the locking code: Obtain url of BASE node, existing lock and revision with
just a single database operation.
* subversion/libsvn_client/locking_commands.c
(wc_lock_item_t): New struct.
(organize_lock_targets): Use wc_ctx argument. Build hash in first loop and
use result later.
(svn_client_lock,
svn_client_unlock): Update caller.
Modified:
subversion/trunk/subversion/libsvn_client/locking_commands.c
Modified: subversion/trunk/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/locking_commands.c?rev=1442652&r1=1442651&r2=1442652&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/trunk/subversion/libsvn_client/locking_commands.c Tue Feb 5 16:36:01 2013
@@ -189,6 +189,14 @@ condense_targets(const char **common_par
return SVN_NO_ERROR;
}
+/* Lock info. Used in organize_lock_targets.
+ ### Maybe return this instead of the ugly hashes? */
+struct wc_lock_item_t
+{
+ svn_revnum_t revision;
+ const char *lock_token;
+};
+
/* Set *COMMON_PARENT_URL to the nearest common parent URL of all TARGETS.
* If TARGETS are local paths, then the entry for each path is examined
* and *COMMON_PARENT is set to the common parent URL for all the
@@ -225,7 +233,7 @@ organize_lock_targets(const char **commo
const apr_array_header_t *targets,
svn_boolean_t do_lock,
svn_boolean_t force,
- svn_client_ctx_t *ctx,
+ svn_wc_context_t *wc_ctx,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -234,6 +242,7 @@ organize_lock_targets(const char **commo
apr_hash_t *rel_targets_ret = apr_hash_make(result_pool);
apr_hash_t *rel_fs_paths = NULL;
apr_array_header_t *rel_targets;
+ apr_hash_t *wc_info = apr_hash_make(scratch_pool);
svn_boolean_t url_mode;
int i;
@@ -289,20 +298,38 @@ organize_lock_targets(const char **commo
sizeof(const char *));
for (i = 0; i < rel_targets->nelts; i++)
{
- const char *rel_target, *local_abspath, *target_url;
+ const char *rel_target;
+ const char *repos_relpath;
+ const char *repos_root_url;
+ const char *target_url;
+ struct wc_lock_item_t *wli;
+ const char *local_abspath;
svn_pool_clear(iterpool);
rel_target = APR_ARRAY_IDX(rel_targets, i, const char *);
- local_abspath = svn_dirent_join(common_dirent, rel_target, iterpool);
- SVN_ERR(svn_wc__node_get_url(&target_url, ctx->wc_ctx, local_abspath,
- scratch_pool, iterpool));
- if (! target_url)
- return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
- _("'%s' has no URL"),
+ local_abspath = svn_dirent_join(common_dirent, rel_target, scratch_pool);
+ wli = apr_pcalloc(scratch_pool, sizeof(*wli));
+
+ SVN_ERR(svn_wc__node_get_base(&wli->revision, &repos_relpath,
+ &repos_root_url, NULL,
+ &wli->lock_token,
+ wc_ctx, local_abspath,
+ result_pool, iterpool));
+
+ /* Node exists in BASE? */
+ if (! repos_root_url || !repos_relpath)
+ return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The node '%s' was not found."),
svn_dirent_local_style(local_abspath,
iterpool));
+ apr_hash_set(wc_info, local_abspath, APR_HASH_KEY_STRING, wli);
+
+ target_url = svn_path_url_add_component2(repos_root_url,
+ repos_relpath,
+ scratch_pool);
+
APR_ARRAY_PUSH(target_urls, const char *) = target_url;
}
@@ -320,7 +347,8 @@ organize_lock_targets(const char **commo
rel_fs_paths = apr_hash_make(result_pool);
for (i = 0; i < rel_targets->nelts; i++)
{
- const char *rel_target, *rel_url, *abs_path;
+ const char *rel_target, *rel_url;
+ const char *local_abspath;
svn_pool_clear(iterpool);
@@ -336,35 +364,49 @@ organize_lock_targets(const char **commo
revision of the dirent target with which it is associated
(if our caller is locking) or to a (possible empty) lock
token string (if the caller is unlocking). */
- abs_path = svn_dirent_join(common_dirent, rel_target, iterpool);
+ local_abspath = svn_dirent_join(common_dirent, rel_target, iterpool);
if (do_lock) /* Lock. */
{
svn_revnum_t *revnum;
+ struct wc_lock_item_t *wli;
revnum = apr_palloc(result_pool, sizeof(* revnum));
- SVN_ERR(svn_wc__node_get_base(revnum, NULL, NULL, NULL, NULL,
- ctx->wc_ctx, abs_path,
- result_pool, iterpool));
+
+ wli = apr_hash_get(wc_info, local_abspath, APR_HASH_KEY_STRING);
+
+ SVN_ERR_ASSERT(wli != NULL);
+
+ *revnum = wli->revision;
+
apr_hash_set(rel_targets_ret, rel_url,
APR_HASH_KEY_STRING, revnum);
}
else /* Unlock. */
{
- const char *lock_token = NULL;
+ const char *lock_token;
+ struct wc_lock_item_t *wli;
/* If not forcing the unlock, get the lock token. */
if (! force)
{
- SVN_ERR(svn_wc__node_get_base(NULL, NULL, NULL, NULL,
- &lock_token,
- ctx->wc_ctx, abs_path,
- result_pool, iterpool));
- if (! lock_token)
+ wli = apr_hash_get(wc_info, local_abspath,
+ APR_HASH_KEY_STRING);
+
+ SVN_ERR_ASSERT(wli != NULL);
+
+ if (! wli->lock_token)
return svn_error_createf(
SVN_ERR_CLIENT_MISSING_LOCK_TOKEN, NULL,
_("'%s' is not locked in this working copy"),
- abs_path);
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+
+ lock_token = wli->lock_token
+ ? apr_pstrdup(result_pool, wli->lock_token)
+ : NULL;
}
+ else
+ lock_token = NULL;
/* If breaking a lock, we shouldn't pass any lock token. */
apr_hash_set(rel_targets_ret, rel_url, APR_HASH_KEY_STRING,
@@ -444,7 +486,7 @@ svn_client_lock(const apr_array_header_t
SVN_ERR(organize_lock_targets(&common_parent_url, &base_dir, &path_revs,
&urls_to_paths, targets, TRUE, steal_lock,
- ctx, pool, pool));
+ ctx->wc_ctx, pool, pool));
/* Open an RA session to the common parent of TARGETS. */
if (base_dir)
@@ -484,7 +526,7 @@ svn_client_unlock(const apr_array_header
SVN_ERR(organize_lock_targets(&common_parent_url, &base_dir, &path_tokens,
&urls_to_paths, targets, FALSE, break_lock,
- ctx, pool, pool));
+ ctx->wc_ctx, pool, pool));
/* Open an RA session. */
if (base_dir)