You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/10/09 19:59:22 UTC

svn commit: r1396140 [1/2] - in /subversion/branches/auto-props-sdc: ./ subversion/bindings/swig/python/libsvn_swig_py/ subversion/include/ subversion/libsvn_client/ subversion/libsvn_fs_fs/ subversion/libsvn_ra_serf/ subversion/libsvn_repos/ subversio...

Author: pburba
Date: Tue Oct  9 17:59:20 2012
New Revision: 1396140

URL: http://svn.apache.org/viewvc?rev=1396140&view=rev
Log:
On the auto-props-sdc branch: Sync with ^/subversion/trunk through r1396138.

Modified:
    subversion/branches/auto-props-sdc/   (props changed)
    subversion/branches/auto-props-sdc/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
    subversion/branches/auto-props-sdc/subversion/include/svn_ra.h
    subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c
    subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/caching.c
    subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs.h
    subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.c
    subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.h
    subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/tree.c
    subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/property.c
    subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/serf.c
    subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/util.c
    subversion/branches/auto-props-sdc/subversion/libsvn_repos/log.c
    subversion/branches/auto-props-sdc/subversion/libsvn_subr/io.c
    subversion/branches/auto-props-sdc/subversion/libsvn_subr/mergeinfo.c
    subversion/branches/auto-props-sdc/subversion/libsvn_wc/adm_ops.c
    subversion/branches/auto-props-sdc/subversion/libsvn_wc/conflicts.c
    subversion/branches/auto-props-sdc/subversion/libsvn_wc/entries.c
    subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc.h
    subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc_db.c
    subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc_db_wcroot.c
    subversion/branches/auto-props-sdc/subversion/mod_dav_svn/deadprops.c
    subversion/branches/auto-props-sdc/subversion/mod_dav_svn/liveprops.c
    subversion/branches/auto-props-sdc/subversion/svn/propget-cmd.c
    subversion/branches/auto-props-sdc/subversion/tests/cmdline/special_tests.py
    subversion/branches/auto-props-sdc/tools/client-side/svn-bench/notify.c
    subversion/branches/auto-props-sdc/tools/client-side/svn-bench/null-export-cmd.c
    subversion/branches/auto-props-sdc/tools/dist/release.py
    subversion/branches/auto-props-sdc/tools/server-side/svnauthz-validate.c
    subversion/branches/auto-props-sdc/tools/server-side/svnpubsub/irkerbridge.py

Propchange: subversion/branches/auto-props-sdc/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1395110-1396138

