You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by jc...@apache.org on 2011/01/14 01:07:27 UTC

svn commit: r1058809 [1/2] - in /subversion/branches/diff-optimizations-bytes: ./ build/generator/ notes/api-errata/1.7/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_diff/ subversion/libsvn_fs_base/bdb/ subversion/libsvn_ra/ ...

Author: jcorvel
Date: Fri Jan 14 00:07:25 2011
New Revision: 1058809

URL: http://svn.apache.org/viewvc?rev=1058809&view=rev
Log:
On the diff-optimizations-bytes branch:

Bring up-to-date with trunk.

Modified:
    subversion/branches/diff-optimizations-bytes/   (props changed)
    subversion/branches/diff-optimizations-bytes/INSTALL
    subversion/branches/diff-optimizations-bytes/build.conf
    subversion/branches/diff-optimizations-bytes/build/generator/gen_win.py
    subversion/branches/diff-optimizations-bytes/configure.ac
    subversion/branches/diff-optimizations-bytes/notes/api-errata/1.7/wc007.txt   (contents, props changed)
    subversion/branches/diff-optimizations-bytes/subversion/include/private/svn_adler32.h   (props changed)
    subversion/branches/diff-optimizations-bytes/subversion/include/private/svn_ra_private.h
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/add.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/commit.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/delete.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/locking_commands.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/merge.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/patch.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_diff/parse-diff.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_fs_base/bdb/env.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra/ra_loader.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/commit.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/merge.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/options.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/property.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/serf.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/update.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/util.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/adler32.c   (props changed)
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/dirent_uri.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/io.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/sqlite.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/upgrade.c
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-metadata.sql
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h
    subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c
    subversion/branches/diff-optimizations-bytes/subversion/mod_authz_svn/mod_authz_svn.c
    subversion/branches/diff-optimizations-bytes/subversion/tests/libsvn_subr/dirent_uri-test.c
    subversion/branches/diff-optimizations-bytes/subversion/tests/libsvn_wc/db-test.c
    subversion/branches/diff-optimizations-bytes/subversion/tests/libsvn_wc/entries-compat.c
    subversion/branches/diff-optimizations-bytes/tools/po/l10n-report.py

Propchange: subversion/branches/diff-optimizations-bytes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 14 00:07:25 2011
@@ -40,4 +40,4 @@
 /subversion/branches/tc_url_rev:874351-874483
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
-/subversion/trunk:1031270-1057038
+/subversion/trunk:1031270-1058787

Modified: subversion/branches/diff-optimizations-bytes/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/INSTALL?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/INSTALL (original)
+++ subversion/branches/diff-optimizations-bytes/INSTALL Fri Jan 14 00:07:25 2011
@@ -504,8 +504,8 @@ I.    INTRODUCTION
 
       13. SQLite  (REQUIRED)
 
-      Subversion (starting with version 1.6) requires SQLite version
-      3.4.0 or above, and you can meet this dependency several ways:
+      Subversion 1.7 requires SQLite version 3.6.18 or above.  You can meet
+      this dependency several ways:
         * Use an SQLite amalgamation file.
         * Specify an SQLite installation to use.
         * Let Subversion find an installed SQLite.

Modified: subversion/branches/diff-optimizations-bytes/build.conf
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/build.conf?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/build.conf (original)
+++ subversion/branches/diff-optimizations-bytes/build.conf Fri Jan 14 00:07:25 2011
@@ -53,10 +53,10 @@ private-built-includes =
         subversion/bindings/javahl/include/org_apache_subversion_javahl_CommitItemStateFlags.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_NativeResources.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_Path.h
-        subversion/bindings/javahl/include/org_apache_subversion_javahl_Revision.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_SVNRepos.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_SVNClient.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_types_Version.h
+        subversion/bindings/javahl/include/org_apache_subversion_javahl_types_Revision.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_callback_UserPasswordCallback.h
 
 

Modified: subversion/branches/diff-optimizations-bytes/build/generator/gen_win.py
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/build/generator/gen_win.py?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/build/generator/gen_win.py (original)
+++ subversion/branches/diff-optimizations-bytes/build/generator/gen_win.py Fri Jan 14 00:07:25 2011
@@ -1544,8 +1544,9 @@ class WinGeneratorBase(GeneratorBase):
     msg = 'Found SQLite version %s\n'
 
     major, minor, patch = version
