Modified: subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c Thu Oct 13 
15:25:15 2016
@@ -50,6 +50,7 @@
 
 #include "private/svn_wc_private.h"
 #include "private/svn_skel.h"
+#include "private/svn_sorts_private.h"
 #include "private/svn_string_private.h"
 
 #include "svn_private_config.h"
@@ -1622,7 +1623,14 @@ build_text_conflict_resolve_items(svn_sk
         }
       case svn_wc_conflict_choose_mine_full:
         {
-          install_from_abspath = mine_abspath;
+          /* In case of selecting to resolve the conflict choosing the full
+             own file, allow the text conflict resolution to just take the
+             existing local file if no merged file was present (case: binary
+             file conflicts do not generate a locally merge file).
+          */
+          install_from_abspath = mine_abspath
+                                   ? mine_abspath
+                                   : local_abspath;
           break;
         }
       case svn_wc_conflict_choose_theirs_conflict:
@@ -1633,6 +1641,15 @@ build_text_conflict_resolve_items(svn_sk
                 ? svn_diff_conflict_display_latest
                 : svn_diff_conflict_display_modified;
 
+          if (mine_abspath == NULL)
+            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, 
NULL,
+                                     _("Conflict on '%s' cannot be resolved to 
"
+                                       "'theirs-conflict' or 'mine-conflict' "
+                                       "because a merged version of the file "
+                                       "cannot be created."),
+                                     svn_dirent_local_style(local_abspath,
+                                                            scratch_pool));
+
           SVN_ERR(merge_showing_conflicts(&install_from_abspath,
                                           db, local_abspath,
                                           style, merge_options,
@@ -3391,6 +3408,7 @@ svn_wc__conflict_prop_mark_resolved(svn_
                                     const char *local_abspath,
                                     const char *propname,
                                     svn_wc_conflict_choice_t choice,
+                                    const svn_string_t *merged_value,
                                     svn_wc_notify_func2_t notify_func,
                                     void *notify_baton,
                                     apr_pool_t *scratch_pool)
@@ -3407,7 +3425,7 @@ svn_wc__conflict_prop_mark_resolved(svn_
 
   SVN_ERR(resolve_prop_conflict_on_node(&did_resolve, wc_ctx->db,
                                         local_abspath, conflicts,
-                                        propname, choice, NULL, NULL,
+                                        propname, choice, NULL, merged_value,
                                         NULL, NULL, scratch_pool));
 
   if (did_resolve && notify_func)
@@ -3684,3 +3702,176 @@ svn_wc__conflict_tree_update_moved_away_
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__conflict_tree_merge_local_changes(svn_wc_context_t *wc_ctx,
+                                          const char *local_abspath,
+                                          const char *dest_abspath,
+                                          svn_cancel_func_t cancel_func,
+                                          void *cancel_baton,
+                                          svn_wc_notify_func2_t notify_func,
+                                          void *notify_baton,
+                                          apr_pool_t *scratch_pool)
+{
+  svn_wc_conflict_reason_t local_change;
+  svn_wc_conflict_action_t incoming_change;
+  svn_wc_operation_t operation;
+  svn_boolean_t tree_conflicted;
+  const apr_array_header_t *conflicts;
+  svn_skel_t *conflict_skel;
+
+  SVN_ERR(svn_wc__read_conflicts(&conflicts, &conflict_skel,
+                                 wc_ctx->db, local_abspath,
+                                 FALSE, /* no tempfiles */
+                                 FALSE, /* only tree conflicts */
+                                 scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
+                                     &tree_conflicted, wc_ctx->db,
+                                     local_abspath, conflict_skel,
+                                     scratch_pool, scratch_pool));
+  if (!tree_conflicted)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_wc__conflict_read_tree_conflict(&local_change, &incoming_change,
+                                              NULL, wc_ctx->db, local_abspath,
+                                              conflict_skel,
+                                              scratch_pool, scratch_pool));
+
+  /* Make sure the expected conflict is recorded. */
+  if (operation != svn_wc_operation_update &&
+      operation != svn_wc_operation_switch &&
+      operation != svn_wc_operation_merge)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict operation '%s' on '%s'"),
+                             svn_token__to_word(operation_map, operation),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+  if (local_change != svn_wc_conflict_reason_edited)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict reason '%s' on '%s'"),
+                             svn_token__to_word(reason_map, local_change),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+  if (incoming_change != svn_wc_conflict_action_delete)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict action '%s' on '%s'"),
+                             svn_token__to_word(action_map, incoming_change),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  /* Merge local changes. */
+  SVN_ERR(svn_wc__db_merge_local_changes(wc_ctx->db, local_abspath,
+                                         dest_abspath, operation,
+                                         incoming_change, local_change,
+                                         cancel_func, cancel_baton,
+                                         notify_func, notify_baton,
+                                         scratch_pool));
+
+  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, cancel_func, cancel_baton,
+                         scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__guess_incoming_move_target_nodes(apr_array_header_t **possible_targets,
+                                         svn_wc_context_t *wc_ctx,
+                                         const char *victim_abspath,
+                                         svn_node_kind_t victim_node_kind,
+                                         const char *moved_to_repos_relpath,
+                                         svn_revnum_t rev,
+                                         apr_pool_t *result_pool,
+                                         apr_pool_t *scratch_pool)
+{
+  apr_array_header_t *candidates;
+  apr_pool_t *iterpool;
+  int i;
+  apr_size_t longest_ancestor_len = 0;
+
+  *possible_targets = apr_array_make(result_pool, 1, sizeof(const char *));
+  SVN_ERR(svn_wc__find_repos_node_in_wc(&candidates, wc_ctx->db, 
victim_abspath,
+                                        moved_to_repos_relpath, rev,
+                                        scratch_pool, scratch_pool));
+
+  /* Find a "useful move target" node in our set of candidates.
+   * Since there is no way to be certain, filter out nodes which seem
+   * unlikely candidates, and return the first node which is "good enough".
+   * Nodes which are tree conflict victims don't count, and nodes which
+   * cannot be modified (e.g. replaced or deleted nodes) don't count.
+   * Nodes which are of a different node kind don't count either.
+   * Ignore switched nodes as well, since that is an unlikely case during
+   * update/swtich/merge conflict resolution. And externals shouldn't even
+   * be on our candidate list in the first place.
+   * If multiple candidates match these criteria, choose the one which
+   * shares the longest common ancestor with the victim. */
+  iterpool = svn_pool_create(scratch_pool);
+  for (i = 0; i < candidates->nelts; i++)
+    {
+      const char *local_abspath;
+      const char *ancestor_abspath;
+      apr_size_t ancestor_len;
+      svn_boolean_t tree_conflicted;
+      svn_wc__db_status_t status;
+      svn_boolean_t is_wcroot;
+      svn_boolean_t is_switched;
+      svn_node_kind_t node_kind;
+      const char *moved_to_abspath;
+      int insert_index;
+
+      svn_pool_clear(iterpool);
+
+      local_abspath = APR_ARRAY_IDX(candidates, i, const char *);
+
+      SVN_ERR(svn_wc__internal_conflicted_p(NULL, NULL, &tree_conflicted,
+                                            wc_ctx->db, local_abspath,
+                                            iterpool));
+      if (tree_conflicted)
+        continue;
+
+      SVN_ERR(svn_wc__db_read_info(&status, &node_kind,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL,
+                                   wc_ctx->db, local_abspath, iterpool,
+                                   iterpool));
+      if (status != svn_wc__db_status_normal &&
+          status != svn_wc__db_status_added)
+        continue;
+
+      if (node_kind != victim_node_kind)
+        continue;
+
+      SVN_ERR(svn_wc__db_is_switched(&is_wcroot, &is_switched, NULL,
+                                     wc_ctx->db, local_abspath, iterpool));
+      if (is_wcroot || is_switched)
+        continue;
+
+      /* This might be a move target. Fingers crossed ;-) */
+      moved_to_abspath = apr_pstrdup(result_pool, local_abspath);
+
+      /* Insert the move target into the list. Targets which are closer
+       * (path-wise) to the conflict victim are more likely to be a good
+       * match, so put them at the front of the list. */
+      ancestor_abspath = svn_dirent_get_longest_ancestor(local_abspath,
+                                                         victim_abspath,
+                                                         iterpool);
+      ancestor_len = strlen(ancestor_abspath);
+      if (ancestor_len >= longest_ancestor_len)
+        {
+          longest_ancestor_len = ancestor_len;
+          insert_index = 0; /* prepend */
+        }
+      else
+        {
+          insert_index = (*possible_targets)->nelts; /* append */
+        }
+      svn_sort__array_insert(*possible_targets, &moved_to_abspath,
+                             insert_index);
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/authzperf/subversion/libsvn_wc/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/copy.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/copy.c Thu Oct 13 
15:25:15 2016
@@ -791,10 +791,11 @@ copy_or_move(svn_boolean_t *record_move_
             break; /* OK to add */
 
           default:
-            return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
-                               _("There is already a versioned item '%s'"),
-                               svn_dirent_local_style(dst_abspath,
-                                                      scratch_pool));
+            if (!metadata_only)
+              return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
+                                 _("There is already a versioned item '%s'"),
+                                 svn_dirent_local_style(dst_abspath,
+                                                        scratch_pool));
         }
   }
 

Modified: subversion/branches/authzperf/subversion/libsvn_wc/crop.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/crop.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/crop.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/crop.c Thu Oct 13 
15:25:15 2016
@@ -106,7 +106,12 @@ crop_children(svn_wc__db_t *db,
           svn_boolean_t modified, all_deletes;
 
           if (child_status != svn_wc__db_status_deleted)
-            continue; /* Leave local additions alone */
+            {
+              /* ### TODO: Check for issue #4636 constraints, but not only on
+                     this node, but also at all its descendants: We don't want
+                     to remove moved_from information here! */
+              continue; /* Leave local additions alone */
+            }
 
           SVN_ERR(svn_wc__node_has_local_mods(&modified, &all_deletes,
                                               db, child_abspath, FALSE,

Modified: subversion/branches/authzperf/subversion/libsvn_wc/entries.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/entries.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/entries.c Thu Oct 13 
15:25:15 2016
@@ -2004,7 +2004,7 @@ write_entry(struct write_baton **entry_n
   if (entry_node && entry->tree_conflict_data)
     {
       /* Issues #3840/#3916: 1.6 stores multiple tree conflicts on the
-         parent node, 1.7 stores them directly on the conflited nodes.
+         parent node, 1.7 stores them directly on the conflicted nodes.
          So "((skel1) (skel2))" becomes "(skel1)" and "(skel2)" */
       svn_skel_t *skel;
 

Modified: subversion/branches/authzperf/subversion/libsvn_wc/questions.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/questions.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/questions.c Thu Oct 13 
15:25:15 2016
@@ -79,15 +79,15 @@
 
 
 /* Set *MODIFIED_P to TRUE if (after translation) VERSIONED_FILE_ABSPATH
- * (of VERSIONED_FILE_SIZE bytes) differs from PRISTINE_STREAM (of
- * PRISTINE_SIZE bytes), else to FALSE if not.
+ * (of VERSIONED_FILE_SIZE bytes) differs from pristine file with checksum
+ * PRISTINE_CHECKSUM, else to FALSE if not.
  *
  * If EXACT_COMPARISON is FALSE, translate VERSIONED_FILE_ABSPATH's EOL
  * style and keywords to repository-normal form according to its properties,
- * and compare the result with PRISTINE_STREAM.  If EXACT_COMPARISON is
- * TRUE, translate PRISTINE_STREAM's EOL style and keywords to working-copy
- * form according to VERSIONED_FILE_ABSPATH's properties, and compare the
- * result with VERSIONED_FILE_ABSPATH.
+ * calculate checksum and compare the result with PRISTINE_STREAM.  If
+ * EXACT_COMPARISON is TRUE, open pristine, translate it's EOL style and
+ * keywords to working-copy form according to VERSIONED_FILE_ABSPATH's
+ * properties, and compare the result with VERSIONED_FILE_ABSPATH.
  *
  * HAS_PROPS should be TRUE if the file had properties when it was not
  * modified, otherwise FALSE.
@@ -95,8 +95,6 @@
  * PROPS_MOD should be TRUE if the file's properties have been changed,
  * otherwise FALSE.
  *
- * PRISTINE_STREAM will be closed before a successful return.
- *
  * DB is a wc_db; use SCRATCH_POOL for temporary allocation.
  */
 static svn_error_t *
@@ -104,20 +102,20 @@ compare_and_verify(svn_boolean_t *modifi
                    svn_wc__db_t *db,
                    const char *versioned_file_abspath,
                    svn_filesize_t versioned_file_size,
-                   svn_stream_t *pristine_stream,
-                   svn_filesize_t pristine_size,
+                   const svn_checksum_t *pristine_checksum,
                    svn_boolean_t has_props,
                    svn_boolean_t props_mod,
                    svn_boolean_t exact_comparison,
                    apr_pool_t *scratch_pool)
 {
-  svn_boolean_t same;
   svn_subst_eol_style_t eol_style;
   const char *eol_str;
   apr_hash_t *keywords;
   svn_boolean_t special = FALSE;
   svn_boolean_t need_translation;
   svn_stream_t *v_stream; /* versioned_file */
+  svn_checksum_t *v_checksum;
+  svn_error_t *err;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(versioned_file_abspath));
 
@@ -140,13 +138,20 @@ compare_and_verify(svn_boolean_t *modifi
   else
     need_translation = FALSE;
 
-  if (! need_translation
-      && (versioned_file_size != pristine_size))
+  if (! need_translation)
     {
-      *modified_p = TRUE;
+      svn_filesize_t pristine_size;
+
+      SVN_ERR(svn_wc__db_pristine_read(NULL, &pristine_size, db,
+                                       versioned_file_abspath, 
pristine_checksum,
+                                       scratch_pool, scratch_pool));
+
+      if (versioned_file_size != pristine_size)
+        {
+          *modified_p = TRUE;
 
-      /* ### Why did we open the pristine? */
-      return svn_error_trace(svn_stream_close(pristine_stream));
+          return SVN_NO_ERROR;
+        }
     }
 
   /* ### Other checks possible? */
@@ -162,8 +167,13 @@ compare_and_verify(svn_boolean_t *modifi
       /* We don't use APR-level buffering because the comparison function
        * will do its own buffering. */
       apr_file_t *file;
-      SVN_ERR(svn_io_file_open(&file, versioned_file_abspath, APR_READ,
-                               APR_OS_DEFAULT, scratch_pool));
+      err = svn_io_file_open(&file, versioned_file_abspath, APR_READ,
+                             APR_OS_DEFAULT, scratch_pool);
+      /* Convert EACCESS on working copy path to WC specific error code. */
+      if (err && APR_STATUS_IS_EACCES(err->apr_err))
+        return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
+      else
+        SVN_ERR(err);
       v_stream = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
 
       if (need_translation)
@@ -188,20 +198,38 @@ compare_and_verify(svn_boolean_t *modifi
             }
           else
             {
+              svn_boolean_t same;
+              svn_stream_t *pristine_stream;
+
+              SVN_ERR(svn_wc__db_pristine_read(&pristine_stream, NULL,
+                                               db, versioned_file_abspath,
+                                               pristine_checksum,
+                                               scratch_pool, scratch_pool));
               /* Wrap base stream to translate into working copy form, and
                * arrange to throw an error if its EOL style is inconsistent. */
               pristine_stream = svn_subst_stream_translated(pristine_stream,
                                                             eol_str, FALSE,
                                                             keywords, TRUE,
                                                             scratch_pool);
+              SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, 
v_stream,
+                                                scratch_pool));
+              *modified_p = (! same);
+              return SVN_NO_ERROR;
             }
         }
     }
 
-  SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, v_stream,
-                                    scratch_pool));
+  /* Get checksum of detranslated (normalized) content. */
+  err = svn_stream_contents_checksum(&v_checksum, v_stream,
+                                     pristine_checksum->kind,
+                                     scratch_pool, scratch_pool);
+  /* Convert EACCESS on working copy path to WC specific error code. */
+  if (err && APR_STATUS_IS_EACCES(err->apr_err))
+    return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
+  else
+    SVN_ERR(err);
 
-  *modified_p = (! same);
+  *modified_p = (! svn_checksum_match(v_checksum, pristine_checksum));
 
   return SVN_NO_ERROR;
 }
@@ -213,8 +241,6 @@ svn_wc__internal_file_modified_p(svn_boo
                                  svn_boolean_t exact_comparison,
                                  apr_pool_t *scratch_pool)
 {
-  svn_stream_t *pristine_stream;
-  svn_filesize_t pristine_size;
   svn_wc__db_status_t status;
   svn_node_kind_t kind;
   const svn_checksum_t *checksum;
@@ -302,27 +328,12 @@ svn_wc__internal_file_modified_p(svn_boo
     }
 
  compare_them:
-  SVN_ERR(svn_wc__db_pristine_read(&pristine_stream, &pristine_size,
-                                   db, local_abspath, checksum,
-                                   scratch_pool, scratch_pool));
-
   /* Check all bytes, and verify checksum if requested. */
-  {
-    svn_error_t *err;
-    err = compare_and_verify(modified_p, db,
+  SVN_ERR(compare_and_verify(modified_p, db,
                              local_abspath, dirent->filesize,
-                             pristine_stream, pristine_size,
-                             has_props, props_mod,
+                             checksum, has_props, props_mod,
                              exact_comparison,
-                             scratch_pool);
-
-    /* At this point we already opened the pristine file, so we know that
-       the access denied applies to the working copy path */
-    if (err && APR_STATUS_IS_EACCES(err->apr_err))
-      return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
-    else
-      SVN_ERR(err);
-  }
+                             scratch_pool));
 
   if (!*modified_p)
     {

Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc-queries.sql?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc-queries.sql Thu Oct 
13 15:25:15 2016
@@ -1291,6 +1291,10 @@ PRAGMA locking_mode = exclusive;
    exclusive-locking is mostly used on remote file systems. */
 PRAGMA journal_mode = DELETE
 
+-- STMT_FIND_REPOS_PATH_IN_WC
+SELECT local_relpath FROM nodes_current
+  WHERE wc_id = ?1 AND repos_path = ?2 AND revision = ?3
+
 /* ------------------------------------------------------------------------- */
 
 /* these are used in entries.c  */

Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c Thu Oct 13 
15:25:15 2016
@@ -10168,7 +10168,7 @@ db_read_repos_info(svn_revnum_t *revisio
                                                              local_relpath),
                                     result_pool);
             }
-          else
+          else if (base_del_relpath)
             {
               SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, revision,
                                                         repos_relpath,
@@ -10188,6 +10188,8 @@ db_read_repos_info(svn_revnum_t *revisio
                                                              local_relpath),
                                     result_pool);
             }
+          else
+            SVN_ERR_MALFUNCTION();
         }
       else if (status == svn_wc__db_status_excluded)
         {
@@ -16577,3 +16579,48 @@ svn_wc__db_process_commit_queue(svn_wc__
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__find_repos_node_in_wc(apr_array_header_t **local_abspath_list,
+                              svn_wc__db_t *db,
+                              const char *wri_abspath,
+                              const char *repos_relpath,
+                              svn_revnum_t rev,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *wri_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &wri_relpath, db,
+                                                 wri_abspath, scratch_pool,
+                                                 scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_FIND_REPOS_PATH_IN_WC));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isr", wcroot->wc_id, repos_relpath, rev));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  *local_abspath_list = apr_array_make(result_pool, have_row ? 1 : 0,
+                                       sizeof(const char*));
+  while (have_row)
+    {
+      const char *local_relpath;
+      const char *local_abspath;
+
+      local_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+      local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
+                                      result_pool);
+      APR_ARRAY_PUSH(*local_abspath_list, const char *) = local_abspath;
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+    
+  return svn_error_trace(svn_sqlite__reset(stmt));
+}
+

Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h Thu Oct 13 
15:25:15 2016
@@ -3048,7 +3048,7 @@ svn_wc__db_wclock_obtain(svn_wc__db_t *d
                          svn_boolean_t steal_lock,
                          apr_pool_t *scratch_pool);
 
