You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/02/08 06:14:20 UTC

svn commit: r1565920 - /subversion/trunk/subversion/libsvn_client/update.c

Author: breser
Date: Sat Feb  8 05:14:20 2014
New Revision: 1565920

URL: http://svn.apache.org/r1565920
Log:
Reuse RA sessions with update --parents.

Prior code would walk up the tree and open a new RA session for each missing
parent.  This meant over DAV that for n missing parents you needed n RA
sessions, and along with that (n*2)+1 OPTIONS requests.  This change still
needs n REPORT requests but that's a more intrustive change for later.

Using the new code and checking out the subversion tree with depth empty from
the ASF repo and then updating with --parents the deepest tree we have halves
the update time over the old code.

* subversion/libsvn_client/update.c
  (update_internal): Add a new ra_session_p argument and handle reparenting
    if the session can be reused.  Save any new ra_sessions in the ra_session_p
    argument for reuse.
  (svn_client__update_internal): Update the update_internal() calls.

Modified:
    subversion/trunk/subversion/libsvn_client/update.c

Modified: subversion/trunk/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/update.c?rev=1565920&r1=1565919&r2=1565920&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/update.c (original)
+++ subversion/trunk/subversion/libsvn_client/update.c Sat Feb  8 05:14:20 2014
@@ -196,6 +196,10 @@ record_conflict(svn_wc_conflict_result_t
 
    Add the paths of any conflict victims to CONFLICTED_PATHS, if that
    is not null.
+
+   Use RA_SESSION_P to run the update if it is not NULL.  If it is then
+   open a new ra session and place it in RA_SESSION_P.  This allows 
+   repeated calls to update_internal to reuse the same session.
 */
 static svn_error_t *
 update_internal(svn_revnum_t *result_rev,
@@ -211,6 +215,7 @@ update_internal(svn_revnum_t *result_rev
                 svn_boolean_t *timestamp_sleep,
                 svn_boolean_t notify_summary,
                 svn_client_ctx_t *ctx,
+                svn_ra_session_t **ra_session_p,
                 apr_pool_t *pool)
 {
   const svn_delta_editor_t *update_editor;
@@ -229,7 +234,7 @@ update_internal(svn_revnum_t *result_rev
   const char *diff3_cmd;
   apr_hash_t *wcroot_iprops;
   svn_opt_revision_t opt_rev;
-  svn_ra_session_t *ra_session;
+  svn_ra_session_t *ra_session = *ra_session_p;
   const char *preserved_exts_str;
   apr_array_header_t *preserved_exts;
   struct svn_client__dirent_fetcher_baton_t dfb;
@@ -366,11 +371,41 @@ update_internal(svn_revnum_t *result_rev
       (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);
     }
 
-  /* Open an RA session for the URL */
-  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
-                                               anchor_url,
-                                               anchor_abspath, NULL, TRUE,
-                                               TRUE, ctx, pool, pool));
+  /* Try to reuse the RA session by reparenting it to the anchor_url.
+   * This code is probably overly cautious since we only use this
+   * currently when parents are missing and so all the anchor_urls
+   * have to be in the same repo. */
+  if (ra_session)
+    {
+      svn_error_t *err = svn_ra_reparent(ra_session, anchor_url, pool);
+      if (err)
+        {
+          if (err->apr_err == SVN_ERR_RA_ILLEGAL_URL)
+            {
+            /* session changed repos, can't reuse it */
+              svn_error_clear(err);
+              ra_session = NULL;
+            }
+          else
+            {
+              return svn_error_trace(err);
+            }
+        }
+      else
+        {
+          corrected_url = NULL;
+        }
+    }
+
+  /* Open an RA session for the URL if one isn't already available */
+  if (!ra_session)
+    {
+      SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
+                                                   anchor_url,
+                                                   anchor_abspath, NULL, TRUE,
+                                                   TRUE, ctx, pool, pool));
+      *ra_session_p = ra_session;
+    }
 
   /* If we got a corrected URL from the RA subsystem, we'll need to
      relocate our working copy first. */
@@ -524,6 +559,7 @@ svn_client__update_internal(svn_revnum_t
   const char *anchor_abspath, *lockroot_abspath;
   svn_error_t *err;
   svn_opt_revision_t peg_revision = *revision;
+  svn_ra_session_t *ra_session = NULL;
   apr_hash_t *conflicted_paths
     = ctx->conflict_func2 ? apr_hash_make(pool) : NULL;
 
@@ -572,7 +608,7 @@ svn_client__update_internal(svn_revnum_t
                                 &peg_revision, svn_depth_empty, FALSE,
                                 ignore_externals, allow_unver_obstructions,
                                 adds_as_modification, timestamp_sleep,
-                                FALSE, ctx, pool);
+                                FALSE, ctx, &ra_session, pool);
           if (err)
             goto cleanup;
           anchor_abspath = missing_parent;
@@ -597,7 +633,7 @@ svn_client__update_internal(svn_revnum_t
                         &peg_revision, depth, depth_is_sticky,
                         ignore_externals, allow_unver_obstructions,
                         adds_as_modification, timestamp_sleep,
-                        TRUE, ctx, pool);
+                        TRUE, ctx, &ra_session, pool);
 
   /* Give the conflict resolver callback the opportunity to
    * resolve any conflicts that were raised. */