-    if major < 3 or (major == 3 and minor < 4):
-      sys.stderr.write("ERROR: SQLite 3.4.0 or higher is required "
+    if major < 3 or (major == 3 and minor < 6) \
+                 or (major == 3 and minor == 6 and patch < 18):
+      sys.stderr.write("ERROR: SQLite 3.6.18 or higher is required "
                        "(%s found)\n" % self.sqlite_version);
       sys.exit(1)
     else:

Modified: subversion/branches/diff-optimizations-bytes/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/configure.ac?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/configure.ac (original)
+++ subversion/branches/diff-optimizations-bytes/configure.ac Fri Jan 14 00:07:25 2011
@@ -152,7 +152,7 @@ dnl Find Apache with a recent-enough mag
 SVN_FIND_APACHE(20020903)
 
 dnl Search for SQLite
-SQLITE_MINIMUM_VER="3.4.0"
+SQLITE_MINIMUM_VER="3.6.18"
 SQLITE_RECOMMENDED_VER="3.7.2"
 SQLITE_URL="http://www.sqlite.org/sqlite-amalgamation-${SQLITE_RECOMMENDED_VER}.tar.gz"
 SVN_LIB_SQLITE(${SQLITE_MINIMUM_VER}, ${SQLITE_RECOMMENDED_VER},

Modified: subversion/branches/diff-optimizations-bytes/notes/api-errata/1.7/wc007.txt
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/notes/api-errata/1.7/wc007.txt?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/notes/api-errata/1.7/wc007.txt (original)
+++ subversion/branches/diff-optimizations-bytes/notes/api-errata/1.7/wc007.txt Fri Jan 14 00:07:25 2011
@@ -1,4 +1,4 @@
-API ERRATA -- $Id: wc006.txt 943050 2010-05-11 08:56:25Z julianfoad $
+API ERRATA -- $Id$
 
 Root Cause of Errata: 
  Library(s) Affected: libsvn_wc

Propchange: subversion/branches/diff-optimizations-bytes/notes/api-errata/1.7/wc007.txt
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: subversion/branches/diff-optimizations-bytes/subversion/include/private/svn_adler32.h
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 14 00:07:25 2011
@@ -40,4 +40,4 @@
 /subversion/branches/tc_url_rev/subversion/libsvn_diff/diff.h:874351-874483
 /subversion/branches/tree-conflicts/subversion/libsvn_diff/diff.h:868291-873154
 /subversion/branches/tree-conflicts-notify/subversion/libsvn_diff/diff.h:873926-874008
-/subversion/trunk/subversion/include/private/svn_adler32.h:1054278-1057038
+/subversion/trunk/subversion/include/private/svn_adler32.h:1054278-1058787

Modified: subversion/branches/diff-optimizations-bytes/subversion/include/private/svn_ra_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/include/private/svn_ra_private.h?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/include/private/svn_ra_private.h (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/include/private/svn_ra_private.h Fri Jan 14 00:07:25 2011
@@ -102,6 +102,11 @@ typedef svn_error_t *(*svn_ra__lock_retr
  * Use @a cancel_func and @a cancel_baton to check for early
  * cancellation.
  *
+ * @note If the server does not support #SVN_RA_CAPABILITY_ATOMIC_REVPROPS
+ * (i.e., is a pre-1.7 server), then this function makes a "best effort"
+ * attempt to obtain the lock, but is susceptible to a race condition; see
+ * issue #3546.
+ *
  * @since New in 1.7.
  */
 svn_error_t *

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/add.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/add.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/add.c Fri Jan 14 00:07:25 2011
@@ -462,6 +462,11 @@ struct add_with_write_lock_baton {
   svn_boolean_t force;
   svn_boolean_t no_ignore;
   svn_client_ctx_t *ctx;
+
+  /* Absolute path to the first existing parent directory of local_abspath.
+   * If not NULL, all missing parents of local_abspath must be created
+   * before local_abspath can be added. */
+  const char *existing_parent_abspath;
 };
 
 /* The main logic of the public svn_client_add4. */
@@ -472,6 +477,47 @@ add(void *baton, apr_pool_t *result_pool
   svn_error_t *err;
   struct add_with_write_lock_baton *b = baton;
 
+  if (b->existing_parent_abspath)
+    {
+      const char *parent_abspath;
+      const char *child_relpath;
+      apr_array_header_t *components;
+      int i;
+      apr_pool_t *iterpool;
+
+      parent_abspath = b->existing_parent_abspath;
+      child_relpath = svn_dirent_is_child(b->existing_parent_abspath,
+                                          b->local_abspath, NULL);
+      components = svn_path_decompose(child_relpath, scratch_pool);
+      iterpool = svn_pool_create(scratch_pool);
+      for (i = 0; i < components->nelts - 1; i++)
+        {
+          const char *component;
+          svn_node_kind_t disk_kind;
+
+          svn_pool_clear(iterpool);
+
+          if (b->ctx->cancel_func)
+            SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
+
+          component = APR_ARRAY_IDX(components, i, const char *);
+          parent_abspath = svn_dirent_join(parent_abspath, component,
+                                           scratch_pool);
+          SVN_ERR(svn_io_check_path(parent_abspath, &disk_kind, iterpool));
+          if (disk_kind != svn_node_none && disk_kind != svn_node_dir)
+            return svn_error_createf(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL,
+                                     _("'%s' prevents creating parent of '%s'"),
+                                     parent_abspath, b->local_abspath);
+
+          SVN_ERR(svn_io_make_dir_recursively(parent_abspath, scratch_pool));
+          SVN_ERR(svn_wc_add_from_disk(b->ctx->wc_ctx, parent_abspath,
+                                       b->ctx->notify_func2,
+                                       b->ctx->notify_baton2,
+                                       scratch_pool));
+        }
+      svn_pool_destroy(iterpool);
+    }
+
   SVN_ERR(svn_io_check_path(b->local_abspath, &kind, scratch_pool));
   if (kind == svn_node_dir)
     {
@@ -505,26 +551,27 @@ add(void *baton, apr_pool_t *result_pool
 }
 
 
-/* Go up the directory tree, looking for a versioned directory.  If found,
-   add all the intermediate directories.  Otherwise, return
-   SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
-/* ### This function needs rewriting into its callers in a style that finds the
-       parent and then acquires an infinite depth lock there for the entire
-       operation */
+/* Go up the directory tree from LOCAL_ABSPATH, looking for a versioned
+ * directory.  If found, return its path in *EXISTING_PARENT_ABSPATH.
+ * Otherwise, return SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
 static svn_error_t *
-add_parent_dirs(svn_client_ctx_t *ctx,
-                const char *local_abspath,
-                apr_pool_t *scratch_pool)
+find_existing_parent(const char **existing_parent_abspath,
+                     svn_client_ctx_t *ctx,
+                     const char *local_abspath,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
 {
   int format;
   const char *parent_abspath;
-  svn_boolean_t own_lock;
   svn_wc_context_t *wc_ctx = ctx->wc_ctx;
 
   SVN_ERR(svn_wc_check_wc2(&format, wc_ctx, local_abspath, scratch_pool));
 
   if (format > 0)
-    return SVN_NO_ERROR;
+    {
+      *existing_parent_abspath = apr_pstrdup(result_pool, local_abspath);
+      return SVN_NO_ERROR;
+    }
 
   if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
     return svn_error_create(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL, NULL);
@@ -538,25 +585,11 @@ add_parent_dirs(svn_client_ctx_t *ctx,
 
   parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
-  SVN_ERR(add_parent_dirs(ctx, parent_abspath, scratch_pool));
-
-  SVN_ERR(svn_wc_locked2(&own_lock, NULL, wc_ctx, parent_abspath,
-                         scratch_pool));
-
-  if (!own_lock)
-    SVN_ERR(svn_wc__acquire_write_lock(NULL, wc_ctx, parent_abspath, FALSE,
-                                       scratch_pool, scratch_pool));
-
   if (ctx->cancel_func)
     SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-  SVN_ERR(svn_wc_add_from_disk(wc_ctx, local_abspath,
-                               ctx->notify_func2, ctx->notify_baton2,
-                               scratch_pool));
-  /* ### New dir gets added with its own per-directory lock which we
-     must release.  This code should be redundant when we move to a
-     single db. */
-  SVN_ERR(svn_wc__release_write_lock(wc_ctx, parent_abspath, scratch_pool));
+  SVN_ERR(find_existing_parent(existing_parent_abspath, ctx, parent_abspath,
+                               result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -594,12 +627,17 @@ svn_client_add4(const char *path,
   else
     parent_abspath = svn_dirent_dirname(local_abspath, pool);
 
+  baton.existing_parent_abspath = NULL;
   if (add_parents)
     {
       apr_pool_t *subpool;
+      const char *existing_parent_abspath;
 
       subpool = svn_pool_create(pool);
-      SVN_ERR(add_parent_dirs(ctx, parent_abspath, subpool));
+      SVN_ERR(find_existing_parent(&existing_parent_abspath, ctx,
+                                   parent_abspath, pool, subpool));
+      if (strcmp(existing_parent_abspath, parent_abspath) != 0)
+        baton.existing_parent_abspath = existing_parent_abspath;
       svn_pool_destroy(subpool);
     }
 
@@ -609,8 +647,10 @@ svn_client_add4(const char *path,
   baton.no_ignore = no_ignore;
   baton.ctx = ctx;
   SVN_ERR(svn_wc__call_with_write_lock(add, &baton, ctx->wc_ctx,
-                                       parent_abspath, FALSE,
-                                       pool, pool));
+                                       baton.existing_parent_abspath
+                                         ? baton.existing_parent_abspath
+                                         : parent_abspath,
+                                       FALSE, pool, pool));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/commit.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/commit.c Fri Jan 14 00:07:25 2011
@@ -1091,6 +1091,13 @@ svn_client_commit5(const apr_array_heade
   SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, base_abspath,
                                      FALSE, pool, pool));
 
+  /*
+   * At this point, the working copy must be unlocked (if possible)
+   * before returning from this function. So we must now handle every
+   * error explicitly, rather than using SVN_ERR().
+   *
+   */
+
   /* One day we might support committing from multiple working copies, but
      we don't yet.  This check ensures that we don't silently commit a
      subset of the targets.
@@ -1105,8 +1112,13 @@ svn_client_commit5(const apr_array_heade
         const char *target_path = APR_ARRAY_IDX(targets, i, const char *);
 
         svn_pool_clear(iterpool);
-        SVN_ERR(check_nonrecursive_dir_delete(target_path, ctx->wc_ctx, depth,
-                                              iterpool));
+        cmt_err = check_nonrecursive_dir_delete(target_path, ctx->wc_ctx,
+                                                depth, iterpool);
+        if (cmt_err)
+          {
+            svn_pool_destroy(iterpool);
+            goto cleanup;
+          }
       }
     svn_pool_destroy(iterpool);
   }

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/delete.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/delete.c Fri Jan 14 00:07:25 2011
@@ -158,7 +158,7 @@ delete_urls(const apr_array_header_t *pa
 
   /* Condense our list of deletion targets. */
   SVN_ERR(svn_uri_condense_targets(&common, &targets, paths, TRUE,
-                                   pool, pool));
+                                   pool, subpool));
   if (! targets->nelts)
     {
       const char *bname;

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/locking_commands.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/locking_commands.c Fri Jan 14 00:07:25 2011
@@ -175,13 +175,13 @@ organize_lock_targets(const char **commo
                       svn_boolean_t do_lock,
                       svn_boolean_t force,
                       svn_client_ctx_t *ctx,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   int i;
-  apr_array_header_t *rel_targets = apr_array_make(pool, 1,
+  apr_array_header_t *rel_targets = apr_array_make(result_pool, 1,
                                                    sizeof(const char *));
-  apr_hash_t *rel_targets_ret = apr_hash_make(pool);
-  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_hash_t *rel_targets_ret = apr_hash_make(result_pool);
   svn_boolean_t url_mode;
 
   SVN_ERR(svn_client__assert_homogeneous_target_type(targets));
@@ -192,10 +192,12 @@ organize_lock_targets(const char **commo
   /* Get the common parent and all paths */
   if (url_mode)
     SVN_ERR(svn_uri_condense_targets(common_parent_url, &rel_targets,
-                                     targets, TRUE, pool, pool));
+                                     targets, TRUE, result_pool,
+                                     scratch_pool));
   else
     SVN_ERR(svn_dirent_condense_targets(common_parent_url, &rel_targets,
-                                        targets, TRUE, pool, pool));
+                                        targets, TRUE, result_pool,
+                                        scratch_pool));
 
   /* svn_uri_condense_targets and svn_dirent_condense_targets leaves
      URLs/paths empty if TARGETS only had 1 member, so we special case
@@ -204,9 +206,9 @@ organize_lock_targets(const char **commo
     {
       const char *parent, *base;
       if (url_mode)
-        svn_uri_split(&parent, &base, *common_parent_url, pool);
+        svn_uri_split(&parent, &base, *common_parent_url, result_pool);
       else
-        svn_dirent_split(&parent, &base, *common_parent_url, pool);
+        svn_dirent_split(&parent, &base, *common_parent_url, result_pool);
 
       *common_parent_url = parent;
       APR_ARRAY_PUSH(rel_targets, const char *) = base;
@@ -220,14 +222,15 @@ organize_lock_targets(const char **commo
   if (url_mode)
     {
       svn_revnum_t *invalid_revnum;
-      invalid_revnum = apr_palloc(pool, sizeof(*invalid_revnum));
+      invalid_revnum = apr_palloc(result_pool, sizeof(*invalid_revnum));
       *invalid_revnum = SVN_INVALID_REVNUM;
       *base_dir = NULL;
 
       for (i = 0; i < rel_targets->nelts; i++)
         {
           const char *target = APR_ARRAY_IDX(rel_targets, i, const char *);
-          apr_hash_set(rel_targets_ret, svn_path_uri_decode(target, pool),
+          apr_hash_set(rel_targets_ret,
+                       svn_path_uri_decode(target, result_pool),
                        APR_HASH_KEY_STRING,
                        do_lock ? (const void *) invalid_revnum
                        : (const void *) "");
@@ -237,9 +240,10 @@ organize_lock_targets(const char **commo
   else  /* common parent is a local path */
     {
       apr_array_header_t *rel_urls;
-      apr_array_header_t *urls = apr_array_make(pool, 1,
+      apr_array_header_t *urls = apr_array_make(scratch_pool, 1,
                                                 sizeof(const char *));
-      apr_hash_t *urls_hash = apr_hash_make(pool);
+      apr_hash_t *urls_hash = apr_hash_make(scratch_pool);
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
       const char *common_url;
 
       *base_dir = *common_parent_url;
@@ -251,31 +255,31 @@ organize_lock_targets(const char **commo
           const char *local_abspath;
           const char *url;
 
-          svn_pool_clear(subpool);
+          svn_pool_clear(iterpool);
 
-          local_abspath = svn_dirent_join(*common_parent_url, target, subpool);
+          local_abspath = svn_dirent_join(*common_parent_url, target, iterpool);
 
           SVN_ERR(svn_wc__node_get_url(&url, ctx->wc_ctx, local_abspath,
-                                       pool, subpool));
+                                       scratch_pool, iterpool));
 
           if (! url)
             return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
                                      _("'%s' has no URL"),
-                                     svn_dirent_local_style(target, pool));
+                                     svn_dirent_local_style(target, iterpool));
 
           APR_ARRAY_PUSH(urls, const char *) = url;
         }
 
       /* Condense our absolute urls and get the relative urls. */
       SVN_ERR(svn_uri_condense_targets(&common_url, &rel_urls, urls,
-                                       FALSE, pool, pool));
+                                       FALSE, result_pool, scratch_pool));
 
       /* svn_uri_condense_targets leaves URLs empty if TARGETS only
          had 1 member, so we special case that (again). */
       if (apr_is_empty_array(rel_urls))
         {
-          const char *base_name = svn_uri_basename(common_url, pool);
-          common_url = svn_uri_dirname(common_url, pool);
+          const char *base_name = svn_uri_basename(common_url, scratch_pool);
+          common_url = svn_uri_dirname(common_url, result_pool);
           APR_ARRAY_PUSH(rel_urls, const char *) = base_name;
         }
 
@@ -292,22 +296,22 @@ organize_lock_targets(const char **commo
           const char *target = APR_ARRAY_IDX(rel_targets, i, const char *);
           const char *url = APR_ARRAY_IDX(rel_urls, i, const char *);
           const char *abs_path;
-          const char *decoded_url = svn_path_uri_decode(url, pool);
+          const char *decoded_url = svn_path_uri_decode(url, scratch_pool);
 
-          svn_pool_clear(subpool);
+          svn_pool_clear(iterpool);
 
           apr_hash_set(urls_hash, decoded_url,
                        APR_HASH_KEY_STRING,
-                       apr_pstrdup(pool, target));
+                       apr_pstrdup(scratch_pool, target));
 
-          abs_path = svn_dirent_join(*common_parent_url, target, subpool);
+          abs_path = svn_dirent_join(*common_parent_url, target, iterpool);
 
           if (do_lock) /* Lock. */
             {
               svn_revnum_t *revnum;
-              revnum = apr_palloc(pool, sizeof(* revnum));
+              revnum = apr_palloc(result_pool, sizeof(* revnum));
               SVN_ERR(svn_wc__node_get_base_rev(revnum, ctx->wc_ctx,
-                                                abs_path, subpool));
+                                                abs_path, result_pool));
               apr_hash_set(rel_targets_ret, decoded_url,
                            APR_HASH_KEY_STRING, revnum);
             }