-/* Set LOCK_ABSPATH to the path of the the directory that owns the
+/* Set LOCK_ABSPATH to the path of the directory that owns the
    lock on LOCAL_ABSPATH, or NULL, if LOCAL_ABSPATH is not locked. */
 svn_error_t*
 svn_wc__db_wclock_find_root(const char **lock_abspath,
@@ -3404,6 +3404,22 @@ svn_wc__db_update_moved_away_conflict_vi
                                              void *notify_baton,
                                              apr_pool_t *scratch_pool);
 
+/* Merge local changes from tree conflict victim at LOCAL_ABSPATH into the
+   directory at DEST_ABSPATH. This function requires that LOCAL_ABSPATH is
+   a directory and a tree-conflict victim. DST_ABSPATH must be a directory. */
+svn_error_t *
+svn_wc__db_merge_local_changes(svn_wc__db_t *db,
+                               const char *local_abspath,
+                               const char *dest_abspath,
+                               svn_wc_operation_t operation,
+                               svn_wc_conflict_action_t action,
+                               svn_wc_conflict_reason_t reason,
+                               svn_cancel_func_t cancel_func,
+                               void *cancel_baton,
+                               svn_wc_notify_func2_t notify_func,
+                               void *notify_baton,
+                               apr_pool_t *scratch_pool);
+
 /* LOCAL_ABSPATH is moved to MOVE_DST_ABSPATH.  MOVE_SRC_ROOT_ABSPATH
  * is the root of the move to MOVE_DST_OP_ROOT_ABSPATH.
  * DELETE_ABSPATH is the op-root of the move; it's the same
@@ -3459,6 +3475,24 @@ svn_wc__required_lock_for_resolve(const
                                   const char *local_abspath,
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool);
+
+/* Return an array of const char * elements, which represent local absolute
+ * paths for nodes, within the working copy indicated by WRI_ABSPATH, which
+ * correspond to REPOS_RELPATH@REV.
+ * If no such nodes exist, return an empty array.
+ *
+ * Note that this function returns each and every such node that is known
+ * in the WC, including, for example, nodes that were children of a directory
+ * which has been replaced.
+ */
+svn_error_t *
+svn_wc__find_repos_node_in_wc(apr_array_header_t **local_abspath_list,
+                              svn_wc__db_t *db,
+                              const char *wri_abspath,
+                              const char *repos_relpath,
+                              svn_revnum_t rev,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
 /* @} */
 
 typedef svn_error_t * (*svn_wc__db_verify_cb_t)(void *baton,

Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc_db_pristine.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc_db_pristine.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db_pristine.c 
(original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db_pristine.c Thu Oct 
13 15:25:15 2016
@@ -227,7 +227,6 @@ svn_wc__db_pristine_read(svn_stream_t **
   const char *local_relpath;
   const char *pristine_abspath;
 
-  SVN_ERR_ASSERT(contents != NULL);
   SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
 
   /* Some 1.6-to-1.7 wc upgrades created rows without checksums and
@@ -317,9 +316,10 @@ pristine_install_txn(svn_sqlite__db_t *s
           {
             return svn_error_createf(
               SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
-              _("New pristine text '%s' has different size: %ld versus %ld"),
+              _("New pristine text '%s' has different size: %s versus %s"),
               svn_checksum_to_cstring_display(sha1_checksum, scratch_pool),
-              (long int)finfo1.size, (long int)finfo2.size);
+              apr_off_t_toa(scratch_pool, finfo1.size),
+              apr_off_t_toa(scratch_pool, finfo2.size));
           }
       }
 #endif

Modified: subversion/branches/authzperf/subversion/libsvn_wc/wc_db_update_move.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/wc_db_update_move.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db_update_move.c 
(original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db_update_move.c Thu 
Oct 13 15:25:15 2016
@@ -1197,6 +1197,135 @@ tc_editor_alter_file(node_move_baton_t *
 }
 
 static svn_error_t *
+tc_editor_merge_local_file_change(node_move_baton_t *nmb,
+                                  const char *dst_relpath,
+                                  const char *src_relpath,
+                                  const svn_checksum_t *src_checksum,
+                                  const svn_checksum_t *dst_checksum,
+                                  apr_hash_t *dst_props,
+                                  apr_hash_t *src_props,
+                                  svn_boolean_t do_text_merge,
+                                  apr_pool_t *scratch_pool)
+{
+  update_move_baton_t *b = nmb->umb;
+  working_node_version_t old_version, new_version;
+  const char *dst_abspath = svn_dirent_join(b->wcroot->abspath,
+                                            dst_relpath,
+                                            scratch_pool);
+  svn_skel_t *conflict_skel = NULL;
+  apr_hash_t *actual_props;
+  apr_array_header_t *propchanges;
+  enum svn_wc_merge_outcome_t merge_outcome;
+  svn_wc_notify_state_t prop_state, content_state;
+  svn_skel_t *work_item, *work_items = NULL;
+  svn_node_kind_t dst_kind_on_disk;
+  svn_boolean_t obstructed = FALSE;
+
+  SVN_ERR(mark_node_edited(nmb, scratch_pool));
+  if (nmb->skip)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_io_check_path(dst_abspath, &dst_kind_on_disk, scratch_pool));
+  if (dst_kind_on_disk != svn_node_none && dst_kind_on_disk != svn_node_file)
+    {
+      SVN_ERR(create_node_tree_conflict(&conflict_skel, nmb, dst_relpath,
+                                        svn_node_file, svn_node_file,
+                                        svn_wc_conflict_reason_obstructed,
+                                        svn_wc_conflict_action_edit,
+                                        NULL,
+                                        scratch_pool, scratch_pool));
+      obstructed = TRUE;
+    }
+
+  old_version.location_and_kind = b->old_version;
+  new_version.location_and_kind = b->new_version;
+
+  old_version.checksum = src_checksum;
+  old_version.props = src_props;
+  new_version.checksum = dst_checksum;
+  new_version.props = dst_props;
+
+  SVN_ERR(update_working_props(&prop_state, &conflict_skel, &propchanges,
+                               &actual_props, b, dst_relpath,
+                               &old_version, &new_version,
+                               scratch_pool, scratch_pool));
+
+  if (!obstructed && do_text_merge)
+    {
+      const char *old_pristine_abspath;
+      const char *src_abspath;
+
+      /*
+       * Run a 3-way merge to update the file at its post-move location, using
+       * the pre-move file's pristine text as the merge base, the post-move
+       * content as the merge-left version, and the current content of the
+       * working file at the pre-move location as the merge-right version.
+       */
+      SVN_ERR(svn_wc__db_pristine_get_path(&old_pristine_abspath,
+                                           b->db, b->wcroot->abspath,
+                                           src_checksum,
+                                           scratch_pool, scratch_pool));
+      src_abspath = svn_dirent_join(b->wcroot->abspath, src_relpath,
+                                    scratch_pool);
+      SVN_ERR(svn_wc__internal_merge(&work_item, &conflict_skel,
+                                     &merge_outcome, b->db,
+                                     old_pristine_abspath,
+                                     src_abspath,
+                                     dst_abspath,
+                                     dst_abspath,
+                                     NULL, NULL, NULL, /* diff labels */
+                                     actual_props,
+                                     FALSE, /* dry-run */
+                                     NULL, /* diff3-cmd */
+                                     NULL, /* merge options */
+                                     propchanges,
+                                     b->cancel_func, b->cancel_baton,
+                                     scratch_pool, scratch_pool));
+
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+
+      if (merge_outcome == svn_wc_merge_conflict)
+        content_state = svn_wc_notify_state_conflicted;
+      else
+        content_state = svn_wc_notify_state_merged;
+    }
+  else
+    content_state = svn_wc_notify_state_unchanged;
+
+  /* If there are any conflicts to be stored, convert them into work items
+   * too. */
+  if (conflict_skel)
+    {
+      const char *dst_repos_relpath;
+
+      SVN_ERR(svn_wc__db_depth_get_info(NULL, NULL, NULL,
+                                        &dst_repos_relpath, NULL, NULL,
+                                        NULL, NULL, NULL, NULL, NULL, NULL,
+                                        NULL,
+                                        b->wcroot, dst_relpath,
+                                        b->dst_op_depth,
+                                        scratch_pool, scratch_pool));
+
+      SVN_ERR(create_conflict_markers(&work_item, dst_abspath, b->db,
+                                      dst_repos_relpath, conflict_skel,
+                                      b->operation, &old_version, &new_version,
+                                      svn_node_file, !obstructed,
+                                      scratch_pool, scratch_pool));
+
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+    }
+
+  SVN_ERR(update_move_list_add(b->wcroot, dst_relpath, b->db,
+                               svn_wc_notify_update_update,
+                               svn_node_file,
+                               content_state,
+                               prop_state,
+                               conflict_skel, work_items, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 tc_editor_delete(node_move_baton_t *nmb,
                  const char *relpath,
                  svn_node_kind_t old_kind,
@@ -1805,6 +1934,402 @@ svn_wc__db_update_moved_away_conflict_vi
 
   /* Send all queued up notifications. */
   SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, old_rev, new_rev,
+                                             notify_func, notify_baton,
+                                             scratch_pool));
+  if (notify_func)
+    {
+      svn_wc_notify_t *notify;
+
+      notify = svn_wc_create_notify(svn_dirent_join(wcroot->abspath,
+                                                    local_relpath,
+                                                    scratch_pool),
+                                    svn_wc_notify_update_completed,
+                                    scratch_pool);
+      notify->kind = svn_node_none;
+      notify->content_state = svn_wc_notify_state_inapplicable;
+      notify->prop_state = svn_wc_notify_state_inapplicable;
+      notify->revision = new_rev;
+      notify_func(notify_baton, notify, scratch_pool);
+    }
+
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+get_working_info(apr_hash_t **props,
+                 const svn_checksum_t **checksum,
+                 apr_array_header_t **children,
+                 svn_node_kind_t *kind,
+                 const char *local_relpath,
+                 svn_wc__db_wcroot_t *wcroot,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t status;
+  const char *repos_relpath;
+  svn_node_kind_t db_kind;
+  svn_error_t *err;
+
+  err = svn_wc__db_read_info_internal(&status, &db_kind, NULL, &repos_relpath,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      checksum,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      NULL, NULL, NULL, NULL, NULL,
+                                      wcroot, local_relpath,
+                                      result_pool, scratch_pool);
+
+  /* If there is no node, or only a node that describes a delete
+     of a lower layer we report this node as not existing. */
+  if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+      || (!err && status != svn_wc__db_status_added
+               && status != svn_wc__db_status_normal))
+    {
+      svn_error_clear(err);
+
+      if (kind)
+        *kind = svn_node_none;
+      if (checksum)
+        *checksum = NULL;
+      if (props)
+        *props = NULL;
+      if (children)
+        *children = apr_array_make(result_pool, 0, sizeof(const char *));
+
+      return SVN_NO_ERROR;
+    }
+  else
+    SVN_ERR(err);
+
+  SVN_ERR(svn_wc__db_read_props_internal(props, wcroot, local_relpath,
+                                         result_pool, scratch_pool));
+
+  if (kind)
+    *kind = db_kind;
+
+  if (children && db_kind == svn_node_dir)
+    {
+      svn_sqlite__stmt_t *stmt;
+      svn_boolean_t have_row;
+
+      *children = apr_array_make(result_pool, 16, sizeof(const char *));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_SELECT_WORKING_CHILDREN));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      while (have_row)
+        {
+          const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+
+          APR_ARRAY_PUSH(*children, const char *)
+              = svn_relpath_basename(child_relpath, result_pool);
+
+          SVN_ERR(svn_sqlite__step(&have_row, stmt));
+        }
+      SVN_ERR(svn_sqlite__reset(stmt));
+    }
+  else if (children)
+    *children = apr_array_make(result_pool, 0, sizeof(const char *));
+
+  return SVN_NO_ERROR;
+}
+
+/* ### Drive TC_EDITOR so as to ...
+ */
+static svn_error_t *
+walk_local_changes(node_move_baton_t *nmb,
+                   svn_wc__db_wcroot_t *wcroot,
+                   const char *src_relpath,
+                   const char *dst_relpath,
+                   apr_pool_t *scratch_pool)
+{
+  update_move_baton_t *b = nmb->umb;
+  svn_node_kind_t src_kind, dst_kind;
+  const svn_checksum_t *src_checksum, *dst_checksum;
+  apr_hash_t *src_props, *dst_props;
+  apr_array_header_t *src_children, *dst_children;
+
+  if (b->cancel_func)
+    SVN_ERR(b->cancel_func(b->cancel_baton));
+
+  SVN_ERR(get_working_info(&src_props, &src_checksum, &src_children,
+                           &src_kind, src_relpath, wcroot, scratch_pool,
+                           scratch_pool));
+
+  SVN_ERR(get_info(&dst_props, &dst_checksum, &dst_children, &dst_kind,
+                   dst_relpath, b->dst_op_depth,
+                   wcroot, scratch_pool, scratch_pool));
+
+  if (src_kind == svn_node_none
+      || (dst_kind != svn_node_none && src_kind != dst_kind))
+    {
+      SVN_ERR(tc_editor_delete(nmb, dst_relpath, dst_kind, src_kind,
+                               scratch_pool));
+    }
+
+  if (nmb->skip)
+    return SVN_NO_ERROR;
+
+  if (src_kind != svn_node_none && src_kind != dst_kind)
+    {
+      if (src_kind == svn_node_file || src_kind == svn_node_symlink)
+        {
+          SVN_ERR(tc_editor_add_file(nmb, dst_relpath, dst_kind,
+                                     src_checksum, src_props,
+                                     scratch_pool));
+        }
+      else if (src_kind == svn_node_dir)
+        {
+          SVN_ERR(tc_editor_add_directory(nmb, dst_relpath, dst_kind,
+                                          src_props, scratch_pool));
+        }
+    }
+  else if (src_kind != svn_node_none)
+    {
+      svn_boolean_t props_equal;
+
+      SVN_ERR(props_match(&props_equal, src_props, dst_props, scratch_pool));
+
+      if (src_kind == svn_node_file || src_kind == svn_node_symlink)
+        {
+          svn_boolean_t is_modified;
+
+          SVN_ERR(svn_wc__internal_file_modified_p(&is_modified, b->db,
+                                                   svn_dirent_join(
+                                                     b->wcroot->abspath,
+                                                     src_relpath,
+                                                     scratch_pool),
+                                                   FALSE /* exact_comparison 
*/,
+                                                   scratch_pool));
+          if (!props_equal || is_modified)
+            SVN_ERR(tc_editor_merge_local_file_change(nmb, dst_relpath,
+                                                      src_relpath,
+                                                      src_checksum,
+                                                      dst_checksum,
+                                                      dst_props, src_props,
+                                                      is_modified,
+                                                      scratch_pool));
+        }
+      else if (src_kind == svn_node_dir)
+        {
+          if (!props_equal)
+            SVN_ERR(tc_editor_alter_directory(nmb, dst_relpath,
+                                              dst_props, src_props,
+                                              scratch_pool));
+        }
+    }
+
+  if (nmb->skip)
+    return SVN_NO_ERROR;
+
+  if (src_kind == svn_node_dir)
+    {
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+      int i = 0, j = 0;
+
+      while (i < src_children->nelts || j < dst_children->nelts)
+        {
+          const char *child_name;
+          svn_boolean_t src_only = FALSE, dst_only = FALSE;
+          node_move_baton_t cnmb = { 0 };
+
+          cnmb.pb = nmb;
+          cnmb.umb = nmb->umb;
+          cnmb.shadowed = nmb->shadowed;
+
+          svn_pool_clear(iterpool);
+          if (i >= src_children->nelts)
+            {
+              dst_only = TRUE;
+              child_name = APR_ARRAY_IDX(dst_children, j, const char *);
+            }
+          else if (j >= dst_children->nelts)
+            {
+              src_only = TRUE;
+              child_name = APR_ARRAY_IDX(src_children, i, const char *);
+            }
+          else
+            {
+              const char *src_name = APR_ARRAY_IDX(src_children, i,
+                                                   const char *);
+              const char *dst_name = APR_ARRAY_IDX(dst_children, j,
+                                                   const char *);
+              int cmp = strcmp(src_name, dst_name);
+
+              if (cmp > 0)
+                dst_only = TRUE;
+              else if (cmp < 0)
+                src_only = TRUE;
+
+              child_name = dst_only ? dst_name : src_name;
+            }
+
+          cnmb.src_relpath = svn_relpath_join(src_relpath, child_name,
+                                              iterpool);
+          cnmb.dst_relpath = svn_relpath_join(dst_relpath, child_name,
+                                              iterpool);
+
+          if (!cnmb.shadowed)
+            SVN_ERR(check_node_shadowed(&cnmb.shadowed, wcroot,
+                                        cnmb.dst_relpath, b->dst_op_depth,
+                                        iterpool));
+
+          SVN_ERR(walk_local_changes(&cnmb, wcroot, cnmb.src_relpath,
+                                     cnmb.dst_relpath, iterpool));
+
+          if (!dst_only)
+            ++i;
+          if (!src_only)
+            ++j;
+
+          if (nmb->skip) /* Does parent now want a skip? */
+            break;
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* The body of svn_wc__db_merge_local_changes(). */
+static svn_error_t *
+merge_local_changes(svn_revnum_t *old_rev,
+                    svn_revnum_t *new_rev,
+                    svn_wc__db_t *db,
+                    svn_wc__db_wcroot_t *wcroot,
+                    const char *local_relpath,
+                    const char *dst_relpath,
+                    svn_wc_operation_t operation,
+                    svn_wc_conflict_action_t action,
+                    svn_wc_conflict_reason_t reason,
+                    svn_cancel_func_t cancel_func,
+                    void *cancel_baton,
+                    apr_pool_t *scratch_pool)
+{
+  update_move_baton_t umb = { NULL };
+  svn_wc_conflict_version_t old_version;
+  svn_wc_conflict_version_t new_version;
+  apr_int64_t repos_id;
+  node_move_baton_t nmb = { 0 };
+
+  SVN_ERR_ASSERT(svn_relpath_skip_ancestor(dst_relpath, local_relpath) == 
NULL);
+
+  /* In case of 'merge' the source is in the BASE tree (+ local mods) and the
+   * destination is a copied tree. For update/switch the source is a copied
+   * tree (copied from the pre-update BASE revision when the tree conflict
+   * was raised), and the destination is in the BASE tree. */
+  if (operation == svn_wc_operation_merge)
+    {
+      umb.src_op_depth = 0;
+      umb.dst_op_depth = relpath_depth(dst_relpath);
+    }
+  else
+    {
+      umb.src_op_depth = relpath_depth(local_relpath);
+      umb.dst_op_depth = 0;
+    }
+
+  SVN_ERR(verify_write_lock(wcroot, local_relpath, scratch_pool));
+  SVN_ERR(verify_write_lock(wcroot, dst_relpath, scratch_pool));
+
+  SVN_ERR(svn_wc__db_depth_get_info(NULL, &new_version.node_kind,
+                                    &new_version.peg_rev,
+                                    &new_version.path_in_repos, &repos_id,
+                                    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                    NULL,
+                                    wcroot, local_relpath, umb.src_op_depth,
+                                    scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__db_fetch_repos_info(&new_version.repos_url,
+                                      &new_version.repos_uuid,
+                                      wcroot, repos_id,
+                                      scratch_pool));
+
+  SVN_ERR(svn_wc__db_depth_get_info(NULL, &old_version.node_kind,
+                                    &old_version.peg_rev,
+                                    &old_version.path_in_repos, &repos_id,
+                                    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                    NULL,
+                                    wcroot, dst_relpath, umb.dst_op_depth,
+                                    scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__db_fetch_repos_info(&old_version.repos_url,
+                                      &old_version.repos_uuid,
+                                      wcroot, repos_id,
+                                      scratch_pool));
+  *old_rev = old_version.peg_rev;
+  *new_rev = new_version.peg_rev;
+
+  umb.operation = operation;
+  umb.old_version= &old_version;
+  umb.new_version= &new_version;
+  umb.db = db;
+  umb.wcroot = wcroot;
+  umb.cancel_func = cancel_func;
+  umb.cancel_baton = cancel_baton;
+
+  if (umb.src_op_depth == 0)
+    SVN_ERR(suitable_for_move(wcroot, local_relpath, scratch_pool));
+
+  /* Create a new, and empty, list for notification information. */
+  SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
+                                      STMT_CREATE_UPDATE_MOVE_LIST));
+
+  /* Drive the editor... */
+
+  nmb.umb = &umb;
+  nmb.src_relpath = local_relpath;
+  nmb.dst_relpath = dst_relpath;
+  /* nmb.shadowed = FALSE; */
+  /* nmb.edited = FALSE; */
+  /* nmb.skip_children = FALSE; */
+
+  /* We walk the move source, comparing each node with the equivalent node at
+   * the move destination and applying any local changes to nodes at the move
+   destination. */
+  SVN_ERR(walk_local_changes(&nmb, wcroot, local_relpath, dst_relpath,
+                             scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_merge_local_changes(svn_wc__db_t *db,
+                               const char *local_abspath,
+                               const char *dest_abspath,
+                               svn_wc_operation_t operation,
+                               svn_wc_conflict_action_t action,
+                               svn_wc_conflict_reason_t reason,
+                               svn_cancel_func_t cancel_func,
+                               void *cancel_baton,
+                               svn_wc_notify_func2_t notify_func,
+                               void *notify_baton,
+                               apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  svn_revnum_t old_rev, new_rev;
+  const char *local_relpath;
+  const char *dest_relpath;
+
+  /* ### Check for mixed-rev src or dst? */
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+                                                db, local_abspath,
+                                                scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  dest_relpath
+    = svn_dirent_skip_ancestor(wcroot->abspath, dest_abspath);
+
+  SVN_WC__DB_WITH_TXN(merge_local_changes(&old_rev, &new_rev, db, wcroot,
+                                          local_relpath, dest_relpath,
+                                          operation, action, reason,
+                                          cancel_func, cancel_baton,
+                                          scratch_pool),
+                      wcroot);
+
+  /* Send all queued up notifications. */
+  SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, old_rev, new_rev,
                                              notify_func, notify_baton,
                                              scratch_pool));
   if (notify_func)

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/dav_svn.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/dav_svn.h?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/dav_svn.h Thu Oct 13 
15:25:15 2016
@@ -457,6 +457,40 @@ const char *dav_svn__get_vtxn_stub(reque
 /* For accessing transaction properties (typically "!svn/vtxr") */
 const char *dav_svn__get_vtxn_root_stub(request_rec *r);
 
+
+/*** Output helpers ***/
+
+/* An opaque type which represents an output for a particular request.
+
+   All writes should target a dav_svn__output object by either using
+   the dav_svn__brigade functions or by preparing a bucket brigade and
+   passing it to the output with dav_svn__output_pass_brigade().
+
+   IMPORTANT:  Don't write to an ap_filter_t coming from mod_dav, and
+   use this wrapper and the corresponding private API instead.  Using
+   the ap_filter_t can cause unbounded memory usage with self-removing
+   output filters (e.g., with the filters installed by mod_headers or
+   mod_deflate).
+
+   See 
https://mail-archives.apache.org/mod_mbox/httpd-dev/201608.mbox/%3C20160822151917.GA22369%40redhat.com%3E
+*/
+typedef struct dav_svn__output dav_svn__output;
+
+/* Create the output wrapper for request R, allocated in POOL. */
+dav_svn__output *
+dav_svn__output_create(request_rec *r,
+                       apr_pool_t *pool);
+
+/* Get a bucket allocator to use for all bucket/brigade creations
+   when writing to OUTPUT. */
+apr_bucket_alloc_t *
+dav_svn__output_get_bucket_alloc(dav_svn__output *output);
+
+/* Pass the bucket brigade BB down to the OUTPUT's filter stack. */
+svn_error_t *
+dav_svn__output_pass_brigade(dav_svn__output *output,
+                             apr_bucket_brigade *bb);
+
 
 /*** activity.c ***/
 
@@ -645,7 +679,7 @@ dav_svn__insert_all_liveprops(request_re
 /* Generate the HTTP response body for a successful MERGE. */
 /* ### more docco */
 dav_error *
-dav_svn__merge_response(ap_filter_t *output,
+dav_svn__merge_response(dav_svn__output *output,
                         const dav_svn_repos *repos,
                         svn_revnum_t new_rev,
                         const char *post_commit_err,
@@ -679,49 +713,49 @@ static const dav_report_elem dav_svn__re
 dav_error *
 dav_svn__update_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output);
+                       dav_svn__output *output);
 dav_error *
 dav_svn__log_report(const dav_resource *resource,
                     const apr_xml_doc *doc,
-                    ap_filter_t *output);
+                    dav_svn__output *output);
 dav_error *
 dav_svn__dated_rev_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 dav_error *
 dav_svn__get_locations_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output);
+                              dav_svn__output *output);
 dav_error *
 dav_svn__get_location_segments_report(const dav_resource *resource,
                                       const apr_xml_doc *doc,
-                                      ap_filter_t *output);
+                                      dav_svn__output *output);
 dav_error *
 dav_svn__file_revs_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 dav_error *
 dav_svn__replay_report(const dav_resource *resource,
                        const apr_xml_doc *doc,
-                       ap_filter_t *output);
+                       dav_svn__output *output);
 dav_error *
 dav_svn__get_mergeinfo_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output);
+                              dav_svn__output *output);
 dav_error *
 dav_svn__get_locks_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output);
