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)