@@ -320,7 +324,8 @@ organize_lock_targets(const char **commo
 
                   SVN_ERR(svn_wc__node_get_lock_info(&lock_token, NULL, NULL,
                                                      NULL, ctx->wc_ctx,
-                                                     abs_path, pool, subpool));
+                                                     abs_path, result_pool,
+                                                     iterpool));
                   if (! lock_token)
                     return svn_error_createf
                       (SVN_ERR_CLIENT_MISSING_LOCK_TOKEN, NULL,
@@ -341,10 +346,10 @@ organize_lock_targets(const char **commo
 
       *rel_fs_paths_p = urls_hash;
       *common_parent_url = common_url;
+      svn_pool_destroy(iterpool);
     }
 
   *rel_targets_p = rel_targets_ret;
-  svn_pool_destroy(subpool);
   return SVN_NO_ERROR;
 }
 
@@ -408,7 +413,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));
+                                ctx, pool, pool));
 
   /* Open an RA session to the common parent of TARGETS. */
   if (base_dir)
@@ -448,7 +453,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));
+                                ctx, pool, pool));
 
   /* Open an RA session. */
   if (base_dir)

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/merge.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/merge.c Fri Jan 14 00:07:25 2011
@@ -529,7 +529,9 @@ make_tree_conflict(svn_wc_conflict_descr
 }
 
 /* Record a tree conflict in the WC, unless this is a dry run or a record-
- * only merge.
+ * only merge, or if a tree conflict is already flagged for the VICTIM_PATH.
+ * (The latter can happen if a merge-tracking-aware merge is doing multiple
+ * editor drives because of a gap in the range of eligible revisions.)
  *
  * The tree conflict, with its victim specified by VICTIM_PATH, is
  * assumed to have happened during a merge using merge baton MERGE_B.
@@ -546,16 +548,25 @@ tree_conflict(merge_cmd_baton_t *merge_b
               svn_wc_conflict_action_t action,
               svn_wc_conflict_reason_t reason)
 {
+  const svn_wc_conflict_description2_t *existing_conflict;
   svn_wc_conflict_description2_t *conflict;
 
   if (merge_b->record_only || merge_b->dry_run)
     return SVN_NO_ERROR;
 
-  SVN_ERR(make_tree_conflict(&conflict, merge_b, victim_abspath,
-                             node_kind, action, reason));
+  SVN_ERR(svn_wc__get_tree_conflict(&existing_conflict, merge_b->ctx->wc_ctx,
+                                    victim_abspath, merge_b->pool,
+                                    merge_b->pool));
+  if (existing_conflict == NULL)
+    {
+      /* There is no existing tree conflict so it is safe to add one. */
+      SVN_ERR(make_tree_conflict(&conflict, merge_b, victim_abspath,
+                                 node_kind, action, reason));
+      SVN_ERR(svn_wc__add_tree_conflict(merge_b->ctx->wc_ctx, conflict,
+                                        merge_b->pool));
+    }
 
-  return svn_error_return(
-    svn_wc__add_tree_conflict(merge_b->ctx->wc_ctx, conflict, merge_b->pool));
+  return SVN_NO_ERROR;
 }
 
 /* Similar to tree_conflict(), but if this is an "add" action and there

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/patch.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_client/patch.c Fri Jan 14 00:07:25 2011
@@ -32,6 +32,7 @@
 #include "svn_client.h"
 #include "svn_dirent_uri.h"
 #include "svn_diff.h"
+#include "svn_hash.h"
 #include "svn_io.h"
 #include "svn_path.h"
 #include "svn_pools.h"
@@ -48,7 +49,7 @@
 
 typedef struct hunk_info_t {
   /* The hunk. */
-  const svn_diff_hunk_t *hunk;
+  svn_diff_hunk_t *hunk;
 
   /* The line where the hunk matched in the target file. */
   svn_linenum_t matched_line;