+                          dav_svn__output *output);
 
 dav_error *
 dav_svn__get_deleted_rev_report(const dav_resource *resource,
                                 const apr_xml_doc *doc,
-                                ap_filter_t *output);
+                                dav_svn__output *output);
 
 dav_error *
 dav_svn__get_inherited_props_report(const dav_resource *resource,
                                     const apr_xml_doc *doc,
-                                    ap_filter_t *output);
+                                    dav_svn__output *output);
 
 /*** posts/ ***/
 
@@ -729,11 +763,11 @@ dav_svn__get_inherited_props_report(cons
 dav_error *
 dav_svn__post_create_txn(const dav_resource *resource,
                          svn_skel_t *request_skel,
-                         ap_filter_t *output);
+                         dav_svn__output *output);
 dav_error *
 dav_svn__post_create_txn_with_props(const dav_resource *resource,
                                     svn_skel_t *request_skel,
-                                    ap_filter_t *output);
+                                    dav_svn__output *output);
 
 /*** authz.c ***/
 
@@ -940,23 +974,28 @@ int dav_svn__find_ns(const apr_array_hea
 
 /* Write LEN bytes from DATA to OUTPUT using BB.  */
 svn_error_t *dav_svn__brigade_write(apr_bucket_brigade *bb,
-                                    ap_filter_t *output,
+                                    dav_svn__output *output,
                                     const char *buf,
                                     apr_size_t len);
 
 /* Write NULL-terminated string STR to OUTPUT using BB.  */
 svn_error_t *dav_svn__brigade_puts(apr_bucket_brigade *bb,
-                                   ap_filter_t *output,
+                                   dav_svn__output *output,
                                    const char *str);
 
 
 /* Write data to OUTPUT using BB, using FMT as the output format string.  */
 svn_error_t *dav_svn__brigade_printf(apr_bucket_brigade *bb,
-                                     ap_filter_t *output,
+                                     dav_svn__output *output,
                                      const char *fmt,
                                      ...)
   __attribute__((format(printf, 3, 4)));
 
+/* Write an unspecified number of strings to OUTPUT using BB.  */
+svn_error_t *dav_svn__brigade_putstrs(apr_bucket_brigade *bb,
+                                      dav_svn__output *output,
+                                      ...) SVN_NEEDS_SENTINEL_NULL;
+
 
 
 
@@ -990,11 +1029,10 @@ dav_svn__sanitize_error(svn_error_t *ser
 
 
 /* Return a writable generic stream that will encode its output to base64
-   and send it to the Apache filter OUTPUT using BB.  Allocate the stream in
-   POOL. */
+   and send it to OUTPUT using BB.  Allocate the stream in POOL. */
 svn_stream_t *
 dav_svn__make_base64_output_stream(apr_bucket_brigade *bb,
-                                   ap_filter_t *output,
+                                   dav_svn__output *output,
                                    apr_pool_t *pool);
 
 /* In INFO->r->subprocess_env set "SVN-ACTION" to LINE, "SVN-REPOS" to
@@ -1036,7 +1074,8 @@ dav_svn__operational_log(struct dav_reso
  */
 dav_error *
 dav_svn__final_flush_or_error(request_rec *r, apr_bucket_brigade *bb,
-                              ap_filter_t *output, dav_error *preferred_err,
+                              dav_svn__output *output,
+                              dav_error *preferred_err,
                               apr_pool_t *pool);
 
 /* Log a DAV error response.

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/merge.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/merge.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/merge.c Thu Oct 13 
15:25:15 2016
@@ -72,13 +72,12 @@ send_response(const dav_svn_repos *repos
               svn_fs_root_t *root,
               const char *path,
               svn_boolean_t is_dir,
-              ap_filter_t *output,
+              dav_svn__output *output,
               apr_bucket_brigade *bb,
               apr_pool_t *pool)
 {
   const char *href;
   const char *vsn_url;
-  apr_status_t status;
   svn_revnum_t rev_to_use;
 
   href = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_PUBLIC,
@@ -86,7 +85,7 @@ send_response(const dav_svn_repos *repos
   rev_to_use = dav_svn__get_safe_cr(root, path, pool);
   vsn_url = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_VERSION,
                                rev_to_use, path, FALSE /* add_href */, pool);
-  status = ap_fputstrs(output, bb,
+  SVN_ERR(dav_svn__brigade_putstrs(bb, output,
                        "<D:response>" DEBUG_CR
                        "<D:href>",
                        apr_xml_quote_string(pool, href, 1),
@@ -103,9 +102,7 @@ send_response(const dav_svn_repos *repos
                        "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                        "</D:propstat>" DEBUG_CR
                        "</D:response>" DEBUG_CR,
-                       NULL);
-  if (status != APR_SUCCESS)
-    return svn_error_wrap_apr(status, "Can't write response to output");
+                       SVN_VA_NULL));
 
   return SVN_NO_ERROR;
 }
@@ -115,7 +112,7 @@ static svn_error_t *
 do_resources(const dav_svn_repos *repos,
              svn_fs_root_t *root,
              svn_revnum_t revision,
-             ap_filter_t *output,
+             dav_svn__output *output,
              apr_bucket_brigade *bb,
              apr_pool_t *pool)
 {
@@ -217,7 +214,7 @@ do_resources(const dav_svn_repos *repos,
 */
 
 dav_error *
-dav_svn__merge_response(ap_filter_t *output,
+dav_svn__merge_response(dav_svn__output *output,
                         const dav_svn_repos *repos,
                         svn_revnum_t new_rev,
                         const char *post_commit_err,
@@ -233,7 +230,6 @@ dav_svn__merge_response(ap_filter_t *out
   svn_string_t *creationdate, *creator_displayname;
   const char *post_commit_err_elem = NULL,
              *post_commit_header_info = NULL;
-  apr_status_t status;
   apr_hash_t *revprops;
 
   serr = svn_fs_revision_root(&root, repos->fs, new_rev, pool);
@@ -245,7 +241,8 @@ dav_svn__merge_response(ap_filter_t *out
                                   repos->pool);
     }
 
-  bb = apr_brigade_create(pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   /* prep some strings */
 
@@ -289,7 +286,7 @@ dav_svn__merge_response(ap_filter_t *out
   creationdate = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
   creator_displayname = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
 
-  status = ap_fputstrs(output, bb,
+  serr = dav_svn__brigade_putstrs(bb, output,
                      DAV_XML_HEADER DEBUG_CR
                      "<D:merge-response xmlns:D=\"DAV:\"",
                      post_commit_header_info,
@@ -308,48 +305,47 @@ dav_svn__merge_response(ap_filter_t *out
                      "<D:resourcetype><D:baseline/></D:resourcetype>" DEBUG_CR,
                      post_commit_err_elem, DEBUG_CR
                      "<D:version-name>", rev, "</D:version-name>" DEBUG_CR,
-                     NULL);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+                     SVN_VA_NULL);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   if (creationdate)
     {
-      status = ap_fputstrs(output, bb,
+      serr = dav_svn__brigade_putstrs(bb, output,
                          "<D:creationdate>",
                          apr_xml_quote_string(pool, creationdate->data, 1),
                          "</D:creationdate>" DEBUG_CR,
-                         NULL);
-      if (status != APR_SUCCESS)
-        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                                  0, status,
-                                  "Could not write output");
+                         SVN_VA_NULL);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write output",
+                                    repos->pool);
     }
   if (creator_displayname)
     {
-      status = ap_fputstrs(output, bb,
+      serr = dav_svn__brigade_putstrs(bb, output,
                          "<D:creator-displayname>",
                          apr_xml_quote_string(pool,
                                               creator_displayname->data, 1),
                          "</D:creator-displayname>" DEBUG_CR,
-                         NULL);
-      if (status != APR_SUCCESS)
-        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                                  0, status,
-                                  "Could not write output");
+                         SVN_VA_NULL);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not write output",
+                                    repos->pool);
     }
-  status = ap_fputstrs(output, bb,
+  serr = dav_svn__brigade_putstrs(bb, output,
                      "</D:prop>" DEBUG_CR
                      "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                      "</D:propstat>" DEBUG_CR
                      "</D:response>" DEBUG_CR,
-
-                     NULL);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+                     SVN_VA_NULL);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   /* ONLY have dir_delta drive the editor if the caller asked us to
      generate a full MERGE response.  svn clients can ask us to
@@ -378,20 +374,20 @@ dav_svn__merge_response(ap_filter_t *out
     }
 
   /* wrap up the merge response */
-  status = ap_fputs(output, bb,
-                  "</D:updated-set>" DEBUG_CR
-                  "</D:merge-response>" DEBUG_CR);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+  serr = dav_svn__brigade_puts(bb, output,
+                               "</D:updated-set>" DEBUG_CR
+                               "</D:merge-response>" DEBUG_CR);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   /* send whatever is left in the brigade */
-  status = ap_pass_brigade(output, bb);
-  if (status != APR_SUCCESS)
-    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              0, status,
-                              "Could not write output");
+  serr = dav_svn__output_pass_brigade(output, bb);
+  if (serr != NULL)
+    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                "Could not write output",
+                                repos->pool);
 
   return NULL;
 }

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/posts/create_txn.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/posts/create_txn.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/posts/create_txn.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/posts/create_txn.c Thu 
Oct 13 15:25:15 2016
@@ -34,7 +34,7 @@
 dav_error *
 dav_svn__post_create_txn(const dav_resource *resource,
                          svn_skel_t *request_skel,
-                         ap_filter_t *output)
+                         dav_svn__output *output)
 {
   const char *txn_name;
   const char *vtxn_name;
@@ -75,7 +75,7 @@ dav_svn__post_create_txn(const dav_resou
 dav_error *
 dav_svn__post_create_txn_with_props(const dav_resource *resource,
                                     svn_skel_t *request_skel,
-                                    ap_filter_t *output)
+                                    dav_svn__output *output)
 {
   const char *txn_name;
   const char *vtxn_name;

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/dated-rev.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/dated-rev.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/dated-rev.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/dated-rev.c 
Thu Oct 13 15:25:15 2016
@@ -50,7 +50,7 @@
 dav_error *
 dav_svn__dated_rev_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   apr_xml_elem *child;
   int ns;
@@ -58,7 +58,6 @@ dav_svn__dated_rev_report(const dav_reso
   svn_revnum_t rev;
   apr_bucket_brigade *bb;
   svn_error_t *err;
-  apr_status_t apr_err;
   dav_error *derr = NULL;
 
   /* Find the DAV:creationdate element and get the requested time from it. */
@@ -95,15 +94,16 @@ dav_svn__dated_rev_report(const dav_reso
                                 "Could not access revision times.");
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-  apr_err = ap_fprintf(output, bb,
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
+  err = dav_svn__brigade_printf(bb, output,
                        DAV_XML_HEADER DEBUG_CR
                        "<S:dated-rev-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
                        "xmlns:D=\"DAV:\">" DEBUG_CR
                        "<D:" SVN_DAV__VERSION_NAME ">%ld</D:"
                        SVN_DAV__VERSION_NAME ">""</S:dated-rev-report>", rev);
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/deleted-rev.c 
Thu Oct 13 15:25:15 2016
@@ -41,7 +41,7 @@
 dav_error *
 dav_svn__get_deleted_rev_report(const dav_resource *resource,
                                 const apr_xml_doc *doc,
-                                ap_filter_t *output)
+                                dav_svn__output *output)
 {
   apr_xml_elem *child;
   int ns;
@@ -52,7 +52,6 @@ dav_svn__get_deleted_rev_report(const da
   svn_revnum_t deleted_rev;
   apr_bucket_brigade *bb;
   svn_error_t *err;
-  apr_status_t apr_err;
   dav_error *derr = NULL;
 
   /* Sanity check. */
@@ -118,16 +117,17 @@ dav_svn__get_deleted_rev_report(const da
                                 "Could not find revision path was deleted.");
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
-  apr_err = ap_fprintf(output, bb,
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
+  err = dav_svn__brigade_printf(bb, output,
                        DAV_XML_HEADER DEBUG_CR
                        "<S:get-deleted-rev-report xmlns:S=\""
                        SVN_XML_NAMESPACE "\" xmlns:D=\"DAV:\">" DEBUG_CR
                        "<D:" SVN_DAV__VERSION_NAME ">%ld</D:"
                        SVN_DAV__VERSION_NAME ">""</S:get-deleted-rev-report>",
                        deleted_rev);
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/file-revs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/file-revs.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/file-revs.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/file-revs.c 
Thu Oct 13 15:25:15 2016
@@ -43,7 +43,7 @@ struct file_rev_baton {
   apr_bucket_brigade *bb;
 
   /* where to deliver the output */
-  ap_filter_t *output;
+  dav_svn__output *output;
 
   /* Whether we've written the <S:file-revs-report> header.  Allows for lazy
      writes to support mod_dav-based error handling. */
@@ -234,7 +234,7 @@ file_rev_handler(void *baton,
 dav_error *
 dav_svn__file_revs_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -304,7 +304,7 @@ dav_svn__file_revs_report(const dav_reso
                                   "Not all parameters passed");
 
   frb.bb = apr_brigade_create(resource->pool,
-                              output->c->bucket_alloc);
+                              dav_svn__output_get_bucket_alloc(output));
   frb.output = output;
   frb.needs_header = TRUE;
   frb.svndiff_version = resource->info->svndiff_version;

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-location-segments.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-location-segments.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-location-segments.c
 (original)
+++ 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-location-segments.c
 Thu Oct 13 15:25:15 2016
@@ -48,7 +48,7 @@
 struct location_segment_baton
 {
   svn_boolean_t sent_opener;
-  ap_filter_t *output;
+  dav_svn__output *output;
   apr_bucket_brigade *bb;
   dav_svn__authz_read_baton arb;
 };
@@ -79,28 +79,26 @@ location_segment_receiver(svn_location_s
                           apr_pool_t *pool)
 {
   struct location_segment_baton *b = baton;
-  apr_status_t apr_err;
 
   SVN_ERR(maybe_send_opener(b));
 
   if (segment->path)
     {
       const char *path_quoted = apr_xml_quote_string(pool, segment->path, 1);
-      apr_err = ap_fprintf(b->output, b->bb,
+
+      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                            "<S:location-segment path=\"%s\" "
                            "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
                            path_quoted,
-                           segment->range_start, segment->range_end);
+                           segment->range_start, segment->range_end));
     }
   else
     {
-      apr_err = ap_fprintf(b->output, b->bb,
+      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                            "<S:location-segment "
                            "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
-                           segment->range_start, segment->range_end);
+                           segment->range_start, segment->range_end));
     }
-  if (apr_err)
-    return svn_error_create(apr_err, 0, NULL);
   return SVN_NO_ERROR;
 }
 
@@ -108,7 +106,7 @@ location_segment_receiver(svn_location_s
 dav_error *
 dav_svn__get_location_segments_report(const dav_resource *resource,
                                       const apr_xml_doc *doc,
-                                      ap_filter_t *output)
+                                      dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -216,7 +214,8 @@ dav_svn__get_location_segments_report(co
   arb.repos = resource->info->repos;
 
   /* Build the bucket brigade we'll use for output. */
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   /* Do what we came here for. */
   location_segment_baton.sent_opener = FALSE;

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locations.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locations.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locations.c 
(original)
+++ 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locations.c 
Thu Oct 13 15:25:15 2016
@@ -44,23 +44,20 @@
 #include "../dav_svn.h"
 
 
-static apr_status_t
-send_get_locations_report(ap_filter_t *output,
+static svn_error_t *
+send_get_locations_report(dav_svn__output *output,
                           apr_bucket_brigade *bb,
                           const dav_resource *resource,
                           apr_hash_t *fs_locations)
 {
   apr_hash_index_t *hi;
-  apr_pool_t *pool;
-  apr_status_t apr_err;
+  apr_pool_t *pool = resource->pool;
 
-  pool = resource->pool;
-
-  apr_err = ap_fprintf(output, bb, DAV_XML_HEADER DEBUG_CR
+  SVN_ERR(dav_svn__brigade_printf(
+                       bb, output,
+                       DAV_XML_HEADER DEBUG_CR
                        "<S:get-locations-report xmlns:S=\"" SVN_XML_NAMESPACE
-                       "\" xmlns:D=\"DAV:\">" DEBUG_CR);
-  if (apr_err)
-    return apr_err;
+                       "\" xmlns:D=\"DAV:\">" DEBUG_CR));
 
   for (hi = apr_hash_first(pool, fs_locations); hi; hi = apr_hash_next(hi))
     {
@@ -70,24 +67,25 @@ send_get_locations_report(ap_filter_t *o
 
       apr_hash_this(hi, &key, NULL, &value);
       path_quoted = apr_xml_quote_string(pool, value, 1);
-      apr_err = ap_fprintf(output, bb, "<S:location "
+      SVN_ERR(dav_svn__brigade_printf(
+                           bb, output, "<S:location "
                            "rev=\"%ld\" path=\"%s\"/>" DEBUG_CR,
-                           *(const svn_revnum_t *)key, path_quoted);
-      if (apr_err)
-        return apr_err;
+                           *(const svn_revnum_t *)key, path_quoted));
     }
-  return ap_fprintf(output, bb, "</S:get-locations-report>" DEBUG_CR);
+
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                  "</S:get-locations-report>" DEBUG_CR));
+  return SVN_NO_ERROR;
 }
 
 
 dav_error *
 dav_svn__get_locations_report(const dav_resource *resource,
                               const apr_xml_doc *doc,
-                              ap_filter_t *output)
+                              dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
-  apr_status_t apr_err;
   apr_bucket_brigade *bb;
   dav_svn__authz_read_baton arb;
 
@@ -171,12 +169,13 @@ dav_svn__get_locations_report(const dav_
                                   resource->pool);
     }
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
-  apr_err = send_get_locations_report(output, bb, resource, fs_locations);
+  serr = send_get_locations_report(output, bb, resource, fs_locations);
 
-  if (apr_err)
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  if (serr)
+    derr = dav_svn__convert_err(serr,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locks.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locks.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locks.c 
(original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/reports/get-locks.c 
Thu Oct 13 15:25:15 2016
@@ -44,25 +44,11 @@
    report in libsvn_ra_neon/get_locks.c.  */
 
 
-#define SVN_APR_ERR(expr)                       \
-  do {                                          \
-    apr_status_t apr_status__temp = (expr);     \
-    if (apr_status__temp)                       \
-      return apr_status__temp;                  \
-  } while (0)
-
-
 /* Transmit LOCKS (a hash of Subversion filesystem locks keyed by
-   path) across OUTPUT using BB.  Use POOL for necessary allocations.
-
-   NOTE:  As written, this function currently returns one of only two
-   status values -- "success", and "we had trouble writing out to the
-   output stream".  If you need to return something more interesting,
-   you'll probably want to generate dav_error's here instead of
-   passing back only apr_status_t's.  */
-static apr_status_t
+   path) across OUTPUT using BB.  Use POOL for necessary allocations. */
+static svn_error_t *
 send_get_lock_response(apr_hash_t *locks,
-                       ap_filter_t *output,
+                       dav_svn__output *output,
                        apr_bucket_brigade *bb,
                        apr_pool_t *pool)
 {
@@ -70,7 +56,7 @@ send_get_lock_response(apr_hash_t *locks
   apr_hash_index_t *hi;
 
   /* start sending report */
-  SVN_APR_ERR(ap_fprintf(output, bb,
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
                          DAV_XML_HEADER DEBUG_CR
                          "<S:get-locks-report xmlns:S=\"" SVN_XML_NAMESPACE
                          "\" xmlns:D=\"DAV:\">" DEBUG_CR));
@@ -86,7 +72,7 @@ send_get_lock_response(apr_hash_t *locks
 
       /* Begin the <S:lock> tag, transmitting the path, token, and
          creation date. */
-      SVN_APR_ERR(ap_fprintf(output, bb,
+      SVN_ERR(dav_svn__brigade_printf(bb, output,
                              "<S:lock>" DEBUG_CR
                              "<S:path>%s</S:path>" DEBUG_CR
                              "<S:token>%s</S:token>" DEBUG_CR
@@ -98,7 +84,7 @@ send_get_lock_response(apr_hash_t *locks
 
       /* Got expiration date?  Tell the client. */
       if (lock->expiration_date)
-        SVN_APR_ERR(ap_fprintf(output, bb,
+        SVN_ERR(dav_svn__brigade_printf(bb, output,
                                "<S:expirationdate>%s</S:expirationdate>"
                                DEBUG_CR,
                                svn_time_to_cstring(lock->expiration_date,
@@ -126,7 +112,7 @@ send_get_lock_response(apr_hash_t *locks
               owner = encoded_owner->data;
               owner_base64 = TRUE;
             }
-          SVN_APR_ERR(ap_fprintf(output, bb,
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
                                  "<S:owner %s>%s</S:owner>" DEBUG_CR,
                                  owner_base64 ? "encoding=\"base64\"" : "",
                                  owner));
@@ -154,34 +140,32 @@ send_get_lock_response(apr_hash_t *locks
               comment = encoded_comment->data;
               comment_base64 = TRUE;
             }
-          SVN_APR_ERR(ap_fprintf(output, bb,
+          SVN_ERR(dav_svn__brigade_printf(bb, output,
                                  "<S:comment %s>%s</S:comment>" DEBUG_CR,
                                  comment_base64 ? "encoding=\"base64\"" : "",
                                  comment));
         }
 
       /* Okay, finish up this lock by closing the <S:lock> tag. */
-      SVN_APR_ERR(ap_fprintf(output, bb, "</S:lock>" DEBUG_CR));
+      SVN_ERR(dav_svn__brigade_printf(bb, output, "</S:lock>" DEBUG_CR));
     }
   svn_pool_destroy(iterpool);
 
   /* Finish the report */
-  SVN_APR_ERR(ap_fprintf(output, bb, "</S:get-locks-report>" DEBUG_CR));
+  SVN_ERR(dav_svn__brigade_printf(bb, output,
+                                  "</S:get-locks-report>" DEBUG_CR));
 
   return APR_SUCCESS;
 }
 
-#undef SVN_APR_ERR
-
 dav_error *
 dav_svn__get_locks_report(const dav_resource *resource,
                           const apr_xml_doc *doc,
-                          ap_filter_t *output)
+                          dav_svn__output *output)
 {
   apr_bucket_brigade *bb;
   svn_error_t *err;
   dav_error *derr = NULL;
-  apr_status_t apr_err;
   apr_hash_t *locks;
   dav_svn__authz_read_baton arb;
   svn_depth_t depth = svn_depth_unknown;
@@ -227,10 +211,12 @@ dav_svn__get_locks_report(const dav_reso
     return dav_svn__convert_err(err, HTTP_INTERNAL_SERVER_ERROR,
                                 err->message, resource->pool);
 
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
-  if ((apr_err = send_get_lock_response(locks, output, bb, resource->pool)))
-    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+  err = send_get_lock_response(locks, output, bb, resource->pool);
+  if (err)
+    derr = dav_svn__convert_err(err,
                                 HTTP_INTERNAL_SERVER_ERROR,
                                 "Error writing REPORT response.",
                                 resource->pool);

Modified: 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/inherited-props.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/reports/inherited-props.c?rev=1764707&r1=1764706&r2=1764707&view=diff
==============================================================================
--- 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/inherited-props.c 
(original)
+++ 
subversion/branches/authzperf/subversion/mod_dav_svn/reports/inherited-props.c 
Thu Oct 13 15:25:15 2016
@@ -47,7 +47,7 @@
 dav_error *
 dav_svn__get_inherited_props_report(const dav_resource *resource,
                                     const apr_xml_doc *doc,
-                                    ap_filter_t *output)
+                                    dav_svn__output *output)
 {
   svn_error_t *serr;
   dav_error *derr = NULL;
@@ -106,7 +106,8 @@ dav_svn__get_inherited_props_report(cons
   arb.repos = resource->info->repos;
 
   /* Build inherited property brigade */
-  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+  bb = apr_brigade_create(resource->pool,
+                          dav_svn__output_get_bucket_alloc(output));
 
   serr = svn_fs_revision_root(&root, resource->info->repos->fs,
                               rev, resource->pool);



Reply via email to