Modified: subversion/branches/auto-props-sdc/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/branches/auto-props-sdc/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Tue Oct  9 17:59:20 2012
@@ -4212,10 +4212,6 @@ svn_swig_py_config_enumerator2(const cha
                                       make_ob_pool, pool)) == NULL)
     {
       err = callback_exception_error();
-      /* If it's not a SubversionException, we still have to clear it, because
-         otherwise the SWIG wrapper will not check for it, and return a value with an
-         exception pending. */
-      PyErr_Clear();
     }
   else if (!PyBool_Check(result))
     {
@@ -4223,6 +4219,11 @@ svn_swig_py_config_enumerator2(const cha
       Py_DECREF(result);
     }
 
+  /* Any Python exception we might have pending must be cleared,
+     because the SWIG wrapper will not check for it, and return a value with
+     the exception still set. */
+  PyErr_Clear();
+
   if (err)
     {
       /* We can't return the error, but let's at least stop enumeration. */
@@ -4258,10 +4259,6 @@ svn_swig_py_config_section_enumerator2(c
                                       make_ob_pool, pool)) == NULL)
     {
       err = callback_exception_error();
-      /* If it's not a SubversionException, we still have to clear it, because
-         otherwise the SWIG wrapper will not check for it, and return a value with an
-         exception pending. */
-      PyErr_Clear();
     }
   else if (!PyBool_Check(result))
     {
@@ -4269,6 +4266,11 @@ svn_swig_py_config_section_enumerator2(c
       Py_DECREF(result);
     }
 
+  /* Any Python exception we might have pending must be cleared,
+     because the SWIG wrapper will not check for it, and return a value with
+     the exception still set. */
+  PyErr_Clear();
+
   if (err)
     {
       /* We can't return the error, but let's at least stop enumeration. */

Modified: subversion/branches/auto-props-sdc/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/include/svn_ra.h?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/include/svn_ra.h (original)
+++ subversion/branches/auto-props-sdc/subversion/include/svn_ra.h Tue Oct  9 17:59:20 2012
@@ -971,42 +971,11 @@ svn_ra_get_commit_editor(svn_ra_session_
  * etc.)  The keys are <tt>const char *</tt>, values are
  * <tt>@c svn_string_t *</tt>.
  *
- * If the server advertises the #SVN_RA_CAPABILITY_INHERITED_PROPS capability
- * and if @a inherited_props is not @c NULL, then set @a *inherited_props to
- * a depth-first ordered array of #svn_prop_inherited_item_t * structures
- * representing the properties inherited by @a path at @a revision (or the
- * 'head' revision if @a revision is @c SVN_INVALID_REVNUM.  If
- * @a inherited_props is not @c NULL and no inheritable properties are found,
- * then set @a *inherited_props to an empty array.  If the server does not
- * advertise the #SVN_RA_CAPABILITY_INHERITED_PROPS capability and
- * @a inherited_props is not @c NULL, then set @a *inherited_props to
- * @c NULL.
- *
  * The stream handlers for @a stream may not perform any RA
  * operations using @a session.
  *
- * @since New in 1.8.
- */
-svn_error_t *
-svn_ra_get_file2(svn_ra_session_t *session,
-                 const char *path,
-                 svn_revnum_t revision,
-                 svn_stream_t *stream,
-                 svn_revnum_t *fetched_rev,
-                 apr_hash_t **props,
-                 apr_array_header_t **inherited_props,
-                 apr_pool_t *result_pool,
-                 apr_pool_t *scratch_pool);
-
-/**
- * Similar to @c svn_ra_get_file2, but does not support the retrieval of
- * inherited properties.
- *
  * @since New in 1.2.
- *
- * @deprecated Provided for compatibility with the 1.7 API.
  */
-SVN_DEPRECATED
 svn_error_t *
 svn_ra_get_file(svn_ra_session_t *session,
                 const char *path,
@@ -1041,40 +1010,8 @@ svn_ra_get_file(svn_ra_session_t *sessio
  * etc.)  The keys are <tt>const char *</tt>, values are
  * <tt>@c svn_string_t *</tt>.
  *
- * If the server advertises the #SVN_RA_CAPABILITY_INHERITED_PROPS capability
- * and if @a inherited_props is not @c NULL, then set @a *inherited_props to
- * a depth-first ordered array of #svn_prop_inherited_item_t * structures
- * representing the properties inherited by @a path at @a revision (or the
- * 'head' revision if @a revision is @c SVN_INVALID_REVNUM.  If
- * @a inherited_props is not @c NULL and no inheritable properties are found,
- * then set @a *inherited_props to an empty array.  If the server does not
- * advertise the #SVN_RA_CAPABILITY_INHERITED_PROPS capability and
- * @a inherited_props is not @c NULL, then set @a *inherited_props to
- * @c NULL.
- *
- * @since New in 1.8.
- */
-svn_error_t *
-svn_ra_get_dir3(svn_ra_session_t *session,
-                apr_hash_t **dirents,
-                svn_revnum_t *fetched_rev,
-                apr_hash_t **props,
-                apr_array_header_t **inherited_props,
-                const char *path,
-                svn_revnum_t revision,
-                apr_uint32_t dirent_fields,
-                apr_pool_t *result_pool,
-                apr_pool_t *scratch_pool);
-
-/**
- * Similar to @c svn_ra_get_dir3, but does not support the retrieval of
- * inherited properties.
- *
  * @since New in 1.4.
- *
- * @deprecated Provided for compatibility with the 1.8 API.
  */
-SVN_DEPRECATED
 svn_error_t *
 svn_ra_get_dir2(svn_ra_session_t *session,
                 apr_hash_t **dirents,

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_client/add.c Tue Oct  9 17:59:20 2012
@@ -934,7 +934,7 @@ svn_client_add4(const char *path,
   if (err)
     {
       if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
-          && err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY)
+          && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
         {
           return svn_error_trace(err);
         }

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/caching.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/caching.c Tue Oct  9 17:59:20 2012
@@ -371,8 +371,33 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                        no_handler,
                        fs->pool));
 
-  /* initialize fulltext cache as configured */
-  ffd->fulltext_cache = NULL;
+  /* initialize node revision cache, if caching has been enabled */
+  SVN_ERR(create_cache(&(ffd->node_revision_cache),
+                       NULL,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       svn_fs_fs__serialize_node_revision,
+                       svn_fs_fs__deserialize_node_revision,
+                       sizeof(pair_cache_key_t),
+                       apr_pstrcat(pool, prefix, "NODEREVS", (char *)NULL),
+                       fs,
+                       no_handler,
+                       fs->pool));
+
+  /* initialize node change list cache, if caching has been enabled */
+  SVN_ERR(create_cache(&(ffd->changes_cache),
+                       NULL,
+                       membuffer,
+                       0, 0, /* Do not use inprocess cache */
+                       svn_fs_fs__serialize_changes,
+                       svn_fs_fs__deserialize_changes,
+                       sizeof(svn_revnum_t),
+                       apr_pstrcat(pool, prefix, "CHANGES", (char *)NULL),
+                       fs,
+                       no_handler,
+                       fs->pool));
+
+  /* if enabled, cache fulltext and other derived information */
   if (cache_fulltexts)
     {
       SVN_ERR(create_cache(&(ffd->fulltext_cache),
@@ -386,11 +411,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            fs,
                            no_handler,
                            fs->pool));
-    }
-
-  /* initialize node properties cache, if that has been enabled */
-  if (cache_fulltexts)
-    {
+      
       SVN_ERR(create_cache(&(ffd->properties_cache),
                            NULL,
                            membuffer,
@@ -403,10 +424,39 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            fs,
                            no_handler,
                            fs->pool));
+      
+      SVN_ERR(create_cache(&(ffd->mergeinfo_cache),
+                           NULL,
+                           membuffer,
+                           0, 0, /* Do not use inprocess cache */
+                           svn_fs_fs__serialize_mergeinfo,
+                           svn_fs_fs__deserialize_mergeinfo,
+                           APR_HASH_KEY_STRING,
+                           apr_pstrcat(pool, prefix, "MERGEINFO",
+                                       (char *)NULL),
+                           fs,
+                           no_handler,
+                           fs->pool));
+      
+      SVN_ERR(create_cache(&(ffd->mergeinfo_existence_cache),
+                           NULL,
+                           membuffer,
+                           0, 0, /* Do not use inprocess cache */
+                           /* Values are svn_stringbuf_t */
+                           NULL, NULL,
+                           APR_HASH_KEY_STRING,
+                           apr_pstrcat(pool, prefix, "HAS_MERGEINFO",
+                                       (char *)NULL),
+                           fs,
+                           no_handler,
+                           fs->pool));
     }
   else
     {
+      ffd->fulltext_cache = NULL;
       ffd->properties_cache = NULL;
+      ffd->mergeinfo_cache = NULL;
+      ffd->mergeinfo_existence_cache = NULL;
     }
 
   /* initialize revprop cache, if full-text caching has been enabled */
@@ -430,7 +480,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
       ffd->revprop_cache = NULL;
     }
 
-  /* initialize txdelta window cache, if that has been enabled */
+  /* if enabled, cache text deltas and their combinations */
   if (cache_txdeltas)
     {
       SVN_ERR(create_cache(&(ffd->txdelta_window_cache),
@@ -445,15 +495,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                            fs,
                            no_handler,
                            fs->pool));
-    }
-  else
-    {
-      ffd->txdelta_window_cache = NULL;
-    }
 
-  /* initialize txdelta window cache, if that has been enabled */
-  if (cache_txdeltas)
-    {
       SVN_ERR(create_cache(&(ffd->combined_window_cache),
                            NULL,
                            membuffer,
@@ -469,35 +511,10 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
     }
   else
     {
+      ffd->txdelta_window_cache = NULL;
       ffd->combined_window_cache = NULL;
     }
 
-  /* initialize node revision cache, if caching has been enabled */
-  SVN_ERR(create_cache(&(ffd->node_revision_cache),
-                       NULL,
-                       membuffer,
-                       0, 0, /* Do not use inprocess cache */
-                       svn_fs_fs__serialize_node_revision,
-                       svn_fs_fs__deserialize_node_revision,
-                       APR_HASH_KEY_STRING,
-                       apr_pstrcat(pool, prefix, "NODEREVS", (char *)NULL),
-                       fs,
-                       no_handler, 
-                       fs->pool));
-
-  /* initialize node change list cache, if caching has been enabled */
-  SVN_ERR(create_cache(&(ffd->changes_cache),
-                       NULL,
-                       membuffer,
-                       0, 0, /* Do not use inprocess cache */
-                       svn_fs_fs__serialize_changes,
-                       svn_fs_fs__deserialize_changes,
-                       sizeof(svn_revnum_t),
-                       apr_pstrcat(pool, prefix, "CHANGES", (char *)NULL),
-                       fs,
-                       no_handler,
-                       fs->pool));
-
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs.h?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs.h Tue Oct  9 17:59:20 2012
@@ -306,6 +306,15 @@ typedef struct fs_fs_data_t
      is the revision */
   svn_cache__t *changes_cache;
 
+  /* Cache for svn_mergeinfo_t objects; the key is a combination of
+     revision, inheritance flags and path. */
+  svn_cache__t *mergeinfo_cache;
+
+  /* Cache for presence of svn_mergeinfo_t on a noderev; the key is a
+     combination of revision, inheritance flags and path; value is "1"
+     if the node has mergeinfo, "0" if it doesn't. */
+  svn_cache__t *mergeinfo_existence_cache;
+
   /* If set, there are or have been more than one concurrent transaction */
   svn_boolean_t concurrent_transactions;
 

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs_fs.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/fs_fs.c Tue Oct  9 17:59:20 2012
@@ -2178,16 +2178,6 @@ err_dangling_id(svn_fs_t *fs, const svn_
      id_str->data, fs->path);
 }
 
-/* Return a string that uniquely identifies the noderev with the
- * given ID, for use as a cache key.
- */
-static const char *
-get_noderev_cache_key(const svn_fs_id_t *id, apr_pool_t *pool)
-{
-  const svn_string_t *id_unparsed = svn_fs_fs__id_unparse(id, pool);
-  return id_unparsed->data;
-}
-
 /* Look up the NODEREV_P for ID in FS' node revsion cache. If noderev
  * caching has been enabled and the data can be found, IS_CACHED will
  * be set to TRUE. The noderev will be allocated from POOL.
@@ -2203,13 +2193,19 @@ get_cached_node_revision_body(node_revis
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   if (! ffd->node_revision_cache || svn_fs_fs__id_txn_id(id))
-    *is_cached = FALSE;
+    {
+      *is_cached = FALSE;
+    }
   else
-    SVN_ERR(svn_cache__get((void **) noderev_p,
-                           is_cached,
-                           ffd->node_revision_cache,
-                           get_noderev_cache_key(id, pool),
-                           pool));
+    {
+      pair_cache_key_t key = { svn_fs_fs__id_rev(id),
+                               svn_fs_fs__id_offset(id) };
+      SVN_ERR(svn_cache__get((void **) noderev_p,
+                            is_cached,
+                            ffd->node_revision_cache,
+                            &key,
+                            pool));
+    }
 
   return SVN_NO_ERROR;
 }
@@ -2228,10 +2224,14 @@ set_cached_node_revision_body(node_revis
   fs_fs_data_t *ffd = fs->fsap_data;
 
   if (ffd->node_revision_cache && !svn_fs_fs__id_txn_id(id))
-    return svn_cache__set(ffd->node_revision_cache,
-                          get_noderev_cache_key(id, scratch_pool),
-                          noderev_p,
-                          scratch_pool);
+    {
+      pair_cache_key_t key = { svn_fs_fs__id_rev(id),
+                               svn_fs_fs__id_offset(id) };
+      return svn_cache__set(ffd->node_revision_cache,
+                            &key,
+                            noderev_p,
+                            scratch_pool);
+    }
 
   return SVN_NO_ERROR;
 }
@@ -5584,8 +5584,9 @@ fold_change(apr_hash_t *changes,
   apr_pool_t *pool = apr_hash_pool_get(changes);
   svn_fs_path_change2_t *old_change, *new_change;
   const char *path;
+  apr_size_t path_len = strlen(change->path);
 
-  if ((old_change = apr_hash_get(changes, change->path, APR_HASH_KEY_STRING)))
+  if ((old_change = apr_hash_get(changes, change->path, path_len)))
     {
       /* This path already exists in the hash, so we have to merge
          this change into the already existing one. */
@@ -5723,8 +5724,8 @@ fold_change(apr_hash_t *changes,
      re-use its value, but there is no way to fetch it. The API makes no
      guarantees that this (new) key will not be retained. Thus, we (again)
      copy the key into the target pool to ensure a proper lifetime.  */
-  path = apr_pstrdup(pool, change->path);
-  apr_hash_set(changes, path, APR_HASH_KEY_STRING, new_change);
+  path = apr_pstrmemdup(pool, change->path, path_len);
+  apr_hash_set(changes, path, path_len, new_change);
 
   /* Update the copyfrom cache, if any. */
   if (copyfrom_cache)
@@ -5742,10 +5743,12 @@ fold_change(apr_hash_t *changes,
         }
       /* We need to allocate a copy of the key in the copyfrom_pool if
        * we're not doing a deletion and if it isn't already there. */
-      if (copyfrom_string && ! apr_hash_get(copyfrom_cache, copyfrom_key,
-                                            APR_HASH_KEY_STRING))
-        copyfrom_key = apr_pstrdup(copyfrom_pool, copyfrom_key);
-      apr_hash_set(copyfrom_cache, copyfrom_key, APR_HASH_KEY_STRING,
+      if (   copyfrom_string
+          && (   ! apr_hash_count(copyfrom_cache)
+              || ! apr_hash_get(copyfrom_cache, copyfrom_key, path_len)))
+        copyfrom_key = apr_pstrmemdup(copyfrom_pool, copyfrom_key, path_len);
+
+      apr_hash_set(copyfrom_cache, copyfrom_key, path_len,
                    copyfrom_string);
     }
 
@@ -6119,7 +6122,7 @@ svn_fs_fs__paths_changed(apr_hash_t **ch
 
   SVN_ERR(get_changes(&changes, fs, rev, scratch_pool));
 
-  changed_paths = apr_hash_make(pool);
+  changed_paths = svn_hash__make(pool);
 
   SVN_ERR(process_changes(changed_paths, copyfrom_cache, changes,
                           TRUE, pool));

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.c Tue Oct  9 17:59:20 2012
@@ -1211,3 +1211,150 @@ svn_fs_fs__deserialize_changes(void **ou
 
   return SVN_NO_ERROR;
 }
+
+/* Auxiliary structure representing the content of a svn_mergeinfo_t hash.
+   This structure is much easier to (de-)serialize than an APR array.
+ */
+typedef struct mergeinfo_data_t
+{
+  /* number of paths in the hash */
+  unsigned count;
+  
+  /* COUNT keys (paths) */
+  const char **keys;
+  
+  /* COUNT keys lengths (strlen of path) */
+  apr_ssize_t *key_lengths;
+  
+  /* COUNT entries, each giving the number of ranges for the key */
+  int *range_counts;
+
+  /* all ranges in a single, concatenated buffer */
+  svn_merge_range_t *ranges;
+} mergeinfo_data_t;
+
+svn_error_t *
+svn_fs_fs__serialize_mergeinfo(void **data,
+                               apr_size_t *data_len,
+                               void *in,
+                               apr_pool_t *pool)
+{
+  svn_mergeinfo_t mergeinfo = in;
+  mergeinfo_data_t merges;
+  svn_temp_serializer__context_t *context;
+  svn_stringbuf_t *serialized;
+  apr_hash_index_t *hi;
+  int i, k;
+  apr_size_t range_count;
+
+  /* initialize our auxiliary data structure */
+  merges.count = apr_hash_count(mergeinfo);
+  merges.keys = apr_palloc(pool, sizeof(*merges.keys) * merges.count);
+  merges.key_lengths = apr_palloc(pool, sizeof(*merges.key_lengths) *
+                                        merges.count);
+  merges.range_counts = apr_palloc(pool, sizeof(*merges.range_counts) *
+                                         merges.count);
+
+  i = 0;
+  range_count = 0;
+  for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi), ++i)
+    {
+      svn_rangelist_t *ranges;
+      apr_hash_this(hi, (const void**)&merges.keys[i],
+                        &merges.key_lengths[i],
+                        (void **)&ranges);
+      merges.range_counts[i] = ranges->nelts;
+      range_count += ranges->nelts;
+    }
+
+  merges.ranges = apr_palloc(pool, sizeof(*merges.ranges) * range_count);
+
+  i = 0;
+  for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
+    {
+      svn_rangelist_t *ranges = svn__apr_hash_index_val(hi);
+      for (k = 0; k < ranges->nelts; ++k, ++i)
+        merges.ranges[i] = *APR_ARRAY_IDX(ranges, k, svn_merge_range_t*);
+    }
+  
+  /* serialize it and all its elements */
+  context = svn_temp_serializer__init(&merges,
+                                      sizeof(merges),
+                                      range_count * 30,
+                                      pool);
+
+  /* keys array */
+  svn_temp_serializer__push(context,
+                            (const void * const *)&merges.keys,
+                            merges.count * sizeof(*merges.keys));
+
+  for (i = 0; i < merges.count; ++i)
+    svn_temp_serializer__add_string(context, &merges.keys[i]);
+
+  svn_temp_serializer__pop(context);
+
+  /* key lengths array */
+  svn_temp_serializer__push(context,
+                            (const void * const *)&merges.key_lengths,
+                            merges.count * sizeof(*merges.key_lengths));
+  svn_temp_serializer__pop(context);
+
+  /* range counts array */
+  svn_temp_serializer__push(context,
+                            (const void * const *)&merges.range_counts,
+                            merges.count * sizeof(*merges.range_counts));
+  svn_temp_serializer__pop(context);
+
+  /* ranges */
+  svn_temp_serializer__push(context,
+                            (const void * const *)&merges.ranges,
+                            range_count * sizeof(*merges.ranges));
+  svn_temp_serializer__pop(context);
+
+  /* return the serialized result */
+  serialized = svn_temp_serializer__get(context);
+
+  *data = serialized->data;
+  *data_len = serialized->len;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__deserialize_mergeinfo(void **out,
+                                 void *data,
+                                 apr_size_t data_len,
+                                 apr_pool_t *pool)
+{
+  int i, k, n;
+  mergeinfo_data_t *merges = (mergeinfo_data_t *)data;
+  svn_mergeinfo_t mergeinfo;
+  
+  /* de-serialize our auxiliary data structure */
+  svn_temp_deserializer__resolve(merges, (void**)&merges->keys);
+  svn_temp_deserializer__resolve(merges, (void**)&merges->key_lengths);
+  svn_temp_deserializer__resolve(merges, (void**)&merges->range_counts);
+  svn_temp_deserializer__resolve(merges, (void**)&merges->ranges);
+
+  /* de-serialize keys and add entries to the result */
+  n = 0;
+  mergeinfo = svn_hash__make(pool);
+  for (i = 0; i < merges->count; ++i)
+    {
+      svn_rangelist_t *ranges = apr_array_make(pool,
+                                               merges->range_counts[i],
+                                               sizeof(svn_merge_range_t*));
+      for (k = 0; k < merges->range_counts[i]; ++k, ++n)
+        APR_ARRAY_PUSH(ranges, svn_merge_range_t*) = &merges->ranges[n];
+      
+      svn_temp_deserializer__resolve((void*)merges->keys,
+                                     (void**)&merges->keys[i]);
+      apr_hash_set(mergeinfo, merges->keys[i], merges->key_lengths[i], ranges);
+    }
+
+  /* done */
+  *out = mergeinfo;
+
+  return SVN_NO_ERROR;
+}
+

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.h?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.h (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/temp_serializer.h Tue Oct  9 17:59:20 2012
@@ -255,4 +255,22 @@ svn_fs_fs__deserialize_changes(void **ou
                                apr_size_t data_len,
                                apr_pool_t *pool);
 
+/**
+ * Implements #svn_cache__serialize_func_t for #svn_mergeinfo_t objects.
+ */
+svn_error_t *
+svn_fs_fs__serialize_mergeinfo(void **data,
+                               apr_size_t *data_len,
+                               void *in,
+                               apr_pool_t *pool);
+
+/**
+ * Implements #svn_cache__deserialize_func_t for #svn_mergeinfo_t objects.
+ */
+svn_error_t *
+svn_fs_fs__deserialize_mergeinfo(void **out,
+                                 void *data,
+                                 apr_size_t data_len,
+                                 apr_pool_t *pool);
+
 #endif

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/tree.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_fs_fs/tree.c Tue Oct  9 17:59:20 2012
@@ -3736,6 +3736,24 @@ crawl_directory_dag_for_mergeinfo(svn_fs
   return SVN_NO_ERROR;
 }
 
+/* Return the cache key as a combination of REV_ROOT->REV, the inheritance
+   flags INHERIT and ADJUST_INHERITED_MERGEINFO, and the PATH.  The result
+   will be allocated in POOL..
+ */
+static const char *
+mergeinfo_cache_key(const char *path,
+                    svn_fs_root_t *rev_root,
+                    svn_mergeinfo_inheritance_t inherit,
+                    svn_boolean_t adjust_inherited_mergeinfo,
+                    apr_pool_t *pool)
+{
+  apr_int64_t number = rev_root->rev;
+  number = number * 4
+         + (inherit == svn_mergeinfo_nearest_ancestor ? 2 : 0)
+         + (adjust_inherited_mergeinfo ? 1 : 0);
+  
+  return svn_fs_fs__combine_number_and_string(number, path, pool);
+}
 
 /* Calculates the mergeinfo for PATH under REV_ROOT using inheritance
    type INHERIT.  Returns it in *MERGEINFO, or NULL if there is none.
@@ -3743,20 +3761,18 @@ crawl_directory_dag_for_mergeinfo(svn_fs
    used for temporary allocations.
  */
 static svn_error_t *
-get_mergeinfo_for_path(svn_mergeinfo_t *mergeinfo,
-                       svn_fs_root_t *rev_root,
-                       const char *path,
-                       svn_mergeinfo_inheritance_t inherit,
-                       svn_boolean_t adjust_inherited_mergeinfo,
-                       apr_pool_t *result_pool,
-                       apr_pool_t *scratch_pool)
+get_mergeinfo_for_path_internal(svn_mergeinfo_t *mergeinfo,
+                                svn_fs_root_t *rev_root,
+                                const char *path,
+                                svn_mergeinfo_inheritance_t inherit,
+                                svn_boolean_t adjust_inherited_mergeinfo,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool)
 {
   parent_path_t *parent_path, *nearest_ancestor;
   apr_hash_t *proplist;
   svn_string_t *mergeinfo_string;
 
-  *mergeinfo = NULL;
-
   path = svn_fs__canonicalize_abspath(path, scratch_pool);
 
   SVN_ERR(open_path(&parent_path, rev_root, path, 0, NULL, scratch_pool));
@@ -3845,6 +3861,58 @@ get_mergeinfo_for_path(svn_mergeinfo_t *
   return SVN_NO_ERROR;
 }
 
+/* Caching wrapper around get_mergeinfo_for_path_internal().
+ */
+static svn_error_t *
+get_mergeinfo_for_path(svn_mergeinfo_t *mergeinfo,
+                       svn_fs_root_t *rev_root,
+                       const char *path,
+                       svn_mergeinfo_inheritance_t inherit,
+                       svn_boolean_t adjust_inherited_mergeinfo,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = rev_root->fs->fsap_data;
+  const char *cache_key;
+  svn_boolean_t found = FALSE;
+  svn_stringbuf_t *mergeinfo_exists;
+
+  *mergeinfo = NULL;
+
+  cache_key = mergeinfo_cache_key(path, rev_root, inherit,
+                                  adjust_inherited_mergeinfo, scratch_pool);
+  if (ffd->mergeinfo_existence_cache)
+    {
+      SVN_ERR(svn_cache__get((void **)&mergeinfo_exists, &found,
+                             ffd->mergeinfo_existence_cache,
+                             cache_key, result_pool));
+      if (found && mergeinfo_exists->data[0] == '1')
+        SVN_ERR(svn_cache__get((void **)mergeinfo, &found,
+                              ffd->mergeinfo_cache,
+                              cache_key, result_pool));
+    }
+    
+  if (! found)
+    {
+      SVN_ERR(get_mergeinfo_for_path_internal(mergeinfo, rev_root, path,
+                                              inherit,
+                                              adjust_inherited_mergeinfo,
+                                              result_pool, scratch_pool));
+      if (ffd->mergeinfo_existence_cache)
+        {
+          mergeinfo_exists = svn_stringbuf_create(*mergeinfo ? "1" : "0",
+                                                  scratch_pool);
+          SVN_ERR(svn_cache__set(ffd->mergeinfo_existence_cache,
+                                 cache_key, mergeinfo_exists, scratch_pool));
+          if (*mergeinfo)
+            SVN_ERR(svn_cache__set(ffd->mergeinfo_cache,
+                                  cache_key, *mergeinfo, scratch_pool));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Adds mergeinfo for each descendant of PATH (but not PATH itself)
    under ROOT to RESULT_CATALOG.  Returned values are allocated in
    RESULT_POOL; temporary values in POOL. */
@@ -3885,7 +3953,7 @@ get_mergeinfos_for_paths(svn_fs_root_t *
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
 {
-  svn_mergeinfo_catalog_t result_catalog = apr_hash_make(result_pool);
+  svn_mergeinfo_catalog_t result_catalog = svn_hash__make(result_pool);
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   int i;
 
@@ -4025,7 +4093,7 @@ make_revision_root(svn_fs_t *fs,
   root->rev = rev;
 
   frd->root_dir = root_dir;
-  frd->copyfrom_cache = apr_hash_make(root->pool);
+  frd->copyfrom_cache = svn_hash__make(root->pool);
 
   root->fsap_data = frd;
 

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/property.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/property.c Tue Oct  9 17:59:20 2012
@@ -322,16 +322,11 @@ propfind_closed(svn_ra_serf__xml_estate_
   else
     {
       apr_hash_t *gathered;
-      const char *path;
 
       SVN_ERR_ASSERT(leaving_state == PROPSTAT);
 
       gathered = svn_ra_serf__xml_gather_since(xes, PROPSTAT);
 
-      path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
-      if (path == NULL)
-        path = ctx->path;
-
       /* If we've squirreled away a note that says we want to ignore
          these properties, we'll do so.  Otherwise, we need to copy
          them from the temporary hash into the ctx->ret_props hash. */

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/serf.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/serf.c Tue Oct  9 17:59:20 2012
@@ -399,8 +399,10 @@ svn_ra_serf__open(svn_ra_session_t *sess
 
   serf_sess->capabilities = apr_hash_make(serf_sess->pool);
 
-  serf_sess->http10 = TRUE;  /* until we confirm HTTP/1.1  */
-  serf_sess->http10 = FALSE; /* ### don't change behavior yet  */
+  /* Assume HTTP/1.1 is supported. When the server responds HTTP/1.0, switch
+     from chunked encoding to Content-Length, and set Connection:keep-alive
+     header to try and keep the pipeline open. */
+  serf_sess->http10 = FALSE;
 
   SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
 

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/util.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_ra_serf/util.c Tue Oct  9 17:59:20 2012
@@ -691,6 +691,11 @@ setup_serf_req(serf_request_t *request,
       serf_bucket_headers_setn(*hdrs_bkt, "Content-Type", content_type);
     }
 
+#if SERF_VERSION_AT_LEAST(1, 1, 0)
+  if (session->http10)
+      serf_bucket_headers_setn(*hdrs_bkt, "Connection", "keep-alive");
+#endif
+
   /* These headers need to be sent with every request; see issue #3255
      ("mod_dav_svn does not pass client capabilities to start-commit
      hooks") for why. */
@@ -1796,9 +1801,9 @@ handle_response(serf_request_t *request,
       handler->sline = sl;
       handler->sline.reason = apr_pstrdup(handler->handler_pool, sl.reason);
 
-      /* HTTP/1.1? (or later)  */
-      if (sl.version != SERF_HTTP_10)
-        handler->session->http10 = FALSE;
+      /* Fall back to HTTP/1.0 needed? */
+      if (sl.version == SERF_HTTP_10)
+        handler->session->http10 = TRUE;
     }
 
   /* Keep reading from the network until we've read all the headers.  */
@@ -1909,6 +1914,17 @@ handle_response(serf_request_t *request,
         }
     }
 
+  /* These error codes might indicate that the server or proxy does not support
+     HTTP/1.1 (completely), so fall back to HTTP/1.0. */
+  if (handler->session->http10 == FALSE &&
+      (handler->sline.code == 400      /* 400 Bad Request */
+       || handler->sline.code == 411   /* 411 Length Required */
+       || handler->sline.code == 501)) /* 501 Not Implemented */
+    {
+      handler->discard_body = TRUE;
+      handler->session->http10 = TRUE;
+    }
+
   /* Stop processing the above, on every packet arrival.  */
   handler->reading_body = TRUE;
 

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_repos/log.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_repos/log.c Tue Oct  9 17:59:20 2012
@@ -39,6 +39,7 @@
 #include "repos.h"
 #include "private/svn_fspath.h"
 #include "private/svn_mergeinfo_private.h"
+#include "private/svn_subr_private.h"
 
 
 
@@ -159,6 +160,10 @@ svn_repos_check_revision_access(svn_repo
  * The CHANGED hash set and its keys and values are allocated in POOL;
  * keys are const char * paths and values are svn_log_changed_path_t.
  *
+ * To prevent changes from being processed over and over again, the
+ * changed paths for ROOT may be passed in PREFETCHED_CHANGES.  If the
+ * latter is NULL, we will request the list inside this function.
+ *
  * If optional AUTHZ_READ_FUNC is non-NULL, then use it (with
  * AUTHZ_READ_BATON and FS) to check whether each changed-path (and
  * copyfrom_path) is readable:
@@ -177,18 +182,20 @@ static svn_error_t *
 detect_changed(apr_hash_t **changed,
                svn_fs_root_t *root,
                svn_fs_t *fs,
+               apr_hash_t *prefetched_changes,
                svn_repos_authz_func_t authz_read_func,
                void *authz_read_baton,
                apr_pool_t *pool)
 {
-  apr_hash_t *changes;
+  apr_hash_t *changes = prefetched_changes;
   apr_hash_index_t *hi;
   apr_pool_t *subpool;
   svn_boolean_t found_readable = FALSE;
   svn_boolean_t found_unreadable = FALSE;
 
-  *changed = apr_hash_make(pool);
-  SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));
+  *changed = svn_hash__make(pool);
+  if (changes == NULL)
+    SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));
 
   if (apr_hash_count(changes) == 0)
     /* No paths changed in this revision?  Uh, sure, I guess the
@@ -551,26 +558,28 @@ next_history_rev(const apr_array_header_
 
 /* Set *DELETED_MERGEINFO_CATALOG and *ADDED_MERGEINFO_CATALOG to
    catalogs describing how mergeinfo values on paths (which are the
-   keys of those catalogs) were changed in REV. */
+   keys of those catalogs) were changed in REV.  If *PREFETCHED_CAHNGES
+   already contains the changed paths for REV, use that.  Otherwise,
+   request that data and return it in *PREFETCHED_CHANGES. */
 /* ### TODO: This would make a *great*, useful public function,
    ### svn_repos_fs_mergeinfo_changed()!  -- cmpilato  */
 static svn_error_t *
 fs_mergeinfo_changed(svn_mergeinfo_catalog_t *deleted_mergeinfo_catalog,
                      svn_mergeinfo_catalog_t *added_mergeinfo_catalog,
+                     apr_hash_t **prefetched_changes,
                      svn_fs_t *fs,
                      svn_revnum_t rev,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 
 {
-  apr_hash_t *changes;
   svn_fs_root_t *root;
   apr_pool_t *iterpool;
   apr_hash_index_t *hi;
 
   /* Initialize return variables. */
-  *deleted_mergeinfo_catalog = apr_hash_make(result_pool);
-  *added_mergeinfo_catalog = apr_hash_make(result_pool);
+  *deleted_mergeinfo_catalog = svn_hash__make(result_pool);
+  *added_mergeinfo_catalog = svn_hash__make(result_pool);
 
   /* Revision 0 has no mergeinfo and no mergeinfo changes. */
   if (rev == 0)
@@ -579,17 +588,20 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
   /* We're going to use the changed-paths information for REV to
      narrow down our search. */
   SVN_ERR(svn_fs_revision_root(&root, fs, rev, scratch_pool));
-  SVN_ERR(svn_fs_paths_changed2(&changes, root, scratch_pool));
+  if (*prefetched_changes == NULL)
+    SVN_ERR(svn_fs_paths_changed2(prefetched_changes, root, scratch_pool));
 
   /* No changed paths?  We're done. */
-  if (apr_hash_count(changes) == 0)
+  if (apr_hash_count(*prefetched_changes) == 0)
     return SVN_NO_ERROR;
 
   /* Loop over changes, looking for anything that might carry an
      svn:mergeinfo change and is one of our paths of interest, or a
      child or [grand]parent directory thereof. */
   iterpool = svn_pool_create(scratch_pool);
-  for (hi = apr_hash_first(scratch_pool, changes); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(scratch_pool, *prefetched_changes); 
+       hi;
+       hi = apr_hash_next(hi))
     {
       const void *key;
       void *val;
@@ -769,10 +781,14 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
 /* Determine what (if any) mergeinfo for PATHS was modified in
    revision REV, returning the differences for added mergeinfo in
    *ADDED_MERGEINFO and deleted mergeinfo in *DELETED_MERGEINFO.
+   If *PREFETCHED_CAHNGES already contains the changed paths for
+   REV, use that.  Otherwise, request that data and return it in
+   *PREFETCHED_CHANGES.
    Use POOL for all allocations. */
 static svn_error_t *
 get_combined_mergeinfo_changes(svn_mergeinfo_t *added_mergeinfo,
                                svn_mergeinfo_t *deleted_mergeinfo,
+                               apr_hash_t **prefetched_changes,
                                svn_fs_t *fs,
                                const apr_array_header_t *paths,
                                svn_revnum_t rev,
@@ -787,8 +803,8 @@ get_combined_mergeinfo_changes(svn_merge
   svn_error_t *err;
 
   /* Initialize return value. */
-  *added_mergeinfo = apr_hash_make(result_pool);
-  *deleted_mergeinfo = apr_hash_make(result_pool);
+  *added_mergeinfo = svn_hash__make(result_pool);
+  *deleted_mergeinfo = svn_hash__make(result_pool);
 
   /* If we're asking about revision 0, there's no mergeinfo to be found. */
   if (rev == 0)
@@ -804,6 +820,7 @@ get_combined_mergeinfo_changes(svn_merge
   /* Fetch the mergeinfo changes for REV. */
   err = fs_mergeinfo_changed(&deleted_mergeinfo_catalog,
                              &added_mergeinfo_catalog,
+                             prefetched_changes,
                              fs, rev, scratch_pool, scratch_pool);
   if (err)
     {
@@ -829,6 +846,7 @@ get_combined_mergeinfo_changes(svn_merge
     {
       const char *path = APR_ARRAY_IDX(paths, i, const char *);
       const char *prev_path;
+      apr_ssize_t klen;
       svn_revnum_t appeared_rev, prev_rev;
       svn_fs_root_t *prev_root;
       svn_mergeinfo_catalog_t catalog, inherited_catalog;
@@ -899,8 +917,9 @@ get_combined_mergeinfo_changes(svn_merge
                                     FALSE, /* adjust_inherited_mergeinfo */
                                     iterpool, iterpool));
 
-      prev_mergeinfo = apr_hash_get(catalog, prev_path, APR_HASH_KEY_STRING);
-      prev_inherited_mergeinfo = apr_hash_get(inherited_catalog, prev_path, APR_HASH_KEY_STRING);
+      klen = strlen(prev_path);
+      prev_mergeinfo = apr_hash_get(catalog, prev_path, klen);
+      prev_inherited_mergeinfo = apr_hash_get(inherited_catalog, prev_path, klen);
 
       /* Fetch the current mergeinfo (as of REV, and including
          inherited stuff) for this path. */
@@ -915,8 +934,9 @@ get_combined_mergeinfo_changes(svn_merge
                                     FALSE, /* adjust_inherited_mergeinfo */
                                     iterpool, iterpool));
 
-      mergeinfo = apr_hash_get(catalog, path, APR_HASH_KEY_STRING);
-      inherited_mergeinfo = apr_hash_get(inherited_catalog, path, APR_HASH_KEY_STRING);
+      klen = strlen(path);
+      mergeinfo = apr_hash_get(catalog, path, klen);
+      inherited_mergeinfo = apr_hash_get(inherited_catalog, path, klen);
 
       if (!prev_mergeinfo && !mergeinfo)
         continue;
@@ -935,6 +955,16 @@ get_combined_mergeinfo_changes(svn_merge
           if (inherits_same_mergeinfo)
             continue;
         }
+      else
+        {
+          svn_boolean_t same_mergeinfo;
+          SVN_ERR(svn_mergeinfo__equals(&same_mergeinfo,
+                                        prev_inherited_mergeinfo,
+                                        FALSE,
+                                        TRUE, iterpool));
+          if (same_mergeinfo)
+            continue;
+        }
 
       /* Compare, constrast, and combine the results. */
       SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, prev_mergeinfo,
@@ -989,6 +1019,7 @@ static svn_error_t *
 fill_log_entry(svn_log_entry_t *log_entry,
                svn_revnum_t rev,
                svn_fs_t *fs,
+               apr_hash_t *prefetched_changes,
                svn_boolean_t discover_changed_paths,
                const apr_array_header_t *revprops,
                svn_repos_authz_func_t authz_read_func,
@@ -1008,7 +1039,7 @@ fill_log_entry(svn_log_entry_t *log_entr
 
       SVN_ERR(svn_fs_revision_root(&newroot, fs, rev, pool));
       patherr = detect_changed(&changed_paths,
-                               newroot, fs,
+                               newroot, fs, prefetched_changes,
                                authz_read_func, authz_read_baton,
                                pool);
 
@@ -1048,7 +1079,7 @@ fill_log_entry(svn_log_entry_t *log_entr
           if (censor_revprops)
             {
               /* ... but we can only return author/date. */
-              log_entry->revprops = apr_hash_make(pool);
+              log_entry->revprops = svn_hash__make(pool);
               apr_hash_set(log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
                            APR_HASH_KEY_STRING,
                            apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR,
@@ -1077,7 +1108,7 @@ fill_log_entry(svn_log_entry_t *log_entr
                 /* ... but we can only return author/date. */
                 continue;
               if (log_entry->revprops == NULL)
-                log_entry->revprops = apr_hash_make(pool);
+                log_entry->revprops = svn_hash__make(pool);
               apr_hash_set(log_entry->revprops, name,
                            APR_HASH_KEY_STRING, value);
             }
@@ -1119,6 +1150,7 @@ fill_log_entry(svn_log_entry_t *log_entr
 static svn_error_t *
 send_log(svn_revnum_t rev,
          svn_fs_t *fs,
+         apr_hash_t *prefetched_changes,
          svn_mergeinfo_t log_target_history_as_mergeinfo,
          apr_hash_t *nested_merges,
          svn_boolean_t discover_changed_paths,
@@ -1137,7 +1169,7 @@ send_log(svn_revnum_t rev,
   svn_boolean_t found_rev_of_interest = TRUE;
 
   log_entry = svn_log_entry_create(pool);
-  SVN_ERR(fill_log_entry(log_entry, rev, fs,
+  SVN_ERR(fill_log_entry(log_entry, rev, fs, prefetched_changes,
                          discover_changed_paths || handling_merged_revision,
                          revprops, authz_read_func, authz_read_baton,
                          pool));
@@ -1800,7 +1832,7 @@ store_search(svn_mergeinfo_t processed,
      singe revisions where HIST_START is equal to HIST_END. */
   svn_revnum_t start = hist_start <= hist_end ? hist_start : hist_end;
   svn_revnum_t end = hist_start <= hist_end ? hist_end + 1 : hist_start + 1;
-  svn_mergeinfo_t mergeinfo = apr_hash_make(scratch_pool);
+  svn_mergeinfo_t mergeinfo = svn_hash__make(scratch_pool);
   apr_pool_t *processed_pool = apr_hash_pool_get(processed);
   int i;
 
@@ -1941,6 +1973,7 @@ do_logs(svn_fs_t *fs,
           svn_mergeinfo_t added_mergeinfo = NULL;
           svn_mergeinfo_t deleted_mergeinfo = NULL;
           svn_boolean_t has_children = FALSE;
+          apr_hash_t *changes = NULL;
 
           /* If we're including merged revisions, we need to calculate
              the mergeinfo deltas committed in this revision to our
@@ -1961,6 +1994,7 @@ do_logs(svn_fs_t *fs,
                 }
               SVN_ERR(get_combined_mergeinfo_changes(&added_mergeinfo,
                                                      &deleted_mergeinfo,
+                                                     &changes,
                                                      fs, cur_paths,
                                                      current, iterpool,
                                                      iterpool));
@@ -1973,7 +2007,7 @@ do_logs(svn_fs_t *fs,
              in anyway). */
           if (descending_order)
             {
-              SVN_ERR(send_log(current, fs,
+              SVN_ERR(send_log(current, fs, changes,
                                log_target_history_as_mergeinfo, nested_merges,
                                discover_changed_paths,
                                subtractive_merge, handling_merged_revisions,
@@ -1989,8 +2023,8 @@ do_logs(svn_fs_t *fs,
                          single hash to be shared across all of the merged
                          recursions so we can track and squelch duplicates. */
                       subpool = svn_pool_create(pool);
-                      nested_merges = apr_hash_make(subpool);
-                      processed = apr_hash_make(subpool);
+                      nested_merges = svn_hash__make(subpool);
+                      processed = svn_hash__make(subpool);
                     }
 
                   SVN_ERR(handle_merged_revisions(
@@ -2035,7 +2069,7 @@ do_logs(svn_fs_t *fs,
 
                   *cur_rev = current;
                   if (! rev_mergeinfo)
-                    rev_mergeinfo = apr_hash_make(pool);
+                    rev_mergeinfo = svn_hash__make(pool);
                   apr_hash_set(rev_mergeinfo, cur_rev, sizeof(*cur_rev),
                                add_and_del_mergeinfo);
                 }
@@ -2078,8 +2112,8 @@ do_logs(svn_fs_t *fs,
                               || apr_hash_count(deleted_mergeinfo) > 0);
             }
 
-          SVN_ERR(send_log(current, fs, log_target_history_as_mergeinfo,
-                           nested_merges,
+          SVN_ERR(send_log(current, fs, NULL,
+                           log_target_history_as_mergeinfo, nested_merges,
                            discover_changed_paths, subtractive_merge,
                            handling_merged_revisions, revprops, has_children,
                            receiver, receiver_baton, authz_read_func,
@@ -2089,7 +2123,7 @@ do_logs(svn_fs_t *fs,
               if (!nested_merges)
                 {
                   subpool = svn_pool_create(pool);
-                  nested_merges = apr_hash_make(subpool);
+                  nested_merges = svn_hash__make(subpool);
                 }
 
               SVN_ERR(handle_merged_revisions(current, fs,
@@ -2169,7 +2203,7 @@ get_paths_history_as_mergeinfo(svn_merge
       end_rev = tmp_rev;
     }
 
-  *paths_history_mergeinfo = apr_hash_make(result_pool);
+  *paths_history_mergeinfo = svn_hash__make(result_pool);
 
   for (i = 0; i < paths->nelts; i++)
     {
@@ -2302,7 +2336,8 @@ svn_repos_get_logs4(svn_repos_t *repos,
             rev = end - i;
           else
             rev = start + i;
-          SVN_ERR(send_log(rev, fs, NULL, NULL, discover_changed_paths, FALSE,
+          SVN_ERR(send_log(rev, fs, NULL, NULL, NULL,
+                           discover_changed_paths, FALSE,
                            FALSE, revprops, FALSE, receiver,
                            receiver_baton, authz_read_func,
                            authz_read_baton, iterpool));

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_subr/io.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_subr/io.c Tue Oct  9 17:59:20 2012
@@ -2058,8 +2058,12 @@ svn_io_file_lock2(const char *lock_file,
   if (locktype == APR_FLOCK_EXCLUSIVE)
     flags |= APR_WRITE;
 
+  /* locktype is never read after this block, so we don't need to bother
+     setting it.  If that were to ever change, uncomment the following
+     block. 
   if (nonblocking)
     locktype |= APR_FLOCK_NONBLOCK;
+  */
 
   SVN_ERR(svn_io_file_open(&lockfile_handle, lock_file, flags,
                            APR_OS_DEFAULT,

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_subr/mergeinfo.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_subr/mergeinfo.c Tue Oct  9 17:59:20 2012
@@ -35,6 +35,7 @@
 #include "private/svn_fspath.h"
 #include "private/svn_mergeinfo_private.h"
 #include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
 #include "svn_private_config.h"
 #include "svn_hash.h"
 #include "private/svn_dep_compat.h"
@@ -616,6 +617,7 @@ parse_revision_line(const char **input, 
                     apr_pool_t *scratch_pool)
 {
   const char *pathname = "";
+  apr_ssize_t klen;
   svn_rangelist_t *existing_rangelist;
   svn_rangelist_t *rangelist = apr_array_make(scratch_pool, 1,
                                               sizeof(svn_merge_range_t *));
@@ -700,14 +702,14 @@ parse_revision_line(const char **input, 
      leading slash, e.g. "trunk:4033\n/trunk:4039-4995".  In the event
      we encounter this we merge the rangelists together under a single
      absolute path key. */
-  existing_rangelist = apr_hash_get(hash, pathname, APR_HASH_KEY_STRING);
+  klen = strlen(pathname);
+  existing_rangelist = apr_hash_get(hash, pathname, klen);
   if (existing_rangelist)
     SVN_ERR(svn_rangelist_merge2(rangelist, existing_rangelist,
                                  scratch_pool, scratch_pool));
 
-  apr_hash_set(hash, apr_pstrdup(apr_hash_pool_get(hash), pathname),
-               APR_HASH_KEY_STRING,
-               svn_rangelist_dup(rangelist, apr_hash_pool_get(hash)));
+  apr_hash_set(hash, apr_pstrmemdup(apr_hash_pool_get(hash), pathname, klen),
+               klen, svn_rangelist_dup(rangelist, apr_hash_pool_get(hash)));
 
   return SVN_NO_ERROR;
 }
@@ -736,7 +738,7 @@ svn_mergeinfo_parse(svn_mergeinfo_t *mer
 {
   svn_error_t *err;
 
-  *mergeinfo = apr_hash_make(pool);
+  *mergeinfo = svn_hash__make(pool);
   err = parse_top(&input, input + strlen(input), *mergeinfo, pool);
 
   /* Always return SVN_ERR_MERGEINFO_PARSE_ERROR as the topmost error. */
@@ -1559,29 +1561,28 @@ mergeinfo_hash_diff_cb(const void *key, 
     {
       /* Record any deltas (additions or deletions). */
       svn_rangelist_t *deleted_rangelist, *added_rangelist;
-      from_rangelist = apr_hash_get(cb->from, path, APR_HASH_KEY_STRING);
-      to_rangelist = apr_hash_get(cb->to, path, APR_HASH_KEY_STRING);
+      from_rangelist = apr_hash_get(cb->from, path, klen);
+      to_rangelist = apr_hash_get(cb->to, path, klen);
       SVN_ERR(svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
                                  from_rangelist, to_rangelist,
                                  cb->consider_inheritance, cb->pool));
       if (cb->deleted && deleted_rangelist->nelts > 0)
-        apr_hash_set(cb->deleted, apr_pstrdup(cb->pool, path),
-                     APR_HASH_KEY_STRING, deleted_rangelist);
+        apr_hash_set(cb->deleted, apr_pstrmemdup(cb->pool, path, klen),
+                     klen, deleted_rangelist);
       if (cb->added && added_rangelist->nelts > 0)
-        apr_hash_set(cb->added, apr_pstrdup(cb->pool, path),
-                     APR_HASH_KEY_STRING, added_rangelist);
+        apr_hash_set(cb->added, apr_pstrmemdup(cb->pool, path, klen),
+                     klen, added_rangelist);
     }
   else if ((status == svn_hash_diff_key_a) && cb->deleted)
     {
-      from_rangelist = apr_hash_get(cb->from, path, APR_HASH_KEY_STRING);
-      apr_hash_set(cb->deleted, apr_pstrdup(cb->pool, path),
-                   APR_HASH_KEY_STRING,
+      from_rangelist = apr_hash_get(cb->from, path, klen);
+      apr_hash_set(cb->deleted, apr_pstrmemdup(cb->pool, path, klen), klen,
                    svn_rangelist_dup(from_rangelist, cb->pool));
     }
   else if ((status == svn_hash_diff_key_b) && cb->added)
     {
-      to_rangelist = apr_hash_get(cb->to, path, APR_HASH_KEY_STRING);
-      apr_hash_set(cb->added, apr_pstrdup(cb->pool, path), APR_HASH_KEY_STRING,
+      to_rangelist = apr_hash_get(cb->to, path, klen);
+      apr_hash_set(cb->added, apr_pstrmemdup(cb->pool, path, klen), klen,
                    svn_rangelist_dup(to_rangelist, cb->pool));
     }
   return SVN_NO_ERROR;
@@ -1618,17 +1619,17 @@ svn_mergeinfo_diff2(svn_mergeinfo_t *del
   if (from && to == NULL)
     {
       *deleted = svn_mergeinfo_dup(from, result_pool);
-      *added = apr_hash_make(result_pool);
+      *added = svn_hash__make(result_pool);
     }
   else if (from == NULL && to)
     {
-      *deleted = apr_hash_make(result_pool);
+      *deleted = svn_hash__make(result_pool);
       *added = svn_mergeinfo_dup(to, result_pool);
     }
   else
     {
-      *deleted = apr_hash_make(result_pool);
-      *added = apr_hash_make(result_pool);
+      *deleted = svn_hash__make(result_pool);
+      *added = svn_hash__make(result_pool);
 
       if (from && to)
         {
@@ -1648,17 +1649,77 @@ svn_mergeinfo__equals(svn_boolean_t *is_
                       svn_boolean_t consider_inheritance,
                       apr_pool_t *pool)
 {
-  if (apr_hash_count(info1) == apr_hash_count(info2))
+  apr_hash_index_t *hi;
+
+  *is_equal = FALSE;
+
+  /* special cases: at least one side has no merge info */
+  if (info1 == NULL && info2 == NULL)
     {
-      svn_mergeinfo_t deleted, added;
-      SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, info1, info2,
-                                  consider_inheritance, pool, pool));
-      *is_equal = apr_hash_count(deleted) == 0 && apr_hash_count(added) == 0;
+      *is_equal = TRUE;
+      return SVN_NO_ERROR;
     }
-  else
+
+  if (info1 == NULL ||  info2 == NULL)
+    return SVN_NO_ERROR;
+
+  /* trivial case: different number of paths -> unequal */
+  if (apr_hash_count(info1) != apr_hash_count(info2))
+    return SVN_NO_ERROR;
+
+  /* compare range lists for all paths */
+  for (hi = apr_hash_first(pool, info1); hi; hi = apr_hash_next(hi))
     {
-      *is_equal = FALSE;
+      const char *key;
+      apr_ssize_t key_length;
+      svn_rangelist_t *lhs, *rhs;
+      int i;
+      svn_rangelist_t *deleted, *added;
+
+      /* get both path lists */
+      apr_hash_this(hi, (const void**)&key, &key_length, (void **)&lhs);
+      rhs = apr_hash_get(info2, key, key_length);
+
+      /* missing on one side? */
+      if (rhs == NULL)
+        return SVN_NO_ERROR;
+
+      /* quick compare: the range lists will often be a perfect match */
+      if (lhs->nelts == rhs->nelts)
+        {
+          for (i = 0; i < lhs->nelts; ++i)
+            {
+              svn_merge_range_t *lrange
+                = APR_ARRAY_IDX(lhs, i, svn_merge_range_t *);
+              svn_merge_range_t *rrange
+                = APR_ARRAY_IDX(rhs, i, svn_merge_range_t *);
+
+              /* range mismatch? -> needs detailed comparison */
+              if (   lrange->start != rrange->start
+                  || lrange->end != rrange->end)
+                break;
+
+              /* inheritance mismatch? -> merge info differs */
+              if (   consider_inheritance
+                  && lrange->inheritable != rrange->inheritable)
+                return SVN_NO_ERROR;
+            }
+
+          /* all ranges found to match -> next path */
+          if (i == lhs->nelts)
+            continue;
+        }
+
+      /* range lists differ but there are many ways to sort and aggregate
+         revisions into ranges. Do a full diff on them. */
+      SVN_ERR(svn_rangelist_diff(&deleted, &added, lhs, rhs,
+                                  consider_inheritance, pool));
+      if (deleted->nelts || added->nelts)
+        return SVN_NO_ERROR;
     }
+
+  /* no mismatch found */
+  *is_equal = TRUE;
   return SVN_NO_ERROR;
 }
 
@@ -1668,62 +1729,37 @@ svn_mergeinfo_merge2(svn_mergeinfo_t mer
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *sorted1, *sorted2;
-  int i, j;
+  apr_hash_index_t *hi;
   apr_pool_t *iterpool;
 
   if (!apr_hash_count(changes))
     return SVN_NO_ERROR;
 
-  sorted1 = svn_sort__hash(mergeinfo, svn_sort_compare_items_as_paths,
-                           scratch_pool);
-  sorted2 = svn_sort__hash(changes, svn_sort_compare_items_as_paths,
-                           scratch_pool);
-
-  i = 0;
-  j = 0;
   iterpool = svn_pool_create(scratch_pool);
-  while (i < sorted1->nelts && j < sorted2->nelts)
+  for (hi = apr_hash_first(scratch_pool, changes); hi; hi = apr_hash_next(hi))
     {
-      svn_sort__item_t elt1, elt2;
-      int res;
-
-      svn_pool_clear(iterpool);
-
-      elt1 = APR_ARRAY_IDX(sorted1, i, svn_sort__item_t);
-      elt2 = APR_ARRAY_IDX(sorted2, j, svn_sort__item_t);
-      res = svn_sort_compare_items_as_paths(&elt1, &elt2);
-
-      if (res == 0)
-        {
-          svn_rangelist_t *rl1, *rl2;
-
-          rl1 = elt1.value;
-          rl2 = elt2.value;
-
-          SVN_ERR(svn_rangelist_merge2(rl1, rl2, result_pool, iterpool));
-          apr_hash_set(mergeinfo, elt1.key, elt1.klen, rl1);
-          i++;
-          j++;
-        }
-      else if (res < 0)
-        {
-          i++;
+      const char *key;
+      apr_ssize_t klen;
+      svn_rangelist_t *to_insert;
+      svn_rangelist_t *target;
+
+      /* get ranges to insert and the target ranges list of that insertion */
+      apr_hash_this(hi, (const void**)&key, &klen, (void*)&to_insert);
+      target = apr_hash_get(mergeinfo, key, klen);
+
+      /* if range list exists, just expand on it.
+       * Otherwise, add new hash entry. */
+      if (target)
+        {
+          SVN_ERR(svn_rangelist_merge2(target, to_insert, result_pool,
+                                       iterpool));
+          apr_pool_clear(iterpool);
         }
       else
-        {
-          apr_hash_set(mergeinfo, elt2.key, elt2.klen, elt2.value);
-          j++;
-        }
+        apr_hash_set(mergeinfo, key, klen, to_insert);
     }
-  svn_pool_destroy(iterpool);
 
-  /* Copy back any remaining elements from the second hash. */
-  for (; j < sorted2->nelts; j++)
-    {
-      svn_sort__item_t elt = APR_ARRAY_IDX(sorted2, j, svn_sort__item_t);
-      apr_hash_set(mergeinfo, elt.key, elt.klen, elt.value);
-    }
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -1970,7 +2006,7 @@ svn_mergeinfo_catalog_dup(svn_mergeinfo_
 svn_mergeinfo_t
 svn_mergeinfo_dup(svn_mergeinfo_t mergeinfo, apr_pool_t *pool)
 {
-  svn_mergeinfo_t new_mergeinfo = apr_hash_make(pool);
+  svn_mergeinfo_t new_mergeinfo = svn_hash__make(pool);
   apr_hash_index_t *hi;
 
   for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
@@ -2224,13 +2260,18 @@ svn_rangelist_dup(const svn_rangelist_t 
 {
   svn_rangelist_t *new_rl = apr_array_make(pool, rangelist->nelts,
                                            sizeof(svn_merge_range_t *));
+
+  /* allocate target range buffer with a single operation */
+  svn_merge_range_t *copy = apr_palloc(pool, sizeof(*copy) * rangelist->nelts);
   int i;
 
+  /* fill it iteratively and link it into the range list */
   for (i = 0; i < rangelist->nelts; i++)
     {
-      APR_ARRAY_PUSH(new_rl, svn_merge_range_t *) =
-        svn_merge_range_dup(APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *),
-                            pool);
+      memcpy(copy + i,
+             APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *),
+             sizeof(*copy));
+      APR_ARRAY_PUSH(new_rl, svn_merge_range_t *) = copy + i;
     }
 
   return new_rl;

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_wc/adm_ops.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_wc/adm_ops.c Tue Oct  9 17:59:20 2012
@@ -1019,6 +1019,7 @@ check_can_add_node(svn_node_kind_t *kind
   const char *base_name = svn_dirent_basename(local_abspath, scratch_pool);
   svn_boolean_t is_wc_root;
   svn_node_kind_t kind;
+  svn_boolean_t is_special;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(!copyfrom_url || (svn_uri_is_canonical(copyfrom_url,
@@ -1035,7 +1036,8 @@ check_can_add_node(svn_node_kind_t *kind
   SVN_ERR(svn_path_check_valid(local_abspath, scratch_pool));
 
   /* Make sure something's there; set KIND and *KIND_P. */
-  SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
+  SVN_ERR(svn_io_check_special_path(local_abspath, &kind, &is_special,
+                                    scratch_pool));
   if (kind == svn_node_none)
     return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                              _("'%s' not found"),
@@ -1097,14 +1099,20 @@ check_can_add_node(svn_node_kind_t *kind
               SVN_ERR_ASSERT(!is_wc_root);
               break;
             case svn_wc__db_status_normal:
-              if (copyfrom_url)
-                {
-                  SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
-                                                db, local_abspath,
-                                                scratch_pool));
+              SVN_ERR(svn_wc__db_is_wcroot(&is_wc_root, db, local_abspath,
+                                           scratch_pool));
 
-                  if (is_wc_root)
-                    break;
+              if (is_wc_root && copyfrom_url)
+                {
+                  /* Integrate a sub working copy in a parent working copy
+                     (legacy behavior) */
+                  break;
+                }
+              else if (is_wc_root && is_special)
+                {
+                  /* Adding a symlink to a working copy root.
+                     (special_tests.py 23: externals as symlink targets) */
+                  break;
                 }
               /* else: Fall through in default error */
 

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_wc/conflicts.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_wc/conflicts.c Tue Oct  9 17:59:20 2012
@@ -2408,10 +2408,8 @@ resolve_conflict_on_node(svn_boolean_t *
       apr_hash_t *their_old_props;
       apr_hash_t *their_props;
       apr_hash_t *conflicted_props;
-#if SVN_WC__VERSION >= SVN_WC__USES_CONFLICT_SKELS
       apr_hash_t *old_props;
       apr_hash_t *resolve_from = NULL;
-#endif
 
       SVN_ERR(svn_wc__conflict_read_prop_conflict(&prop_reject_file,
                                                   &mine_props, &their_old_props,
@@ -2419,7 +2417,6 @@ resolve_conflict_on_node(svn_boolean_t *
                                                   db, local_abspath, conflicts,
                                                   scratch_pool, scratch_pool));
 
-#if SVN_WC__VERSION >= SVN_WC__USES_CONFLICT_SKELS
       if (operation == svn_wc_operation_merge)
           SVN_ERR(svn_wc__db_read_pristine_props(&old_props, db, local_abspath,
                                                  scratch_pool, scratch_pool));
@@ -2483,7 +2480,6 @@ resolve_conflict_on_node(svn_boolean_t *
                                           FALSE, NULL, NULL,
                                           scratch_pool));
         }
-#endif
 
       /* Legacy behavior: Only report property conflicts as resolved when the
          property reject file exists

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_wc/entries.c?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_wc/entries.c Tue Oct  9 17:59:20 2012
@@ -1508,9 +1508,7 @@ insert_actual_node(svn_sqlite__db_t *sdb
                    apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
-#if SVN_WC__VERSION >= SVN_WC__USES_CONFLICT_SKELS
   svn_skel_t *conflict_data = NULL;
-#endif
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL_NODE));
 
@@ -1525,22 +1523,6 @@ insert_actual_node(svn_sqlite__db_t *sdb
   if (actual_node->changelist)
     SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->changelist));
 
-#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
-  if (actual_node->conflict_old
-      || actual_node->conflict_new
-      || actual_node->conflict_working)
-    {
-      SVN_ERR(svn_sqlite__bind_text(stmt, 7, actual_node->conflict_old));
-      SVN_ERR(svn_sqlite__bind_text(stmt, 8, actual_node->conflict_new));
-      SVN_ERR(svn_sqlite__bind_text(stmt, 9, actual_node->conflict_working));
-    }
-
-  if (actual_node->prop_reject)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 10, actual_node->prop_reject));
-
-  if (actual_node->tree_conflict_data)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 11, actual_node->tree_conflict_data));
-#else
   SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw(
                                 &conflict_data,
                                 db, wri_abspath,
@@ -1559,7 +1541,6 @@ insert_actual_node(svn_sqlite__db_t *sdb
 
       SVN_ERR(svn_sqlite__bind_blob(stmt, 6, data->data, data->len));
     }
-#endif
 
   /* Execute and reset the insert clause. */
   return svn_error_trace(svn_sqlite__insert(NULL, stmt));

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc-queries.sql?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc-queries.sql Tue Oct  9 17:59:20 2012
@@ -102,8 +102,7 @@ ORDER BY op_depth
 LIMIT 1
 
 -- STMT_SELECT_ACTUAL_NODE
-SELECT changelist, properties, conflict_data,
-conflict_old, conflict_new, conflict_working, prop_reject, tree_conflict_data
+SELECT changelist, properties, conflict_data
 FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2
 
@@ -127,8 +126,7 @@ FROM nodes_current
 WHERE wc_id = ?1 AND parent_relpath = ?2
 
 -- STMT_SELECT_ACTUAL_CHILDREN_INFO
-SELECT local_relpath, changelist, properties, conflict_data,
-conflict_old, conflict_new, conflict_working, prop_reject, tree_conflict_data
+SELECT local_relpath, changelist, properties, conflict_data
 FROM actual_node
 WHERE wc_id = ?1 AND parent_relpath = ?2
 
@@ -414,16 +412,11 @@ UPDATE nodes SET translated_size = ?3, l
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?5
 
 -- STMT_INSERT_ACTUAL_CONFLICT
-INSERT INTO actual_node (
-  wc_id, local_relpath, conflict_data,
-  conflict_old, conflict_new, conflict_working, prop_reject,
-  tree_conflict_data, parent_relpath)
-VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)
+INSERT INTO actual_node (wc_id, local_relpath, conflict_data, parent_relpath)
+VALUES (?1, ?2, ?3, ?4)
 
 -- STMT_UPDATE_ACTUAL_CONFLICT
-UPDATE actual_node SET conflict_data = ?3,
-  conflict_old = ?4, conflict_new = ?5, conflict_working = ?6,
-  prop_reject = ?7, tree_conflict_data = ?8
+UPDATE actual_node SET conflict_data = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2
 
 -- STMT_UPDATE_ACTUAL_CHANGELISTS
@@ -594,10 +587,6 @@ DELETE FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2
   AND properties IS NULL
   AND conflict_data IS NULL
-  AND conflict_old IS NULL
-  AND conflict_new IS NULL
-  AND prop_reject IS NULL
-  AND tree_conflict_data IS NULL
   AND changelist IS NULL
   AND text_mod IS NULL
   AND older_checksum IS NULL
@@ -610,10 +599,6 @@ WHERE wc_id = ?1
   AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND properties IS NULL
   AND conflict_data IS NULL
-  AND conflict_old IS NULL
-  AND conflict_new IS NULL
-  AND prop_reject IS NULL
-  AND tree_conflict_data IS NULL
   AND changelist IS NULL
   AND text_mod IS NULL
   AND older_checksum IS NULL
@@ -684,10 +669,6 @@ UPDATE actual_node
 SET properties = NULL,
     text_mod = NULL,
     conflict_data = NULL,
-    conflict_old = NULL,
-    conflict_new = NULL,
-    conflict_working = NULL,
-    prop_reject = NULL,
     tree_conflict_data = NULL,
     older_checksum = NULL,
     left_checksum = NULL,
@@ -699,10 +680,6 @@ UPDATE actual_node
 SET properties = NULL,
     text_mod = NULL,
     conflict_data = NULL,
-    conflict_old = NULL,
-    conflict_new = NULL,
-    conflict_working = NULL,
-    prop_reject = NULL,
     tree_conflict_data = NULL,
     older_checksum = NULL,
     left_checksum = NULL,
@@ -772,38 +749,7 @@ WHERE checksum = ?1 AND refcount = 0
 SELECT local_relpath, conflict_data
 FROM actual_node
 WHERE wc_id = ?1 AND parent_relpath = ?2 AND
-  NOT ((conflict_data IS NULL) AND (conflict_old IS NULL)
-       AND (conflict_new IS NULL) AND (conflict_working IS NULL)
-       AND (prop_reject IS NULL) AND (tree_conflict_data IS NULL))
-
--- STMT_SELECT_CONFLICT_MARKER_FILES1
-SELECT prop_reject
-FROM actual_node
-WHERE wc_id = ?1 AND local_relpath = ?2
-  AND (prop_reject IS NOT NULL)
-
--- STMT_SELECT_CONFLICT_MARKER_FILES2
-SELECT prop_reject, conflict_old, conflict_new, conflict_working
-FROM actual_node
-WHERE wc_id = ?1 AND parent_relpath = ?2
-  AND ((prop_reject IS NOT NULL) OR (conflict_old IS NOT NULL)
-       OR (conflict_new IS NOT NULL) OR (conflict_working IS NOT NULL))
-
--- STMT_CLEAR_TEXT_CONFLICT
-UPDATE actual_node SET
-  conflict_old = NULL,
-  conflict_new = NULL,
-  conflict_working = NULL
-WHERE wc_id = ?1 AND local_relpath = ?2
-
--- STMT_CLEAR_PROPS_CONFLICT
-UPDATE actual_node SET
-  prop_reject = NULL
-WHERE wc_id = ?1 AND local_relpath = ?2
-
--- STMT_CLEAR_TREE_CONFLICT
-UPDATE actual_node SET tree_conflict_data = NULL
-WHERE wc_id = ?1 AND local_relpath = ?2
+  NOT (conflict_data IS NULL)
 
 -- STMT_INSERT_WC_LOCK
 INSERT INTO wc_lock (wc_id, local_dir_relpath, locked_levels)
@@ -1100,9 +1046,8 @@ WHERE (wc_id = ?1 AND local_relpath = ?2
 
 -- STMT_INSERT_ACTUAL_NODE
 INSERT OR REPLACE INTO actual_node (
-  wc_id, local_relpath, parent_relpath, properties, changelist, conflict_data,
-  conflict_old, conflict_new, conflict_working, prop_reject, tree_conflict_data)
-VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)
+  wc_id, local_relpath, parent_relpath, properties, changelist, conflict_data)
+VALUES (?1, ?2, ?3, ?4, ?5, ?6)
 
 /* ------------------------------------------------------------------------- */
 
@@ -1113,8 +1058,7 @@ UPDATE actual_node SET conflict_data = ?
 WHERE wc_id = ?1 AND local_relpath = ?2
 
 -- STMT_INSERT_ACTUAL_CONFLICT_DATA
-INSERT INTO actual_node (
-  wc_id, local_relpath, conflict_data, parent_relpath)
+INSERT INTO actual_node (wc_id, local_relpath, conflict_data, parent_relpath)
 VALUES (?1, ?2, ?3, ?4)
 
 -- STMT_SELECT_ALL_FILES
@@ -1214,10 +1158,6 @@ CREATE TEMPORARY TABLE revert_list (
    local_relpath TEXT NOT NULL,
    actual INTEGER NOT NULL,         /* 1 if an actual row, 0 if a nodes row */
    conflict_data BLOB,
-   conflict_old TEXT,
-   conflict_new TEXT,
-   conflict_working TEXT,
-   prop_reject TEXT,
    notify INTEGER,         /* 1 if an actual row had props or tree conflict */
    op_depth INTEGER,
    repos_id INTEGER,
@@ -1237,11 +1177,8 @@ CREATE TEMPORARY TRIGGER trigger_revert_
 BEFORE DELETE ON actual_node
 BEGIN
    INSERT OR REPLACE INTO revert_list(local_relpath, actual, conflict_data,
-                                      conflict_old, conflict_new,
-                                      conflict_working, prop_reject, notify)
+                                      notify)
    SELECT OLD.local_relpath, 1, OLD.conflict_data,
-          OLD.conflict_old, OLD.conflict_new, OLD.conflict_working,
-          OLD.prop_reject,
           CASE
             WHEN OLD.properties IS NOT NULL
             THEN 1
@@ -1257,11 +1194,8 @@ CREATE TEMPORARY TRIGGER trigger_revert_
 BEFORE UPDATE ON actual_node
 BEGIN
    INSERT OR REPLACE INTO revert_list(local_relpath, actual, conflict_data,
-                                      conflict_old, conflict_new,
-                                      conflict_working, prop_reject, notify)
+                                      notify)
    SELECT OLD.local_relpath, 1, OLD.conflict_data,
-          OLD.conflict_old, OLD.conflict_new, OLD.conflict_working,
-          OLD.prop_reject,
           CASE
             WHEN OLD.properties IS NOT NULL
             THEN 1
@@ -1279,8 +1213,7 @@ DROP TRIGGER trigger_revert_list_actual_
 DROP TRIGGER trigger_revert_list_actual_update
 
 -- STMT_SELECT_REVERT_LIST
-SELECT actual, notify, kind, op_depth, repos_id, conflict_data,
-       conflict_old, conflict_new, conflict_working, prop_reject
+SELECT actual, notify, kind, op_depth, repos_id, conflict_data
 FROM revert_list
 WHERE local_relpath = ?1
 ORDER BY actual DESC

Modified: subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc.h?rev=1396140&r1=1396139&r2=1396140&view=diff
==============================================================================
--- subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/auto-props-sdc/subversion/libsvn_wc/wc.h Tue Oct  9 17:59:20 2012
@@ -152,10 +152,10 @@ extern "C" {
  * == 1.7.x shipped with format 29
  *
  * The bump to 30 switched the conflict storage to a skel inside conflict_data.
- * Also clears some known invalid state.
+ * Also clears some known invalid state. Bumped in r1387742.
  *
  * The bump to 31 added the inherited_props column in the NODES table.
- * Bumped in r????????.
+ * Bumped in r1395109.
  *
  * Please document any further format changes here.
  */
@@ -188,9 +188,6 @@ extern "C" {
 /* A version < this has no work queue (see workqueue.h).  */
 #define SVN_WC__HAS_WORK_QUEUE 13
 
-/* The first version that uses conflict skels for all conflicts */
-#define SVN_WC__USES_CONFLICT_SKELS 30
-
 /* Return true iff error E indicates an "is not a working copy" type
    of error, either because something wasn't a working copy at all, or
    because it's a working copy from a previous version (in need of