@@ -483,7 +484,7 @@ init_prop_target(prop_patch_target_t **p
 
   content_info = apr_pcalloc(result_pool, sizeof(*content_info));
 
-  /* All other fields in are FALSE or NULL due to apr_pcalloc().*/
+  /* All other fields are FALSE or NULL due to apr_pcalloc(). */
   content_info->current_line = 1;
   content_info->eol_style = svn_subst_eol_style_none;
   content_info->lines = apr_array_make(result_pool, 0,
@@ -834,7 +835,7 @@ seek_to_line(target_content_info_t *cont
  * Do temporary allocations in POOL. */
 static svn_error_t *
 match_hunk(svn_boolean_t *matched, target_content_info_t *content_info,
-           const svn_diff_hunk_t *hunk, int fuzz,
+           svn_diff_hunk_t *hunk, int fuzz,
            svn_boolean_t ignore_whitespace,
            svn_boolean_t match_modified, apr_pool_t *pool)
 {
@@ -950,7 +951,7 @@ match_hunk(svn_boolean_t *matched, targe
 static svn_error_t *
 scan_for_match(svn_linenum_t *matched_line,
                target_content_info_t *content_info,
-               const svn_diff_hunk_t *hunk, svn_boolean_t match_first,
+               svn_diff_hunk_t *hunk, svn_boolean_t match_first,
                svn_linenum_t upper_line, int fuzz,
                svn_boolean_t ignore_whitespace,
                svn_boolean_t match_modified,
@@ -1022,7 +1023,7 @@ scan_for_match(svn_linenum_t *matched_li
 static svn_error_t *
 match_existing_target(svn_boolean_t *match,
                       target_content_info_t *content_info,
-                      const svn_diff_hunk_t *hunk,
+                      svn_diff_hunk_t *hunk,
                       svn_stream_t *stream,
                       apr_pool_t *scratch_pool)
 {
@@ -1087,7 +1088,7 @@ match_existing_target(svn_boolean_t *mat
 static svn_error_t *
 get_hunk_info(hunk_info_t **hi, patch_target_t *target,
               target_content_info_t *content_info,
-              const svn_diff_hunk_t *hunk, int fuzz,
+              svn_diff_hunk_t *hunk, int fuzz,
               svn_boolean_t ignore_whitespace,
               svn_boolean_t is_prop_hunk,
               svn_cancel_func_t cancel_func, void *cancel_baton,
@@ -1301,7 +1302,7 @@ copy_lines_to_target(target_content_info
  * Do temporary allocations in POOL. */
 static svn_error_t *
 reject_hunk(patch_target_t *target, target_content_info_t *content_info,
-            const svn_diff_hunk_t *hunk, const char *prop_name,
+            svn_diff_hunk_t *hunk, const char *prop_name,
             apr_pool_t *pool)
 {
   const char *hunk_header;
@@ -1701,6 +1702,9 @@ apply_one_patch(patch_target_t **patch_t
 
       svn_pool_clear(iterpool);
 
+      if (cancel_func)
+        SVN_ERR((cancel_func)(cancel_baton));
+
       hi = APR_ARRAY_IDX(target->content_info->hunks, i, hunk_info_t *);
       if (hi->already_applied)
         continue;
@@ -1935,8 +1939,7 @@ create_missing_parents(patch_target_t *t
 
       svn_pool_clear(iterpool);
 
-      component = APR_ARRAY_IDX(components, i,
-                                const char *);
+      component = APR_ARRAY_IDX(components, i, const char *);
       local_abspath = svn_dirent_join(local_abspath, component, scratch_pool);
 
       SVN_ERR(svn_wc_read_kind(&wc_kind, ctx->wc_ctx, local_abspath, TRUE,
@@ -1990,8 +1993,7 @@ create_missing_parents(patch_target_t *t
       for (i = 0; i < present_components; i++)
         {
           const char *component;
-          component = APR_ARRAY_IDX(components, i,
-                                    const char *);
+          component = APR_ARRAY_IDX(components, i, const char *);
           local_abspath = svn_dirent_join(local_abspath,
                                           component, scratch_pool);
         }
@@ -2011,10 +2013,9 @@ create_missing_parents(patch_target_t *t
 
           svn_pool_clear(iterpool);
 
-          component = APR_ARRAY_IDX(components, i,
-                                    const char *);
+          component = APR_ARRAY_IDX(components, i, const char *);
           local_abspath = svn_dirent_join(local_abspath, component,
-                                     scratch_pool);
+                                          scratch_pool);
           if (dry_run)
             {
               if (ctx->notify_func2)
@@ -2211,6 +2212,9 @@ install_patched_prop_targets(patch_targe
 
       svn_pool_clear(iterpool);
 
+      if (ctx->cancel_func)
+        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+
       /* For a deleted prop we only set the value to NULL. */
       if (prop_target->operation == svn_diff_op_deleted)
         {
@@ -2267,8 +2271,6 @@ install_patched_prop_targets(patch_targe
             {
               SVN_ERR(svn_io_file_create(target->local_abspath, "",
                                          scratch_pool));
-              if (ctx->cancel_func)
-                SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
               SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
                                            /* suppress notification */
                                            NULL, NULL,
@@ -2368,14 +2370,14 @@ find_existing_children(void *baton,
 
 /* Indicate in *EMPTY whether the directory at LOCAL_ABSPATH has any
  * versioned or unversioned children. Consider any DELETED_TARGETS,
- * as well as paths listed in DELETED_ABSPATHS_LIST (which may be NULL)
- * as already deleted. Use WC_CTX as the working copy context.
+ * as well as paths occuring as keys of DELETED_ABSPATHS_HASH (which may
+ * be NULL) as already deleted. Use WC_CTX as the working copy context.
  * Do temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 check_dir_empty(svn_boolean_t *empty, const char *local_abspath,
                 svn_wc_context_t *wc_ctx,
                 apr_array_header_t *deleted_targets,
-                apr_array_header_t *deleted_abspath_list,
+                apr_hash_t *deleted_abspath_hash,
                 apr_pool_t *scratch_pool)
 {
   struct status_baton btn;
@@ -2423,13 +2425,17 @@ check_dir_empty(svn_boolean_t *empty, co
               break;
            }
         }
-      if (! deleted && deleted_abspath_list)
+      if (! deleted && deleted_abspath_hash)
         {
-          for (j = 0; j < deleted_abspath_list->nelts; j++)
+          apr_hash_index_t *hi;
+
+          for (hi = apr_hash_first(scratch_pool, deleted_abspath_hash);
+               hi;
+               hi = apr_hash_next(hi))
             {
               const char *abspath;
 
-              abspath = APR_ARRAY_IDX(deleted_abspath_list, j, const char *);
+              abspath = svn__apr_hash_index_key(hi);
               if (! svn_path_compare_paths(found, abspath))
                {
                   deleted = TRUE;
@@ -2447,33 +2453,6 @@ check_dir_empty(svn_boolean_t *empty, co
   return SVN_NO_ERROR;
 }
 
-/* Push a copy of EMPTY_DIR, allocated in RESULT_POOL, onto the EMPTY_DIRS
- * array if no directory matching EMPTY_DIR is already in the array. */
-static void
-push_if_unique(apr_array_header_t *empty_dirs, const char *empty_dir,
-               apr_pool_t *result_pool)
-{
-  svn_boolean_t is_unique;
-  int i;
-
-  is_unique = TRUE;
-  for (i = 0; i < empty_dirs->nelts; i++)
-    {
-      const char *empty_dir2;
-
-      empty_dir2 = APR_ARRAY_IDX(empty_dirs, i, const char *);
-      if (strcmp(empty_dir, empty_dir2) == 0)
-        {
-          is_unique = FALSE;
-          break;
-        }
-    }
-
-  if (is_unique)
-    APR_ARRAY_PUSH(empty_dirs, const char *) = apr_pstrdup(result_pool,
-                                                           empty_dir);
-}
-
 /* Delete all directories from the working copy which are left empty
  * by deleted TARGETS. Use client context CTX.
  * If DRY_RUN is TRUE, do not modify the working copy.
@@ -2482,11 +2461,13 @@ static svn_error_t *
 delete_empty_dirs(apr_array_header_t *targets_info, svn_client_ctx_t *ctx,
                   svn_boolean_t dry_run, apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *empty_dirs;
+  apr_hash_t *empty_dirs;
+  apr_hash_t *non_empty_dirs;
   apr_array_header_t *deleted_targets;
   apr_pool_t *iterpool;
   svn_boolean_t again;
   int i;
+  apr_hash_index_t *hi;
 
   /* Get a list of all deleted targets. */
   deleted_targets = apr_array_make(scratch_pool, 0, sizeof(patch_target_t *));
@@ -2504,7 +2485,8 @@ delete_empty_dirs(apr_array_header_t *ta
     return SVN_NO_ERROR;
 
   /* Look for empty parent directories of deleted targets. */
-  empty_dirs = apr_array_make(scratch_pool, 0, sizeof(const char *));
+  empty_dirs = apr_hash_make(scratch_pool);
+  non_empty_dirs = apr_hash_make(scratch_pool);
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < targets_info->nelts; i++)
     {
@@ -2519,17 +2501,24 @@ delete_empty_dirs(apr_array_header_t *ta
 
       target_info = APR_ARRAY_IDX(targets_info, i, patch_target_info_t *);
       parent = svn_dirent_dirname(target_info->local_abspath, iterpool);
+
+      if (apr_hash_get(non_empty_dirs, parent, APR_HASH_KEY_STRING))
+        continue;
+      else if (apr_hash_get(empty_dirs, parent, APR_HASH_KEY_STRING))
+        continue;
+
       SVN_ERR(check_dir_empty(&parent_empty, parent, ctx->wc_ctx,
                               deleted_targets, NULL, iterpool));
       if (parent_empty)
-        {
-          APR_ARRAY_PUSH(empty_dirs, const char *) =
-            apr_pstrdup(scratch_pool, parent);
-        }
+        apr_hash_set(empty_dirs, apr_pstrdup(scratch_pool, parent),
+                     APR_HASH_KEY_STRING, "");
+      else
+        apr_hash_set(non_empty_dirs, apr_pstrdup(scratch_pool, parent),
+                     APR_HASH_KEY_STRING, "");
     }
 
   /* We have nothing to do if there aren't any empty directories. */
-  if (empty_dirs->nelts == 0)
+  if (apr_hash_count(empty_dirs) == 0)
     {
       svn_pool_destroy(iterpool);
       return SVN_NO_ERROR;
@@ -2538,7 +2527,7 @@ delete_empty_dirs(apr_array_header_t *ta
   /* Determine the minimal set of empty directories we need to delete. */
   do
     {
-      apr_array_header_t *empty_dirs_copy;
+      apr_hash_t *empty_dirs_copy;
 
       svn_pool_clear(iterpool);
 
@@ -2548,32 +2537,43 @@ delete_empty_dirs(apr_array_header_t *ta
       /* Rebuild the empty dirs list, replacing empty dirs which have
        * an empty parent with their parent. */
       again = FALSE;
-      empty_dirs_copy = apr_array_copy(iterpool, empty_dirs);
-      apr_array_clear(empty_dirs);
-      for (i = 0; i < empty_dirs_copy->nelts; i++)
+      empty_dirs_copy = apr_hash_copy(iterpool, empty_dirs);
+      SVN_ERR(svn_hash__clear(empty_dirs, iterpool));
+
+      for (hi = apr_hash_first(iterpool, empty_dirs_copy);
+           hi;
+           hi = apr_hash_next(hi))
         {
           svn_boolean_t parent_empty;
           const char *empty_dir;
           const char *parent;
 
-          empty_dir = APR_ARRAY_IDX(empty_dirs_copy, i, const char *);
+          empty_dir = svn__apr_hash_index_key(hi);
           parent = svn_dirent_dirname(empty_dir, iterpool);
+
+          if (apr_hash_get(empty_dirs, parent, APR_HASH_KEY_STRING))
+            continue;
+
           SVN_ERR(check_dir_empty(&parent_empty, parent, ctx->wc_ctx,
                                   deleted_targets, empty_dirs_copy,
                                   iterpool));
           if (parent_empty)
             {
               again = TRUE;
-              push_if_unique(empty_dirs, parent, scratch_pool);
+              apr_hash_set(empty_dirs, apr_pstrdup(scratch_pool, parent),
+                           APR_HASH_KEY_STRING, "");
             }
           else
-            push_if_unique(empty_dirs, empty_dir, scratch_pool);
+            apr_hash_set(empty_dirs, apr_pstrdup(scratch_pool, empty_dir),
+                         APR_HASH_KEY_STRING, "");
         }
     }
   while (again);
 
   /* Finally, delete empty directories. */
-  for (i = 0; i < empty_dirs->nelts; i++)
+  for (hi = apr_hash_first(scratch_pool, empty_dirs);
+       hi;
+       hi = apr_hash_next(hi))
     {
       const char *empty_dir;
 
@@ -2582,7 +2582,12 @@ delete_empty_dirs(apr_array_header_t *ta
       if (ctx->cancel_func)
         SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-      empty_dir = APR_ARRAY_IDX(empty_dirs, i, const char *);
+      empty_dir = svn__apr_hash_index_key(hi);
+      if (! dry_run)
+        SVN_ERR(svn_wc_delete4(ctx->wc_ctx, empty_dir, FALSE, FALSE,
+                               ctx->cancel_func, ctx->cancel_baton,
+                               NULL, NULL, /* no duplicate notification */
+                               iterpool));
       if (ctx->notify_func2)
         {
           svn_wc_notify_t *notify;
@@ -2591,11 +2596,6 @@ delete_empty_dirs(apr_array_header_t *ta
                                         iterpool);
           (*ctx->notify_func2)(ctx->notify_baton2, notify, iterpool);
         }
-      if (! dry_run)
-        SVN_ERR(svn_wc_delete4(ctx->wc_ctx, empty_dir, FALSE, FALSE,
-                               ctx->cancel_func, ctx->cancel_baton,
-                               NULL, NULL, /* no duplicate notification */
-                               iterpool));
     }
   svn_pool_destroy(iterpool);
 

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_diff/parse-diff.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_diff/parse-diff.c Fri Jan 14 00:07:25 2011
@@ -595,9 +595,9 @@ parse_prop_name(const char **prop_name, 
  * Set IS_PROPERTY to TRUE if we have a property hunk. If the returned HUNK
  * is the first belonging to a certain property, then PROP_NAME and
  * PROP_OPERATION will be set too. If we have a text hunk, PROP_NAME will be
- * NULL. If IGNORE_WHITESPACE is TRUE, let lines without leading spaces be
- * recognized as context lines.  Allocate results in
- * RESULT_POOL.  Use SCRATCH_POOL for all other allocations. */
+ * NULL.  If IGNORE_WHITESPACE is TRUE, lines without leading spaces will be
+ * treated as context lines.  Allocate results in RESULT_POOL.
+ * Use SCRATCH_POOL for all other allocations. */
 static svn_error_t *
 parse_next_hunk(svn_diff_hunk_t **hunk,
                 svn_boolean_t *is_property,
@@ -685,10 +685,9 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
 
           c = line->data[0];
           /* Tolerate chopped leading spaces on empty lines. */
-          if (original_lines > 0 && modified_lines > 0
-              && ((c == ' ')
-              || (! eof && line->len == 0)
-              || (ignore_whitespace && c != del && c != add)))
+          if (original_lines > 0 && modified_lines > 0 &&
+              ((c == ' ') || (! eof && line->len == 0) ||
+               (ignore_whitespace && c != del && c != add)))
             {
               hunk_seen = TRUE;
               original_lines--;
@@ -735,9 +734,6 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
         }
       else
         {
-          /* ### Add an is_hunk_header() helper function that returns
-           * ### the proper atat string? Then we could collapse the
-           * ### following two if-clauses. */
           if (starts_with(line->data, text_atat))
             {
               /* Looks like we have a hunk header, try to rip it apart. */
@@ -1211,6 +1207,79 @@ svn_diff_open_patch_file(svn_patch_file_
   return SVN_NO_ERROR;
 }
 
+/* Parse hunks from APR_FILE and store them in PATCH->HUNKS.
+ * Parsing stops if no valid next hunk can be found.
+ * If IGNORE_WHITESPACE is TRUE, lines without
+ * leading spaces will be treated as context lines.
+ * Allocate results in RESULT_POOL.
+ * Use SCRATCH_POOL for temporary allocations. */
+static svn_error_t *
+parse_hunks(svn_patch_t *patch, apr_file_t *apr_file,
+            svn_boolean_t ignore_whitespace,
+            apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+  svn_diff_hunk_t *hunk;
+  svn_boolean_t is_property;
+  const char *last_prop_name;
+  const char *prop_name;
+  svn_diff_operation_kind_t prop_operation;
+  apr_pool_t *iterpool;
+
+  last_prop_name = NULL;
+
+  patch->hunks = apr_array_make(result_pool, 10, sizeof(svn_diff_hunk_t *));
+  patch->prop_patches = apr_hash_make(result_pool);
+  iterpool = svn_pool_create(scratch_pool);
+  do
+    {
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(parse_next_hunk(&hunk, &is_property, &prop_name, &prop_operation,
+                              patch, apr_file, ignore_whitespace, result_pool,
+                              iterpool));
+
+      if (hunk && is_property)
+        {
+          if (! prop_name)
+            prop_name = last_prop_name;
+          else
+            last_prop_name = prop_name;
+          SVN_ERR(add_property_hunk(patch, prop_name, hunk, prop_operation,
+                                    result_pool));
+        }
+      else if (hunk)
+        {
+          APR_ARRAY_PUSH(patch->hunks, svn_diff_hunk_t *) = hunk;
+          last_prop_name = NULL;
+        }
+
+    }
+  while (hunk);
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
+/* State machine for the diff header parser.
+ * Expected Input   Required state          Function to call */
+static struct transition transitions[] =
+{
+  {"--- ",          state_start,            diff_minus},
+  {"+++ ",          state_minus_seen,       diff_plus},
+  {"diff --git",    state_start,            git_start},
+  {"--- a/",        state_git_diff_seen,    git_minus},
+  {"--- a/",        state_git_tree_seen,    git_minus},
+  {"--- /dev/null", state_git_tree_seen,    git_minus},
+  {"+++ b/",        state_git_minus_seen,   git_plus},
+  {"+++ /dev/null", state_git_minus_seen,   git_plus},
+  {"rename from ",  state_git_diff_seen,    git_move_from},
+  {"rename to ",    state_move_from_seen,   git_move_to},
+  {"copy from ",    state_git_diff_seen,    git_copy_from},
+  {"copy to ",      state_copy_from_seen,   git_copy_to},
+  {"new file ",     state_git_diff_seen,    git_new_file},
+  {"deleted file ", state_git_diff_seen,    git_deleted_file},
+};
+
 svn_error_t *
 svn_diff_parse_next_patch(svn_patch_t **patch,
                           svn_patch_file_t *patch_file,
@@ -1225,26 +1294,6 @@ svn_diff_parse_next_patch(svn_patch_t **
   apr_pool_t *iterpool;
   enum parse_state state = state_start;
 
-  /* Our table consisting of:
-   * Expected Input     Required state          Function to call */
-  struct transition transitions[] =
-    {
-      {"--- ",          state_start,            diff_minus},
-      {"+++ ",          state_minus_seen,       diff_plus},
-      {"diff --git",    state_start,            git_start},
-      {"--- a/",        state_git_diff_seen,    git_minus},
-      {"--- a/",        state_git_tree_seen,    git_minus},
-      {"--- /dev/null", state_git_tree_seen,    git_minus},
-      {"+++ b/",        state_git_minus_seen,   git_plus},
-      {"+++ /dev/null", state_git_minus_seen,   git_plus},
-      {"rename from ",  state_git_diff_seen,    git_move_from},
-      {"rename to ",    state_move_from_seen,   git_move_to},
-      {"copy from ",    state_git_diff_seen,    git_copy_from},
-      {"copy to ",      state_copy_from_seen,   git_copy_to},
-      {"new file ",     state_git_diff_seen,    git_new_file},
-      {"deleted file ", state_git_diff_seen,    git_deleted_file},
-    };
-
   if (apr_file_eof(patch_file->apr_file) == APR_EOF)
     {
       /* No more patches here. */
@@ -1291,14 +1340,12 @@ svn_diff_parse_next_patch(svn_patch_t **
             }
         }
 
-      if (state == state_unidiff_found
-          || state == state_git_header_found)
+      if (state == state_unidiff_found || state == state_git_header_found)
         {
           /* We have a valid diff header, yay! */
           break;
         }
-      else if (state == state_git_tree_seen
-               && line_after_tree_header_read)
+      else if (state == state_git_tree_seen && line_after_tree_header_read)
         {
           /* We have a valid diff header for a patch with only tree changes.
            * Rewind to the start of the line just read, so subsequent calls
@@ -1309,7 +1356,7 @@ svn_diff_parse_next_patch(svn_patch_t **
           break;
         }
       else if (state == state_git_tree_seen)
-          line_after_tree_header_read = TRUE;
+        line_after_tree_header_read = TRUE;
 
     }
   while (! eof);
@@ -1329,46 +1376,8 @@ svn_diff_parse_next_patch(svn_patch_t **
       *patch = NULL;
     }
   else
-    {
-      svn_diff_hunk_t *hunk;
-      svn_boolean_t is_property;
-      const char *last_prop_name;
-      const char *prop_name;
-      svn_diff_operation_kind_t prop_operation;
-
-      last_prop_name = NULL;
-
-      /* Parse hunks. */
-      (*patch)->hunks = apr_array_make(result_pool, 10,
-                                       sizeof(svn_diff_hunk_t *));
-      (*patch)->prop_patches = apr_hash_make(result_pool);
-      do
-        {
-          svn_pool_clear(iterpool);
-
-          SVN_ERR(parse_next_hunk(&hunk, &is_property, &prop_name,
-                                  &prop_operation, *patch,
-                                  patch_file->apr_file, ignore_whitespace,
-                                  result_pool, iterpool));
-
-          if (hunk && is_property)
-            {
-              if (! prop_name)
-                prop_name = last_prop_name;
-              else
-                last_prop_name = prop_name;
-              SVN_ERR(add_property_hunk(*patch, prop_name, hunk, prop_operation,
-                                        result_pool));
-            }
-          else if (hunk)
-            {
-              APR_ARRAY_PUSH((*patch)->hunks, svn_diff_hunk_t *) = hunk;
-              last_prop_name = NULL;
-            }
-
-        }
-      while (hunk);
-    }
+    SVN_ERR(parse_hunks(*patch, patch_file->apr_file, ignore_whitespace,
+                        result_pool, iterpool));
 
   svn_pool_destroy(iterpool);
 

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_fs_base/bdb/env.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_fs_base/bdb/env.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_fs_base/bdb/env.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_fs_base/bdb/env.c Fri Jan 14 00:07:25 2011
@@ -373,7 +373,7 @@ clear_cache(void *data)
 }
 #endif /* APR_HAS_THREADS */
 
-static volatile svn_atomic_t bdb_cache_state;
+static volatile svn_atomic_t bdb_cache_state = 0;
 
 static svn_error_t *
 bdb_init_cb(void *baton, apr_pool_t *pool)

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra/ra_loader.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra/ra_loader.c Fri Jan 14 00:07:25 2011
@@ -301,6 +301,16 @@ svn_error_t *svn_ra_open4(svn_ra_session
   /* Initialize the return variable. */
   *session_p = NULL;
 
+  apr_err = apr_uri_parse(sesspool, repos_URL, &repos_URI);
+  /* ### Should apr_uri_parse leave hostname NULL?  It doesn't
+   * for "file:///" URLs, only for bogus URLs like "bogus".
+   * If this is the right behavior for apr_uri_parse, maybe we
+   * should have a svn_uri_parse wrapper. */
+  if (apr_err != APR_SUCCESS || repos_URI.hostname == NULL)
+    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                             _("Illegal repository URL '%s'"),
+                             repos_URL);
+
   if (callbacks->auth_baton)
     {
       /* The 'store-passwords' and 'store-auth-creds' parameters used to
@@ -363,15 +373,6 @@ svn_error_t *svn_ra_open4(svn_ra_session
 
           /* Find out where we're about to connect to, and
            * try to pick a server group based on the destination. */
-          apr_err = apr_uri_parse(sesspool, repos_URL, &repos_URI);
-          /* ### Should apr_uri_parse leave hostname NULL?  It doesn't
-           * for "file:///" URLs, only for bogus URLs like "bogus".
-           * If this is the right behavior for apr_uri_parse, maybe we
-           * should have a svn_uri_parse wrapper. */
-          if (apr_err != APR_SUCCESS || repos_URI.hostname == NULL)
-            return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
-                                     _("Illegal repository URL '%s'"),
-                                     repos_URL);
           server_group = svn_config_find_group(servers, repos_URI.hostname,
                                                SVN_CONFIG_SECTION_GROUPS,
                                                sesspool);
@@ -500,7 +501,19 @@ svn_error_t *svn_ra_open4(svn_ra_session
      what to do. */
   if (corrected_url_p && corrected_url)
     {
-      *corrected_url_p = apr_pstrdup(pool, corrected_url);
+      if (! svn_path_is_url(corrected_url))
+        {
+          /* RFC1945 and RFC2616 state that the Location header's
+             value (from whence this CORRECTED_URL ultimately comes),
+             if present, must be an absolute URI.  But some Apache
+             versions (those older than 2.2.11, it seems) transmit
+             only the path portion of the URI.  See issue #3775 for
+             details. */
+          apr_uri_t corrected_URI = repos_URI;
+          corrected_URI.path = (char *)corrected_url;
+          corrected_url = apr_uri_unparse(pool, &corrected_URI, 0);
+        }
+      *corrected_url_p = svn_uri_canonicalize(corrected_url, pool);
       svn_pool_destroy(sesspool);
       return SVN_NO_ERROR;
     }

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/commit.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/commit.c Fri Jan 14 00:07:25 2011
@@ -311,7 +311,8 @@ handle_checkout(serf_request_t *request,
       if (status)
         err = svn_error_compose_create(svn_error_wrap_apr(status, NULL), err);
 
-      ctx->resource_url = svn_uri_canonicalize(uri.path, ctx->pool);
+      ctx->resource_url = svn_ra_serf__uri_canonicalize(uri.path, pool,
+                                                        ctx->pool);
     }
 
   return err;
@@ -487,7 +488,8 @@ get_version_url(const char **checked_in_
 
       if (current_version)
         {
-          *checked_in_url = svn_uri_canonicalize(current_version->data, pool);
+          *checked_in_url =
+            svn_ra_serf__uri_canonicalize(current_version->data, pool, pool);
           return SVN_NO_ERROR;
         }
     }
@@ -542,7 +544,7 @@ get_version_url(const char **checked_in_
                                  _("Path '%s' not present"),
                                  session->repos_url.path);
 
-      root_checkout = svn_uri_canonicalize(root_checkout, pool);
+      root_checkout = svn_ra_serf__uri_canonicalize(root_checkout, pool, pool);
     }
 
   *checked_in_url = svn_path_url_add_component2(root_checkout, relpath, pool);

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/merge.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/merge.c Fri Jan 14 00:07:25 2011
@@ -364,7 +364,8 @@ end_merge(svn_ra_serf__xml_parser_t *par
       info->prop_val = apr_pstrmemdup(info->pool, info->prop_val,
                                       info->prop_val_len);
       if (strcmp(info->prop_name, "href") == 0)
-        info->prop_val = svn_uri_canonicalize(info->prop_val, info->pool);
+        info->prop_val = svn_ra_serf__uri_canonicalize(info->prop_val, 
+                                                       info->pool, info->pool);
 
       /* Set our property. */
       apr_hash_set(info->props, info->prop_name, APR_HASH_KEY_STRING,

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/options.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/options.c Fri Jan 14 00:07:25 2011
@@ -187,7 +187,9 @@ end_options(svn_ra_serf__xml_parser_t *p
     {
       options_ctx->collect_cdata = FALSE;
       options_ctx->activity_collection =
-                 svn_uri_canonicalize(options_ctx->attr_val, options_ctx->pool);
+        svn_ra_serf__uri_canonicalize(options_ctx->attr_val,
+                                      options_ctx->pool,
+                                      options_ctx->pool);
       pop_state(options_ctx);
     }
 
@@ -336,10 +338,12 @@ capabilities_headers_iterator_callback(v
           orc->session->repos_root = orc->session->repos_url;
           orc->session->repos_root.path = apr_pstrdup(orc->session->pool, val);
           orc->session->repos_root_str =
-            svn_uri_canonicalize(apr_uri_unparse(orc->session->pool,
-                                                 &orc->session->repos_root,
-                                                 0),
-                                  orc->session->pool);
+            svn_ra_serf__uri_canonicalize(
+                apr_uri_unparse(orc->session->pool,
+                                &orc->session->repos_root,
+                                0),
+                orc->session->pool,
+                orc->session->pool);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_ME_RESOURCE_HEADER) == 0)
         {

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/property.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/property.c Fri Jan 14 00:07:25 2011
@@ -25,6 +25,7 @@
 
 #include <serf.h>
 
+#include "svn_path.h"
 #include "svn_base64.h"
 #include "svn_xml.h"
 #include "svn_props.h"
@@ -342,7 +343,8 @@ end_propfind(svn_ra_serf__xml_parser_t *
         {
           if (strcmp(ctx->depth, "1") == 0)
             {
-              ctx->current_path = svn_uri_canonicalize(info->val, ctx->pool);
+              ctx->current_path =
+                svn_ra_serf__uri_canonicalize(info->val, ctx->pool, ctx->pool);
             }
           else
             {
@@ -1032,7 +1034,8 @@ svn_ra_serf__get_baseline_info(const cha
                                         "the requested checked-in value"));
             }
 
-          baseline_url = svn_uri_canonicalize(baseline_url, pool);
+          baseline_url = svn_ra_serf__uri_canonicalize(baseline_url,
+                                                       pool, pool);
 
           SVN_ERR(svn_ra_serf__retrieve_props(props, session, conn,
                                               baseline_url, revision, "0",
@@ -1049,7 +1052,8 @@ svn_ra_serf__get_baseline_info(const cha
                                     "requested baseline-collection value"));
         }
 
-      basecoll_url = svn_uri_canonicalize(basecoll_url, pool);
+      basecoll_url = svn_ra_serf__uri_canonicalize(basecoll_url,
+                                                   pool, pool);
 
       if (latest_revnum)
         {

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/ra_serf.h?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/ra_serf.h Fri Jan 14 00:07:25 2011
@@ -794,6 +794,17 @@ const char *
 svn_ra_serf__response_get_location(serf_bucket_t *response,
                                    apr_pool_t *pool);
 
+/* Canonicalize URI, in the general sense.  URI might be a full,
+ * absolute, schema-ful URL.  It might be just the path portion of a
+ * URL.  Or it might be a relative path.  Whatever the case, it is a
+ * URI-encoded identifier of *some sort*, as will be the returned form
+ * thereof.
+ */
+const char *
+svn_ra_serf__uri_canonicalize(const char *uri,
+                              apr_pool_t *scratch_pool,
+                              apr_pool_t *result_pool);
+
 /** XML helper functions. **/
 
 /*

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/serf.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/serf.c Fri Jan 14 00:07:25 2011
@@ -906,7 +906,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
        */
       dirent_walk.full_paths = apr_hash_make(pool);
       dirent_walk.base_paths = apr_hash_make(pool);
-      dirent_walk.orig_path = svn_uri_canonicalize(path, pool);
+      dirent_walk.orig_path = svn_ra_serf__uri_canonicalize(path, pool, pool);
 
       SVN_ERR(svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
                                           &dirent_walk, pool));

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/update.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/update.c Fri Jan 14 00:07:25 2011
@@ -1676,7 +1676,8 @@ start_report(svn_ra_serf__xml_parser_t *
     }
   else if (state == IGNORE_PROP_NAME)
     {
-      push_state(parser, ctx, PROP);
+      report_info_t *info = push_state(parser, ctx, PROP);
+      info->prop_encoding = svn_xml_get_attr_value("encoding", attrs);
     }
   else if (state == NEED_PROP_NAME)
     {
@@ -1686,6 +1687,7 @@ start_report(svn_ra_serf__xml_parser_t *
 
       info->prop_ns = name.namespace;
       info->prop_name = apr_pstrdup(parser->state->pool, name.name);
+      info->prop_encoding = svn_xml_get_attr_value("encoding", attrs);
       info->prop_val = NULL;
       info->prop_val_len = 0;
     }

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/util.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_serf/util.c Fri Jan 14 00:07:25 2011
@@ -914,7 +914,7 @@ svn_ra_serf__response_get_location(serf_
 
   headers = serf_bucket_response_get_headers(response);
   val = serf_bucket_headers_get(headers, "Location");
-  return val ? svn_uri_canonicalize(val, pool) : NULL;
+  return val ? svn_ra_serf__uri_canonicalize(val, pool, pool) : NULL;
 }
 
 /* Implements svn_ra_serf__response_handler_t */
@@ -1837,9 +1837,9 @@ svn_ra_serf__discover_vcc(const char **v
       session->repos_root = session->repos_url;
       session->repos_root.path = apr_pstrdup(session->pool, url_buf->data);
       session->repos_root_str =
-        svn_uri_canonicalize(apr_uri_unparse(session->pool,
-                                             &session->repos_root, 0),
-                             session->pool);
+        svn_ra_serf__uri_canonicalize(apr_uri_unparse(session->pool,
+                                                      &session->repos_root, 0),
+                                      pool, session->pool);
     }
 
   /* Store the repository UUID in the cache. */
@@ -1934,3 +1934,35 @@ svn_ra_serf__error_on_status(int status_
 
   return SVN_NO_ERROR;
 }
+
+
+static const char *
+relative_uri_normalize(const char *relpath,
+                       apr_pool_t *scratch_pool,
+                       apr_pool_t *result_pool)
+{
+  return svn_path_uri_encode(
+             svn_relpath_canonicalize(
+                 svn_path_uri_decode(relpath, scratch_pool),
+                 scratch_pool),
+             result_pool);
+}
+
+
+const char *
+svn_ra_serf__uri_canonicalize(const char *uri,
+                              apr_pool_t *scratch_pool,
+                              apr_pool_t *result_pool)
+{
+  if (svn_path_is_url(uri))
+    return svn_uri_canonicalize(uri, result_pool);
+
+  if (uri[0] == '/')
+    return apr_pstrcat(result_pool, "/", 
+                       relative_uri_normalize(uri + 1,
+                                              scratch_pool,
+                                              scratch_pool),
+                       NULL);
+  
+  return relative_uri_normalize(uri, scratch_pool, result_pool);
+}

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_ra_svn/cyrus_auth.c Fri Jan 14 00:07:25 2011
@@ -54,8 +54,9 @@
  *       in atexit processing, at which point we are already running in
  *       single threaded mode.
  */
-volatile svn_atomic_t svn_ra_svn__sasl_status;
+volatile svn_atomic_t svn_ra_svn__sasl_status = 0;
 
+/* Initialized by svn_ra_svn__sasl_common_init(). */
 static volatile svn_atomic_t sasl_ctx_count;
 
 static apr_pool_t *sasl_pool = NULL;

Propchange: subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/adler32.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 14 00:07:25 2011
@@ -1 +1 @@
-/subversion/trunk/subversion/libsvn_subr/adler32.c:1054278-1057038
+/subversion/trunk/subversion/libsvn_subr/adler32.c:1054278-1058787

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/dirent_uri.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/dirent_uri.c Fri Jan 14 00:07:25 2011
@@ -1819,6 +1819,7 @@ svn_uri_is_canonical(const char *uri, ap
    *  - no '//'
    *  - lowercase URL scheme
    *  - lowercase URL hostname
+   *  - uppercase hex-encoded pair digits ("%AB", not "%ab")
    */
 
   if (*uri == '\0')

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/io.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/io.c Fri Jan 14 00:07:25 2011
@@ -637,7 +637,7 @@ svn_io_copy_link(const char *src,
 }
 
 /* Temporary directory name cache for svn_io_temp_dir() */
-static volatile svn_atomic_t temp_dir_init_state;
+static volatile svn_atomic_t temp_dir_init_state = 0;
 static const char *temp_dir;
 
 /* Helper function to initialize temp dir. Passed to svn_atomic__init_once */

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/sqlite.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_subr/sqlite.c Fri Jan 14 00:07:25 2011
@@ -694,7 +694,7 @@ check_format(svn_sqlite__db_t *db,
                            current_schema);
 }
 
-static volatile svn_atomic_t sqlite_init_state;
+static volatile svn_atomic_t sqlite_init_state = 0;
 
 /* If possible, verify that SQLite was compiled in a thread-safe
    manner. */
@@ -932,7 +932,11 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
 
                  ### Maybe switch to NORMAL(1) when we use larger transaction
                      scopes */
-              "PRAGMA synchronous=OFF;"));
+              "PRAGMA synchronous=OFF;"
+              /* Enable recursive triggers so that a user trigger will fire
+               * in the deletion phase of an INSERT OR REPLACE statement.
+               * Requires SQLite >= 3.6.18 */
+              "PRAGMA recursive_triggers=ON;"));
 
 #if SQLITE_VERSION_AT_LEAST(3,6,19) && defined(SVN_DEBUG)
   /* When running in debug mode, enable the checking of foreign key

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/upgrade.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/upgrade.c Fri Jan 14 00:07:25 2011
@@ -942,8 +942,8 @@ migrate_props(const char *dir_abspath,
 static char *
 remove_suffix(const char *str, const char *suffix, apr_pool_t *result_pool)
 {
-  int str_len = strlen(str);
-  int suffix_len = strlen(suffix);
+  size_t str_len = strlen(str);
+  size_t suffix_len = strlen(suffix);
 
   if (str_len > suffix_len
       && strcmp(str + str_len - suffix_len, suffix) == 0)
@@ -1129,6 +1129,14 @@ bump_to_23(void *baton, svn_sqlite__db_t
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+bump_to_24(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_24));
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_CREATE_NODES_TRIGGERS));
+  return SVN_NO_ERROR;
+}
+
 
 struct upgrade_data_t {
   svn_sqlite__db_t *sdb;
@@ -1390,6 +1398,12 @@ svn_wc__upgrade_sdb(int *result_format,
         *result_format = 23;
         /* FALLTHROUGH  */
 
+      case 23:
+        SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_24, &bb,
+                                             scratch_pool));
+        *result_format = 24;
+        /* FALLTHROUGH  */
+
       /* ### future bumps go here.  */
 #if 0
       case XXX-1:

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-metadata.sql?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-metadata.sql Fri Jan 14 00:07:25 2011
@@ -95,8 +95,9 @@ CREATE TABLE PRISTINE (
      Used to verify the pristine file is "proper". */
   size  INTEGER NOT NULL,
 
-  /* ### this will probably go away, in favor of counting references
-     ### that exist in NODES. Not yet used; always set to 1. */
+  /* The number of rows in the NODES table that have a 'checksum' column
+     value that refers to this row.  (References in other places, such as
+     in the ACTUAL_NODE table, are not counted.) */
   refcount  INTEGER NOT NULL,
 
   /* Alternative MD5 checksum used for communicating with older
@@ -480,6 +481,35 @@ CREATE TABLE NODES (
 CREATE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, op_depth);
 
 
+-- STMT_CREATE_NODES_TRIGGERS
+
+CREATE TRIGGER nodes_insert_trigger
+AFTER INSERT ON nodes
+/* WHEN NEW.checksum IS NOT NULL */
+BEGIN
+  UPDATE pristine SET refcount = refcount + 1
+  WHERE checksum = NEW.checksum;
+END;
+
+CREATE TRIGGER nodes_delete_trigger
+AFTER DELETE ON nodes
+/* WHEN OLD.checksum IS NOT NULL */
+BEGIN
+  UPDATE pristine SET refcount = refcount - 1
+  WHERE checksum = OLD.checksum;
+END;
+
+CREATE TRIGGER nodes_update_checksum_trigger
+AFTER UPDATE OF checksum ON nodes
+/* WHEN NEW.checksum IS NOT NULL OR OLD.checksum IS NOT NULL */
+BEGIN
+  UPDATE pristine SET refcount = refcount + 1
+  WHERE checksum = NEW.checksum;
+  UPDATE pristine SET refcount = refcount - 1
+  WHERE checksum = OLD.checksum;
+END;
+
+
 
 /* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */
 
@@ -552,6 +582,19 @@ PRAGMA user_version = 23;
 
 /* ------------------------------------------------------------------------- */
 
+/* Format 24 involves no schema changes; it starts using the pristine
+   table's refcount column correctly. */
+
+-- STMT_UPGRADE_TO_24
+UPDATE pristine SET refcount =
+  (SELECT COUNT(*) FROM nodes
+   WHERE checksum = pristine.checksum /*OR checksum = pristine.md5_checksum*/);
+
+PRAGMA user_version = 24;
+
+
+/* ------------------------------------------------------------------------- */
+
 /* Format YYY introduces new handling for conflict information.  */
 -- format: YYY
 

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc-queries.sql Fri Jan 14 00:07:25 2011
@@ -411,7 +411,7 @@ DELETE FROM work_queue WHERE id = ?1;
 
 -- STMT_INSERT_PRISTINE
 INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount)
-VALUES (?1, ?2, ?3, 1);
+VALUES (?1, ?2, ?3, 0);
 
 -- STMT_SELECT_PRISTINE_MD5_CHECKSUM
 SELECT md5_checksum
@@ -423,21 +423,14 @@ SELECT checksum
 FROM pristine
 WHERE md5_checksum = ?1
 
--- STMT_SELECT_ANY_PRISTINE_REFERENCE
-SELECT 1 FROM nodes
-  WHERE checksum = ?1 OR checksum = ?2
-LIMIT 1
-
 -- STMT_SELECT_UNREFERENCED_PRISTINES
 SELECT checksum
 FROM pristine
-EXCEPT
-SELECT checksum FROM nodes
-  WHERE checksum IS NOT NULL
+WHERE refcount = 0
 
--- STMT_DELETE_PRISTINE
+-- STMT_DELETE_PRISTINE_IF_UNREFERENCED
 DELETE FROM pristine
-WHERE checksum = ?1
+WHERE checksum = ?1 AND refcount = 0
 
 -- STMT_SELECT_ACTUAL_CONFLICT_VICTIMS
 SELECT local_relpath

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc.h Fri Jan 14 00:07:25 2011
@@ -133,12 +133,15 @@ extern "C" {
  * The change from 22 to 23 introduced multi-layer op_depth processing for
  * NODES.
  *
+ * The change from 23 to 24 started using the 'refcount' column of the
+ * 'pristine' table correctly, instead of always setting it to '1'.
+ *
  * == 1.7.x shipped with format ???
  *
  * Please document any further format changes here.
  */
 
-#define SVN_WC__VERSION 23
+#define SVN_WC__VERSION 24
 
 
 /* Formats <= this have no concept of "revert text-base/props".  */

Modified: subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/libsvn_wc/wc_db.c Fri Jan 14 00:07:25 2011
@@ -1273,9 +1273,8 @@ create_db(svn_sqlite__db_t **sdb,
 
   /* Create the database's schema.  */
   SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_SCHEMA));
-
-  /* Create the NODES table for the experimental schema */
   SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_NODES));
+  SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_NODES_TRIGGERS));
 
   /* Insert the repository. */
   SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid, *sdb,
@@ -2490,28 +2489,33 @@ svn_wc__db_pristine_get_sha1(const svn_c
 }
 
 
-/* Delete the pristine text referenced by SHA1_CHECKSUM from the pristine
- * store of WCROOT.  Delete both the database row and the file on disk. */
+/* If the pristine text referenced by SHA1_CHECKSUM has a reference count
+ * of zero, delete it from the pristine store of WCROOT.  Delete both the
+ * database row and the file on disk. */
 static svn_error_t *
-pristine_remove(svn_wc__db_wcroot_t *wcroot,
+pristine_remove_if_unreferenced(svn_wc__db_wcroot_t *wcroot,
                 const svn_checksum_t *sha1_checksum,
                 apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
   const char *pristine_abspath;
+  int affected_rows;
 
-  /* Remove the DB row. */
+  /* Remove the DB row, if refcount is 0. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_DELETE_PRISTINE));
+                                    STMT_DELETE_PRISTINE_IF_UNREFERENCED));
   SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__update(NULL, stmt));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-  /* Remove the file */
-  SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
-                             sha1_checksum, TRUE /* create_subdir */,
-                             scratch_pool, scratch_pool));
-  SVN_ERR(svn_io_remove_file2(pristine_abspath, TRUE /* ignore_enoent */,
-                              scratch_pool));
+  if (affected_rows > 0)
+    {
+      /* Remove the file. */
+      SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
+                                 sha1_checksum, TRUE /* create_subdir */,
+                                 scratch_pool, scratch_pool));
+      SVN_ERR(svn_io_remove_file2(pristine_abspath, TRUE /* ignore_enoent */,
+                                  scratch_pool));
+    }
 
   return SVN_NO_ERROR;
 }
@@ -2524,7 +2528,6 @@ svn_wc__db_pristine_remove(svn_wc__db_t 
 {
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
-  svn_boolean_t is_referenced;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
   SVN_ERR_ASSERT(sha1_checksum != NULL);
@@ -2556,30 +2559,9 @@ svn_wc__db_pristine_remove(svn_wc__db_t 
       return SVN_NO_ERROR;
   }
 
-  /* Find whether the SHA-1 (or the MD-5) is referenced; set IS_REFERENCED. */
-  {
-    const svn_checksum_t *md5_checksum;
-    svn_sqlite__stmt_t *stmt;
-
-    /* ### Transitional: look for references to its MD-5 as well. */
-    SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db, wri_abspath,
-                                        sha1_checksum, scratch_pool,
-                                        scratch_pool));
-
-    SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                                      STMT_SELECT_ANY_PRISTINE_REFERENCE));
-    SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
-    SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
-    SVN_ERR(svn_sqlite__step(&is_referenced, stmt));
-
-    SVN_ERR(svn_sqlite__reset(stmt));
-  }
-
   /* If not referenced, remove the PRISTINE table row and the file. */
-  if (! is_referenced)
-    {
-      SVN_ERR(pristine_remove(pdh->wcroot, sha1_checksum, scratch_pool));
-    }
+  SVN_ERR(pristine_remove_if_unreferenced(pdh->wcroot, sha1_checksum,
+                                          scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2605,7 +2587,7 @@ pristine_cleanup_wcroot(svn_wc__db_wcroo
 
       SVN_ERR(svn_sqlite__column_checksum(&sha1_checksum, stmt, 0,
                                           scratch_pool));
-      SVN_ERR(pristine_remove(wcroot, sha1_checksum, scratch_pool));
+      SVN_ERR(pristine_remove_if_unreferenced(wcroot, sha1_checksum, scratch_pool));
     }
   SVN_ERR(svn_sqlite__reset(stmt));
 

Modified: subversion/branches/diff-optimizations-bytes/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/mod_authz_svn/mod_authz_svn.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/mod_authz_svn/mod_authz_svn.c Fri Jan 14 00:07:25 2011
@@ -42,6 +42,7 @@
 #include "svn_config.h"
 #include "svn_string.h"
 #include "svn_repos.h"
+#include "svn_dirent_uri.h"
 
 
 extern module AP_MODULE_DECLARE_DATA authz_svn_module;

Modified: subversion/branches/diff-optimizations-bytes/subversion/tests/libsvn_subr/dirent_uri-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/diff-optimizations-bytes/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1058809&r1=1058808&r2=1058809&view=diff
==============================================================================
--- subversion/branches/diff-optimizations-bytes/subversion/tests/libsvn_subr/dirent_uri-test.c (original)
+++ subversion/branches/diff-optimizations-bytes/subversion/tests/libsvn_subr/dirent_uri-test.c Fri Jan 14 00:07:25 2011
@@ -928,6 +928,10 @@ test_uri_canonicalize(apr_pool_t *pool)
     { "foo./.",               "foo." },
     { "foo././/.",            "foo." },
     { "/foo/bar",             "/foo/bar" },
+    /*** TODO:
+    { "/foo/b%ABble",         "/foo/b%ABble" },
+    { "/foo/b%abble",         "/foo/b%ABble" },
+    */
     { "foo/..",               "foo/.." },
     { "foo/../",              "foo/.." },
     { "foo/../.",             "foo/.." },
@@ -970,6 +974,8 @@ test_uri_canonicalize(apr_pool_t *pool)
     { "s://d/c#",              "s://d/c%23" }, /* Escape schema separator */
     { "s://d/c($) .+?",        "s://d/c($)%20.+%3F" }, /* Test special chars */
     { "file:///C%3a/temp",     "file:///C:/temp" },
+    { "http://server/cr%AB",   "http://server/cr%AB" },
+    { "http://server/cr%ab",   "http://server/cr%AB" },
 #ifdef SVN_USE_DOS_PATHS
     { "file:///c:/temp/repos", "file:///C:/temp/repos" },
     { "file:///c:/temp/REPOS", "file:///C:/temp/REPOS" },
@@ -1269,6 +1275,9 @@ test_uri_is_canonical(apr_pool_t *pool)
     { "file:///folder/c#",      FALSE }, /* # needs escaping */
     { "file:///fld/with space", FALSE }, /* # needs escaping */
     { "file:///fld/c%23",       TRUE }, /* Properly escaped C# */
+    { "file:///%DE%AD%BE%EF",  TRUE },
+    { "file:///%de%ad%be%ef",  FALSE },
+    { "file:///%DE%ad%BE%ef",  FALSE },
 #ifdef SVN_USE_DOS_PATHS
     { "file:///c:/temp/repos", FALSE },
     { "file:///c:/temp/REPOS", FALSE },