You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/04/29 20:38:56 UTC

svn commit: r1741682 [17/26] - in /subversion/branches/authzperf: ./ build/ build/ac-macros/ build/generator/ contrib/server-side/svncutter/ notes/ notes/api-errata/1.9/ notes/move-tracking/ subversion/ subversion/bindings/ctypes-python/ subversion/bin...

Modified: subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/conflicts.c Fri Apr 29 18:38:53 2016
@@ -1351,8 +1351,6 @@ generate_propconflict(svn_boolean_t *con
         }
       case svn_wc_conflict_choose_merged:
         {
-          svn_stringbuf_t *merged_stringbuf;
-
           if (!cdesc->merged_file 
               && (!result->merged_file && !result->merged_value))
             return svn_error_create
@@ -1364,6 +1362,8 @@ generate_propconflict(svn_boolean_t *con
             new_value = result->merged_value;
           else
             {
+              svn_stringbuf_t *merged_stringbuf;
+
               SVN_ERR(svn_stringbuf_from_file2(&merged_stringbuf,
                                                result->merged_file ?
                                                     result->merged_file :
@@ -2472,15 +2472,12 @@ resolve_prop_conflict_on_node(svn_boolea
 
           if (!merged_value)
             {
-              svn_stream_t *stream;
-              svn_string_t *merged_propval;
+              svn_stringbuf_t *merged_propval;
 
-              SVN_ERR(svn_stream_open_readonly(&stream, merged_file,
-                                               scratch_pool, scratch_pool));
-              SVN_ERR(svn_string_from_stream(&merged_propval, stream,
-                                             scratch_pool, scratch_pool));
+              SVN_ERR(svn_stringbuf_from_file2(&merged_propval, merged_file,
+                                               scratch_pool));
 
-              merged_value = merged_propval;
+              merged_value = svn_stringbuf__morph_into_string(merged_propval);
             }
           svn_hash_sets(resolve_from, conflicted_propname, merged_value);
         }
@@ -2696,8 +2693,9 @@ resolve_tree_conflict_on_node(svn_boolea
             {
               svn_skel_t *new_conflicts;
 
-              /* Raise moved-away conflicts on any children moved out of
-               * this directory, and leave this directory as-is.
+              /* Raise local moved-away vs. incoming edit conflicts on
+               * any children moved out of this directory, and leave
+               * this directory as-is.
                *
                * The newly conflicted moved-away children will be updated
                * if they are resolved with 'mine_conflict' as well. */
@@ -2726,7 +2724,7 @@ resolve_tree_conflict_on_node(svn_boolea
               if (!new_conflicts || !tree_conflicted)
                 {
                   /* TC is marked resolved by calling
-                     svn_wc__db_resolve_delete_raise_moved_away */
+                     svn_wc__db_op_raise_moved_away */
                   *did_resolve = TRUE;
                   return SVN_NO_ERROR;
                 }
@@ -2973,12 +2971,13 @@ conflict_status_walker(void *baton,
 {
   struct conflict_status_walker_baton *cswb = baton;
   svn_wc__db_t *db = cswb->db;
-
+  svn_wc_notify_action_t notify_action = svn_wc_notify_resolved;
   const apr_array_header_t *conflicts;
   apr_pool_t *iterpool;
   int i;
   svn_boolean_t resolved = FALSE;
   svn_skel_t *conflict;
+  const svn_wc_conflict_description2_t *cd;
 
   if (!status->conflicted)
     return SVN_NO_ERROR;
@@ -2993,7 +2992,6 @@ conflict_status_walker(void *baton,
 
   for (i = 0; i < conflicts->nelts; i++)
     {
-      const svn_wc_conflict_description2_t *cd;
       svn_boolean_t did_resolve;
       svn_wc_conflict_choice_t my_choice = cswb->conflict_choice;
       svn_wc_conflict_result_t *result = NULL;
@@ -3045,7 +3043,10 @@ conflict_status_walker(void *baton,
                                                   iterpool));
 
             if (did_resolve)
-              resolved = TRUE;
+              {
+                resolved = TRUE;
+                notify_action = svn_wc_notify_resolved_tree;
+              }
             break;
 
           case svn_wc_conflict_kind_text:
@@ -3069,6 +3070,8 @@ conflict_status_walker(void *baton,
             SVN_ERR(svn_wc__wq_run(db, local_abspath,
                                    cswb->cancel_func, cswb->cancel_baton,
                                    iterpool));
+            if (resolved)
+                notify_action = svn_wc_notify_resolved_text;
             break;
 
           case svn_wc_conflict_kind_property:
@@ -3089,7 +3092,10 @@ conflict_status_walker(void *baton,
                                                   iterpool));
 
             if (did_resolve)
-              resolved = TRUE;
+              {
+                resolved = TRUE;
+                notify_action = svn_wc_notify_resolved_prop;
+              }
             break;
 
           default:
@@ -3100,12 +3106,33 @@ conflict_status_walker(void *baton,
 
   /* Notify */
   if (cswb->notify_func && resolved)
-    cswb->notify_func(cswb->notify_baton,
-                      svn_wc_create_notify(local_abspath,
-                                           svn_wc_notify_resolved,
-                                           iterpool),
-                      iterpool);
+    {
+      svn_wc_notify_t *notify;
+
+      /* If our caller asked for all conflicts to be resolved,
+       * send a general 'resolved' notification. */
+      if (cswb->resolve_text && cswb->resolve_tree &&
+          (cswb->resolve_prop == NULL || cswb->resolve_prop[0] == '\0'))
+        notify_action = svn_wc_notify_resolved;
+
+      /* If we resolved a property conflict, but no specific property was
+       * requested by the caller, send a general 'resolved' notification. */
+      if (notify_action == svn_wc_notify_resolved_prop &&
+          (cswb->resolve_prop == NULL || cswb->resolve_prop[0] == '\0'))
+        notify_action = svn_wc_notify_resolved;
+
+      notify = svn_wc_create_notify(local_abspath, notify_action, iterpool);
+
+      /* Add the property name for property-specific notifications. */
+      if (notify_action == svn_wc_notify_resolved_prop)
+        {
+          notify->prop_name = cd->property_name;
+          SVN_ERR_ASSERT(strlen(notify->prop_name) > 0);
+        }
+
+      cswb->notify_func(cswb->notify_baton, notify, iterpool);
 
+    }
   if (resolved)
     cswb->resolved_one = TRUE;
 
@@ -3306,8 +3333,354 @@ svn_wc_create_conflict_result(svn_wc_con
   result->choice = choice;
   result->merged_file = apr_pstrdup(pool, merged_file);
   result->save_merged = FALSE;
+  result->merged_value = NULL;
 
   /* If we add more fields to svn_wc_conflict_result_t, add them here. */
 
   return result;
 }
+
+svn_error_t *
+svn_wc__conflict_text_mark_resolved(svn_wc_context_t *wc_ctx,
+                                    const char *local_abspath,
+                                    svn_wc_conflict_choice_t choice,
+                                    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_skel_t *work_items;
+  svn_skel_t *conflict;
+  svn_boolean_t did_resolve;
+
+  SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
+                                   wc_ctx->db, local_abspath,
+                                   scratch_pool, scratch_pool));
+
+  if (!conflict)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(build_text_conflict_resolve_items(&work_items, &did_resolve,
+                                            wc_ctx->db, local_abspath,
+                                            conflict, choice,
+                                            NULL, FALSE, NULL,
+                                            cancel_func, cancel_baton,
+                                            scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__db_op_mark_resolved(wc_ctx->db, local_abspath,
+                                      TRUE, FALSE, FALSE,
+                                      work_items, scratch_pool));
+
+  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
+                         cancel_func, cancel_baton,
+                         scratch_pool));
+
+  if (did_resolve && notify_func)
+    notify_func(notify_baton,
+                svn_wc_create_notify(local_abspath,
+                                     svn_wc_notify_resolved_text,
+                                     scratch_pool),
+                scratch_pool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__conflict_prop_mark_resolved(svn_wc_context_t *wc_ctx,
+                                    const char *local_abspath,
+                                    const char *propname,
+                                    svn_wc_conflict_choice_t choice,
+                                    svn_wc_notify_func2_t notify_func,
+                                    void *notify_baton,
+                                    apr_pool_t *scratch_pool)
+{
+  svn_boolean_t did_resolve;
+  svn_skel_t *conflicts;
+
+  SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL,
+                                   wc_ctx->db, local_abspath,
+                                   scratch_pool, scratch_pool));
+
+  if (!conflicts)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(resolve_prop_conflict_on_node(&did_resolve, wc_ctx->db,
+                                        local_abspath, conflicts,
+                                        propname, choice, NULL, NULL,
+                                        NULL, NULL, scratch_pool));
+
+  if (did_resolve && notify_func)
+    {
+      svn_wc_notify_t *notify;
+
+      /* Send a general notification if no specific property was requested. */
+      if (propname == NULL || propname[0] == '\0')
+        {
+          notify = svn_wc_create_notify(local_abspath,
+                                        svn_wc_notify_resolved,
+                                        scratch_pool);
+        }
+      else
+        {
+          notify = svn_wc_create_notify(local_abspath,
+                                        svn_wc_notify_resolved_prop,
+                                        scratch_pool);
+          notify->prop_name = propname;
+        }
+
+      notify_func(notify_baton, notify, scratch_pool);
+    }
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__conflict_tree_update_break_moved_away(svn_wc_context_t *wc_ctx,
+                                              const char *local_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 reason;
+  svn_wc_conflict_action_t action;
+  svn_wc_operation_t operation;
+  svn_boolean_t tree_conflicted;
+  const char *src_op_root_abspath;
+  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(&reason, &action,
+                                              &src_op_root_abspath,
+                                              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)
+    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 (reason != svn_wc_conflict_reason_deleted &&
+      reason != svn_wc_conflict_reason_replaced &&
+      reason != svn_wc_conflict_reason_moved_away)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict reason '%s' on '%s'"),
+                             svn_token__to_word(reason_map, reason),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  /* Break moves for any children moved out of this directory,
+   * and leave this directory deleted. */
+  if (action != svn_wc_conflict_action_delete)
+    {
+      SVN_ERR(svn_wc__db_op_break_moved_away(
+                      wc_ctx->db, local_abspath, src_op_root_abspath, TRUE,
+                      notify_func, notify_baton, scratch_pool));
+      /* Conflict was marked resolved by db_op_break_moved_away() call .*/
+
+      if (notify_func)
+        notify_func(notify_baton,
+                    svn_wc_create_notify(local_abspath,
+                                         svn_wc_notify_resolved_tree,
+                                         scratch_pool),
+                    scratch_pool);
+      return SVN_NO_ERROR;
+    }
+  /* else # The move is/moves are already broken */
+
+  SVN_ERR(svn_wc__db_op_mark_resolved(wc_ctx->db, local_abspath,
+                                      FALSE, FALSE, TRUE,
+                                      NULL, scratch_pool));
+  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, cancel_func, cancel_baton,
+                         scratch_pool));
+
+  if (notify_func)
+    notify_func(notify_baton,
+                svn_wc_create_notify(local_abspath,
+                                     svn_wc_notify_resolved_tree,
+                                     scratch_pool),
+                scratch_pool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__conflict_tree_update_raise_moved_away(svn_wc_context_t *wc_ctx,
+                                              const char *local_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 reason;
+  svn_wc_conflict_action_t action;
+  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(&reason, &action, 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)
+    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 (reason != svn_wc_conflict_reason_deleted &&
+      reason != svn_wc_conflict_reason_replaced)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict reason '%s' on '%s'"),
+                             svn_token__to_word(reason_map, reason),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+  if (action != svn_wc_conflict_action_edit)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict action '%s' on '%s'"),
+                             svn_token__to_word(action_map, action),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  /* Raise local moved-away vs. incoming edit conflicts on any children
+   * moved out of this directory, and leave this directory as-is.
+   * The user may choose to update newly conflicted moved-away children
+   * when resolving them. If this function raises an error, the conflict
+   * cannot be resolved yet because other conflicts or obstructions
+   * prevent us from propagating the conflict to moved-away children. */
+  SVN_ERR(svn_wc__db_op_raise_moved_away(wc_ctx->db, local_abspath,
+                                         notify_func, notify_baton,
+                                         scratch_pool));
+
+  /* The conflict was marked resolved by svn_wc__db_op_raise_moved_away(). */
+  if (notify_func)
+    notify_func(notify_baton,
+                svn_wc_create_notify(local_abspath,
+                                     svn_wc_notify_resolved_tree,
+                                     scratch_pool),
+                scratch_pool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__conflict_tree_update_moved_away_node(svn_wc_context_t *wc_ctx,
+                                             const char *local_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 reason;
+  svn_wc_conflict_action_t action;
+  svn_wc_operation_t operation;
+  svn_boolean_t tree_conflicted;
+  const char *src_op_root_abspath;
+  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(&reason, &action,
+                                              &src_op_root_abspath,
+                                              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)
+    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 (reason != svn_wc_conflict_reason_moved_away)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict reason '%s' on '%s'"),
+                             svn_token__to_word(reason_map, reason),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+  if (action != svn_wc_conflict_action_edit)
+    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                             _("Unexpected conflict action '%s' on '%s'"),
+                             svn_token__to_word(action_map, action),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  /* Update the moved-away conflict victim. */
+  SVN_ERR(svn_wc__db_update_moved_away_conflict_victim(wc_ctx->db,
+                                                       local_abspath,
+                                                       src_op_root_abspath,
+                                                       operation,
+                                                       action,
+                                                       reason,
+                                                       cancel_func,
+                                                       cancel_baton,
+                                                       notify_func,
+                                                       notify_baton,
+                                                       scratch_pool));
+
+  SVN_ERR(svn_wc__db_op_mark_resolved(wc_ctx->db, local_abspath,
+                                      FALSE, FALSE, TRUE,
+                                      NULL, scratch_pool));
+  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, cancel_func, cancel_baton,
+                         scratch_pool));
+
+  if (notify_func)
+    notify_func(notify_baton,
+                svn_wc_create_notify(local_abspath,
+                                     svn_wc_notify_resolved_tree,
+                                     scratch_pool),
+                scratch_pool);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c Fri Apr 29 18:38:53 2016
@@ -2051,7 +2051,7 @@ svn_wc_get_diff_editor6(const svn_delta_
                             wc_ctx,
                             anchor_abspath, target,
                             depth,
-                            use_git_diff_format, use_text_base,
+                            ignore_ancestry, use_text_base,
                             reverse_order, server_performs_filtering,
                             changelist_filter,
                             diff_processor,

Modified: subversion/branches/authzperf/subversion/libsvn_wc/diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/diff.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/diff.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/diff.h Fri Apr 29 18:38:53 2016
@@ -52,6 +52,7 @@ svn_error_t *
 svn_wc__diff_local_only_file(svn_wc__db_t *db,
                              const char *local_abspath,
                              const char *relpath,
+                             const char *moved_from_relpath,
                              const svn_diff_tree_processor_t *processor,
                              void *processor_parent_baton,
                              svn_boolean_t diff_pristine,
@@ -75,6 +76,7 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
                             const char *local_abspath,
                             const char *relpath,
                             svn_depth_t depth,
+                            const char *moved_from_relpath,
                             const svn_diff_tree_processor_t *processor,
                             void *processor_parent_baton,
                             svn_boolean_t diff_pristine,

Modified: subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/diff_editor.c Fri Apr 29 18:38:53 2016
@@ -744,9 +744,29 @@ walk_local_nodes_diff(struct edit_baton_
 
           if (eb->local_before_remote && local_only)
             {
+              const char *moved_from_relpath;
+
+              if (info->moved_here)
+                {
+                  const char *moved_from_abspath;
+
+                  SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath,
+                                                NULL, NULL, NULL,
+                                                db, child_abspath,
+                                                iterpool, iterpool));
+                  SVN_ERR_ASSERT(moved_from_abspath != NULL);
+
+                  moved_from_relpath = svn_dirent_skip_ancestor(
+                                                        eb->anchor_abspath,
+                                                        moved_from_abspath);
+                }
+              else
+                moved_from_relpath = NULL;
+
               if (info->kind == svn_node_file && diff_files)
                 SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
                                                      child_relpath,
+                                                     moved_from_relpath,
                                                      eb->processor, dir_baton,
                                                      eb->diff_pristine,
                                                      eb->cancel_func,
@@ -756,6 +776,7 @@ walk_local_nodes_diff(struct edit_baton_
                 SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath,
                                                     child_relpath,
                                                     depth_below_here,
+                                                    moved_from_relpath,
                                                     eb->processor, dir_baton,
                                                     eb->diff_pristine,
                                                     eb->cancel_func,
@@ -810,9 +831,29 @@ walk_local_nodes_diff(struct edit_baton_
 
           if (!eb->local_before_remote && local_only)
             {
+              const char *moved_from_relpath;
+
+              if (info->moved_here)
+                {
+                  const char *moved_from_abspath;
+
+                  SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath,
+                                                NULL, NULL, NULL,
+                                                db, child_abspath,
+                                                iterpool, iterpool));
+                  SVN_ERR_ASSERT(moved_from_abspath != NULL);
+
+                  moved_from_relpath = svn_dirent_skip_ancestor(
+                                                        eb->anchor_abspath,
+                                                        moved_from_abspath);
+                }
+              else
+                moved_from_relpath = NULL;
+
               if (info->kind == svn_node_file && diff_files)
                 SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
                                                      child_relpath,
+                                                     moved_from_relpath,
                                                      eb->processor, dir_baton,
                                                      eb->diff_pristine,
                                                      eb->cancel_func,
@@ -820,12 +861,13 @@ walk_local_nodes_diff(struct edit_baton_
                                                      iterpool));
               else if (info->kind == svn_node_dir && diff_dirs)
                 SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath,
-                                                     child_relpath, depth_below_here,
-                                                     eb->processor, dir_baton,
-                                                     eb->diff_pristine,
-                                                     eb->cancel_func,
-                                                     eb->cancel_baton,
-                                                     iterpool));
+                                                    child_relpath, depth_below_here,
+                                                    moved_from_relpath,
+                                                    eb->processor, dir_baton,
+                                                    eb->diff_pristine,
+                                                    eb->cancel_func,
+                                                    eb->cancel_baton,
+                                                    iterpool));
             }
         }
     }
@@ -876,6 +918,7 @@ svn_error_t *
 svn_wc__diff_local_only_file(svn_wc__db_t *db,
                              const char *local_abspath,
                              const char *relpath,
+                             const char *moved_from_relpath,
                              const svn_diff_tree_processor_t *processor,
                              void *processor_parent_baton,
                              svn_boolean_t diff_pristine,
@@ -938,6 +981,7 @@ svn_wc__diff_local_only_file(svn_wc__db_
     {
       copyfrom_src = svn_diff__source_create(original_revision, scratch_pool);
       copyfrom_src->repos_relpath = original_repos_relpath;
+      copyfrom_src->moved_from_relpath = moved_from_relpath;
     }
 
   if (props_mod || !SVN_IS_VALID_REVNUM(revision))
@@ -1016,6 +1060,7 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
                             const char *local_abspath,
                             const char *relpath,
                             svn_depth_t depth,
+                            const char *moved_from_relpath,
                             const svn_diff_tree_processor_t *processor,
                             void *processor_parent_baton,
                             svn_boolean_t diff_pristine,
@@ -1052,6 +1097,7 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
     {
       copyfrom_src = svn_diff__source_create(original_revision, scratch_pool);
       copyfrom_src->repos_relpath = original_repos_relpath;
+      copyfrom_src->moved_from_relpath = moved_from_relpath;
     }
 
   /* svn_wc__db_status_incomplete should never happen, as the result won't be
@@ -1139,12 +1185,40 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
 
           child_relpath = svn_relpath_join(relpath, name, iterpool);
 
+          if (info->moved_here)
+            {
+              const char *moved_from_abspath;
+              const char *a_abspath;
+              const char *a_relpath;
+
+              a_relpath = relpath;
+              a_abspath = local_abspath;
+              while (*a_relpath)
+                {
+                  a_relpath = svn_relpath_dirname(a_relpath, iterpool);
+                  a_abspath = svn_dirent_dirname(a_abspath, iterpool);
+                }
+
+              SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath,
+                                            NULL, NULL, NULL,
+                                            db, child_abspath,
+                                            iterpool, iterpool));
+              SVN_ERR_ASSERT(moved_from_abspath != NULL);
+
+              moved_from_relpath = svn_dirent_skip_ancestor(
+                                                        a_abspath,
+                                                        moved_from_abspath);
+            }
+          else
+            moved_from_relpath = NULL;
+
           switch (info->kind)
             {
             case svn_node_file:
             case svn_node_symlink:
               SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
                                                    child_relpath,
+                                                   moved_from_relpath,
                                                    processor, pdb,
                                                    diff_pristine,
                                                    cancel_func, cancel_baton,
@@ -1157,6 +1231,7 @@ svn_wc__diff_local_only_dir(svn_wc__db_t
                   SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath,
                                                       child_relpath,
                                                       depth_below_here,
+                                                      moved_from_relpath,
                                                       processor, pdb,
                                                       diff_pristine,
                                                       cancel_func,
@@ -1205,6 +1280,8 @@ handle_local_only(struct dir_baton_t *pb
 {
   struct edit_baton_t *eb = pb->eb;
   const struct svn_wc__db_info_t *info;
+  const char *child_abspath;
+  const char *moved_from_relpath;
   svn_boolean_t repos_delete = (pb->deletes
                                 && svn_hash_gets(pb->deletes, name));
 
@@ -1240,6 +1317,25 @@ handle_local_only(struct dir_baton_t *pb
         break;
     }
 
+  child_abspath = svn_dirent_join(pb->local_abspath, name, scratch_pool);
+
+  if (info->moved_here)
+    {
+      const char *moved_from_abspath;
+
+      SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath,
+                                    NULL, NULL, NULL,
+                                    eb->db, child_abspath,
+                                    scratch_pool, scratch_pool));
+      SVN_ERR_ASSERT(moved_from_abspath != NULL);
+
+      moved_from_relpath = svn_dirent_skip_ancestor(
+                                    eb->anchor_abspath,
+                                    moved_from_abspath);
+    }
+  else
+    moved_from_relpath = NULL;
+
   if (info->kind == svn_node_dir)
     {
       svn_depth_t depth ;
@@ -1251,9 +1347,10 @@ handle_local_only(struct dir_baton_t *pb
 
       SVN_ERR(svn_wc__diff_local_only_dir(
                       eb->db,
-                      svn_dirent_join(pb->local_abspath, name, scratch_pool),
+                      child_abspath,
                       svn_relpath_join(pb->relpath, name, scratch_pool),
                       repos_delete ? svn_depth_infinity : depth,
+                      moved_from_relpath,
                       eb->processor, pb->pdb,
                       eb->diff_pristine,
                       eb->cancel_func, eb->cancel_baton,
@@ -1262,8 +1359,9 @@ handle_local_only(struct dir_baton_t *pb
   else
     SVN_ERR(svn_wc__diff_local_only_file(
                       eb->db,
-                      svn_dirent_join(pb->local_abspath, name, scratch_pool),
+                      child_abspath,
                       svn_relpath_join(pb->relpath, name, scratch_pool),
+                      moved_from_relpath,
                       eb->processor, pb->pdb,
                       eb->diff_pristine,
                       eb->cancel_func, eb->cancel_baton,

Modified: subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/diff_local.c Fri Apr 29 18:38:53 2016
@@ -391,9 +391,20 @@ diff_status_callback(void *baton,
 
     if (local_only && (db_status != svn_wc__db_status_deleted))
       {
+        /* Moved from. Relative from diff anchor*/
+        const char *moved_from_relpath = NULL;
+
+        if (status->moved_from_abspath)
+          {
+            moved_from_relpath = svn_dirent_skip_ancestor(
+                                          eb->anchor_abspath,
+                                          status->moved_from_abspath);
+          }
+
         if (db_kind == svn_node_file)
           SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
                                                child_relpath,
+                                               moved_from_relpath,
                                                eb->processor,
                                                eb->cur ? eb->cur->baton : NULL,
                                                FALSE,
@@ -403,6 +414,7 @@ diff_status_callback(void *baton,
         else if (db_kind == svn_node_dir)
           SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath,
                                               child_relpath, depth_below_here,
+                                              moved_from_relpath,
                                               eb->processor,
                                               eb->cur ? eb->cur->baton : NULL,
                                               FALSE,

Modified: subversion/branches/authzperf/subversion/libsvn_wc/old-and-busted.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/old-and-busted.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/old-and-busted.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/old-and-busted.c Fri Apr 29 18:38:53 2016
@@ -1203,7 +1203,8 @@ svn_wc__read_entries_old(apr_hash_t **en
   /* Open the entries file. */
   SVN_ERR(svn_wc__open_adm_stream(&stream, dir_abspath, SVN_WC__ADM_ENTRIES,
                                   scratch_pool, scratch_pool));
-  SVN_ERR(svn_string_from_stream(&buf, stream, scratch_pool, scratch_pool));
+  SVN_ERR(svn_string_from_stream2(&buf, stream, SVN__STREAM_CHUNK_SIZE,
+                                  scratch_pool));
 
   /* We own the returned data; it is modifiable, so cast away... */
   curp = (char *)buf->data;

Modified: subversion/branches/authzperf/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/props.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/props.c Fri Apr 29 18:38:53 2016
@@ -2170,11 +2170,8 @@ svn_wc_canonicalize_svn_prop(const svn_s
 
   /* Keep this static, it may get stored (for read-only purposes) in a
      hash that outlives this function. */
-  static const svn_string_t boolean_value =
-    {
-      SVN_PROP_BOOLEAN_TRUE,
-      sizeof(SVN_PROP_BOOLEAN_TRUE) - 1
-    };
+  static const svn_string_t boolean_value
+    = SVN__STATIC_STRING(SVN_PROP_BOOLEAN_TRUE);
 
   SVN_ERR(validate_prop_against_node_kind(propname, path, kind, pool));
 

Modified: subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/update_editor.c Fri Apr 29 18:38:53 2016
@@ -2883,10 +2883,7 @@ absent_node(const char *path,
   if (pb->skip_this)
     return SVN_NO_ERROR;
 
-  SVN_ERR(mark_directory_edited(pb, scratch_pool));
-
   local_abspath = svn_dirent_join(pb->local_abspath, name, scratch_pool);
-
   /* If an item by this name is scheduled for addition that's a
      genuine tree-conflict.  */
   err = svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
@@ -2906,6 +2903,10 @@ absent_node(const char *path,
       kind = svn_node_unknown;
     }
 
+  if (status != svn_wc__db_status_server_excluded)
+    SVN_ERR(mark_directory_edited(pb, scratch_pool));
+  /* Else fall through as we should update the revision anyway */
+
   if (status == svn_wc__db_status_normal)
     {
       svn_boolean_t wcroot;
@@ -2929,31 +2930,53 @@ absent_node(const char *path,
         }
       else
         {
-          /* The server asks us to replace a file external
-             (Existing BASE node; not reported by the working copy crawler or
-              there would have been a delete_entry() call.
-
-             There is no way we can store this state in the working copy as
-             the BASE layer is already filled.
-
-             We could error out, but that is not helping anybody; the user is not
-             even seeing with what the file external would be replaced, so let's
-             report a skip and continue the update.
-           */
+          svn_boolean_t file_external;
+          svn_revnum_t revnum;
 
-          if (eb->notify_func)
+          SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &revnum, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL, NULL,
+                                           &file_external,
+                                           eb->db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+          if (file_external)
             {
-              svn_wc_notify_t *notify;
-              notify = svn_wc_create_notify(
+              /* The server asks us to replace a file external
+                 (Existing BASE node; not reported by the working copy crawler
+                  or there would have been a delete_entry() call.
+
+                 There is no way we can store this state in the working copy as
+                 the BASE layer is already filled.
+                 We could error out, but that is not helping anybody; the user is not
+                 even seeing with what the file external would be replaced, so let's
+                 report a skip and continue the update.
+               */
+
+              if (eb->notify_func)
+                {
+                  svn_wc_notify_t *notify;
+                  notify = svn_wc_create_notify(
                                     local_abspath,
                                     svn_wc_notify_update_skip_obstruction,
                                     scratch_pool);
 
-              eb->notify_func(eb->notify_baton, notify, scratch_pool);
+                  eb->notify_func(eb->notify_baton, notify, scratch_pool);
+                }
+
+              svn_pool_destroy(scratch_pool);
+              return SVN_NO_ERROR;
             }
+          else
+            {
+              /* We have a normal local node that will now be hidden for the
+                 user. Let's try to delete what is there. This may introduce
+                 tree conflicts if there are local changes */
+              SVN_ERR(delete_entry(path, revnum, pb, scratch_pool));
 
-          svn_pool_destroy(scratch_pool);
-          return SVN_NO_ERROR;
+              /* delete_entry() promises that BASE is empty after the operation,
+                 so we can just fall through now */
+            }
         }
     }
   else if (status == svn_wc__db_status_not_present

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=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc-queries.sql Fri Apr 29 18:38:53 2016
@@ -1286,7 +1286,10 @@ WHERE (wc_id = ?1 AND local_relpath = ?2
    OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_PRAGMA_LOCKING_MODE
-PRAGMA locking_mode = exclusive
+PRAGMA locking_mode = exclusive;
+/* Testing shows DELETE is faster than TRUNCATE on NFS and
+   exclusive-locking is mostly used on remote file systems. */
+PRAGMA journal_mode = DELETE
 
 /* ------------------------------------------------------------------------- */
 
@@ -1744,13 +1747,6 @@ WHERE wc_id = ?1
 
 /* Queries for cached inherited properties. */
 
-/* Select the inherited properties of a single base node. */
--- STMT_SELECT_IPROPS
-SELECT inherited_props FROM nodes
-WHERE wc_id = ?1
-  AND local_relpath = ?2
-  AND op_depth = 0
-
 /* Update the inherited properties of a single base node. */
 -- STMT_UPDATE_IPROP
 UPDATE nodes

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=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db.c Fri Apr 29 18:38:53 2016
@@ -10618,68 +10618,6 @@ svn_wc__db_prop_retrieve_recursive(apr_h
   return svn_error_trace(svn_sqlite__reset(stmt));
 }
 
-/* The body of svn_wc__db_read_cached_iprops(). */
-static svn_error_t *
-db_read_cached_iprops(apr_array_header_t **iprops,
-                      svn_wc__db_wcroot_t *wcroot,
-                      const char *local_relpath,
-                      apr_pool_t *result_pool,
-                      apr_pool_t *scratch_pool)
-{
-  svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_IPROPS));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  if (!have_row)
-    {
-      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
-                               svn_sqlite__reset(stmt),
-                               _("The node '%s' was not found."),
-                               path_for_error_message(wcroot, local_relpath,
-                                                      scratch_pool));
-    }
-
-  SVN_ERR(svn_sqlite__column_iprops(iprops, stmt, 0,
-                                    result_pool, scratch_pool));
-
-  SVN_ERR(svn_sqlite__reset(stmt));
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__db_read_cached_iprops(apr_array_header_t **iprops,
-                              svn_wc__db_t *db,
-                              const char *local_abspath,
-                              apr_pool_t *result_pool,
-                              apr_pool_t *scratch_pool)
-{
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
-                                                db, local_abspath,
-                                                scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
-
-  /* Don't use with_txn yet, as we perform just a single transaction */
-  SVN_ERR(db_read_cached_iprops(iprops, wcroot, local_relpath,
-                                result_pool, scratch_pool));
-
-  if (!*iprops)
-    {
-      *iprops = apr_array_make(result_pool, 0,
-                               sizeof(svn_prop_inherited_item_t *));
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* Remove all prop name value pairs from PROP_HASH where the property
    name is not PROPNAME. */
 static void
@@ -11402,7 +11340,9 @@ relocate_txn(svn_wc__db_wcroot_t *wcroot
 
   SVN_ERR(svn_wc__db_fetch_repos_info(NULL, &repos_uuid, wcroot,
                                       old_repos_id, scratch_pool));
-  SVN_ERR_ASSERT(repos_uuid);  /* This function affects all the children of the given local_relpath,
+  SVN_ERR_ASSERT(repos_uuid);
+
+  /* This function affects all the children of the given local_relpath,
      but the way that it does this is through the repos inheritance mechanism.
      So, we only need to rewrite the repos_id of the given local_relpath,
      as well as any children with a non-null repos_id, as well as various
@@ -11429,6 +11369,11 @@ relocate_txn(svn_wc__db_wcroot_t *wcroot
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
+  /* ### TODO: Update urls stored in inherited properties...
+               What about urls in conflicts?
+                 # We can probably keep these as they are only used
+                   for showing full urls to the user */
+
   return SVN_NO_ERROR;
 }
 

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=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_wc/wc_db.h Fri Apr 29 18:38:53 2016
@@ -3438,7 +3438,7 @@ svn_wc__db_op_raise_moved_away(svn_wc__d
                                apr_pool_t *scratch_pool);
 
 /* Breaks all moves of nodes that exist at or below LOCAL_ABSPATH as
-   shadowed (read: deleted) by the opration rooted at
+   shadowed (read: deleted) by the operation rooted at
    delete_op_root_abspath.
  */
 svn_error_t *

Modified: subversion/branches/authzperf/subversion/mod_authz_svn/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_authz_svn/INSTALL?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_authz_svn/INSTALL (original)
+++ subversion/branches/authzperf/subversion/mod_authz_svn/INSTALL Fri Apr 29 18:38:53 2016
@@ -186,10 +186,16 @@ II.   Configuration
          The "Require" statement in the previous example is not strictly
          needed, but has been included for clarity.
 
-      H. Example 8: Separate authz and groups files.
+      H. Example 8: Separating groups and authorization rules
 
-         This configuration allows storing the groups separately from the
-         main authz file with the authorization rules.
+         It may be convenient to maintain group definitions separately from
+         the authorization rules.  This configuration allows splitting them
+         into two separate files.
+
+         The file specified by the AuthzSVNGroupsFile directive uses the
+         same format as the ordinary authz file and should contain a single
+         section with the group definitions.  See section II.2.B for more
+         details.
 
          <Location /svn>
            DAV svn
@@ -205,78 +211,106 @@ II.   Configuration
            Require valid-user
          </Location>
 
+         Configurations with per-repository access files may also use a
+         single file containing the group definitions.  This configuration
+         avoids the need to duplicate the group definitions across multiple
+         per-repository access files.
+
+           AuthzSVNReposRelativeAccessFile filename
+           AuthzSVNGroupsFile /path/to/groups/file
+
+         NOTE: When the AuthzSVNGroupsFile directive is enabled, the
+         file specified with the AuthzSVNReposRelativeAccessFile or
+         AuthzSVNAccessFile directive cannot contain any group definitions.
+
    2. Specifying permissions
 
-      The file format of the access file looks like this:
+      A. File format of the access file
 
-        [groups]
-        <groupname> = <user>[,<user>...]
-        ...
-
-        [<path in repository>]
-        @<group> = [rw|r]
-        <user> = [rw|r]
-        * = [rw|r]
-
-        [<repository name>:<path in repository>]
-        @<group> = [rw|r]
-        <user> = [rw|r]
-        * = [rw|r]
-
-      An example (line continued lines are supposed to be on one line):
-
-        [groups]
-        subversion = jimb,sussman,kfogel,gstein,brane,joe,ghudson,fitz, \
-                     daniel,cmpilato,kevin,philip,jerenkrantz,rooneg, \
-                     bcollins,blair,striker,naked,dwhedon,dlr,kraai,mbk, \
-                     epg,bdenny,jaa
-        subversion-doc = nsd,zbrown,fmatias,dimentiy,patrick
-        subversion-bindings = xela,yoshiki,morten,jespersm,knacke
-        subversion-rm = mprice
-        ...and so on and so on...
-
-        [/]
-        # Allow everyone read on the entire repository
-        * = r
-        # Allow devs with blanket commit to write to the entire repository
-        @subversion = rw
-
-        [/trunk/doc]
-        @subversion-doc = rw
-
-        [/trunk/subversion/bindings]
-        @subversion-bindings = rw
-
-        [/branches]
-        @subversion-rm = rw
-
-        [/tags]
-        @subversion-rm = rw
-
-        [/branches/issue-650-ssl-certs]
-        mass = rw
-
-        [/branches/pluggable-db]
-        gthompson = rw
-
-        ...
-
-        [/secrets]
-        # Just for demonstration
-        * =
-        @subversion = rw
-
-        # In case of SVNParentPath we can specify which repository we are
-        # referring to.  If no matching repository qualified section is found,
-        # the general unqualified section is tried.
-        #
-        # NOTE: This will work in the case of using SVNPath as well, only the
-        # repository name (the last element of the url) will always be the
-        # same.
-        [dark:/]
-        * =
-        @dark = rw
+         The file format of the access file looks like this:
 
-        [light:/]
-        @light = rw
+           [groups]
+           <groupname> = <user>[,<user>...]
+           ...
+
+           [<path in repository>]
+           @<group> = [rw|r]
+           <user> = [rw|r]
+           * = [rw|r]
+
+           [<repository name>:<path in repository>]
+           @<group> = [rw|r]
+           <user> = [rw|r]
+           * = [rw|r]
+
+         An example (line continued lines are supposed to be on one line):
+
+           [groups]
+           subversion = jimb,sussman,kfogel,gstein,brane,joe,ghudson,fitz, \
+                        daniel,cmpilato,kevin,philip,jerenkrantz,rooneg, \
+                        bcollins,blair,striker,naked,dwhedon,dlr,kraai,mbk, \
+                        epg,bdenny,jaa
+           subversion-doc = nsd,zbrown,fmatias,dimentiy,patrick
+           subversion-bindings = xela,yoshiki,morten,jespersm,knacke
+           subversion-rm = mprice
+           ...and so on and so on...
+
+           [/]
+           # Allow everyone read on the entire repository
+           * = r
+           # Allow devs with blanket commit to write to the entire repository
+           @subversion = rw
+
+           [/trunk/doc]
+           @subversion-doc = rw
+
+           [/trunk/subversion/bindings]
+           @subversion-bindings = rw
+
+           [/branches]
+           @subversion-rm = rw
+
+           [/tags]
+           @subversion-rm = rw
+
+           [/branches/issue-650-ssl-certs]
+           mass = rw
+
+           [/branches/pluggable-db]
+           gthompson = rw
+
+           ...
+
+           [/secrets]
+           # Just for demonstration
+           * =
+           @subversion = rw
+
+           # In case of SVNParentPath we can specify which repository we are
+           # referring to.  If no matching repository qualified section is
+           # found, the general unqualified section is tried.
+           #
+           # NOTE: This will work in the case of using SVNPath as well, only
+           # the repository name (the last element of the url) will always be
+           # the same.
+           [dark:/]
+           * =
+           @dark = rw
+
+           [light:/]
+           @light = rw
+
+      B. File format of the groups file
+
+         The file format of the groups file looks like this:
+
+           [groups]
+           <groupname> = <user>[,<user>...]
+           ...
+
+         An example:
+
+           [groups]
+           developers = harry,sally,john
+           managers = jim,joe
 

Modified: subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/authzperf/subversion/mod_authz_svn/mod_authz_svn.c Fri Apr 29 18:38:53 2016
@@ -639,6 +639,8 @@ req_check_access(request_rec *r,
 
   if (r->method_number == M_MOVE || r->method_number == M_COPY)
     {
+      apr_status_t status;
+
       dest_uri = apr_table_get(r->headers_in, "Destination");
 
       /* Decline MOVE or COPY when there is no Destination uri, this will
@@ -647,7 +649,19 @@ req_check_access(request_rec *r,
       if (!dest_uri)
         return DECLINED;
 
-      apr_uri_parse(r->pool, dest_uri, &parsed_dest_uri);
+      status = apr_uri_parse(r->pool, dest_uri, &parsed_dest_uri);
+      if (status)
+        {
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
+                        "Invalid URI in Destination header");
+          return HTTP_BAD_REQUEST;
+        }
+      if (!parsed_dest_uri.path)
+        {
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                        "Invalid URI in Destination header");
+          return HTTP_BAD_REQUEST;
+        }
 
       ap_unescape_url(parsed_dest_uri.path);
       dest_uri = parsed_dest_uri.path;
@@ -954,19 +968,21 @@ access_checker(request_rec *r)
 #if USE_FORCE_AUTHN
       if (authn_configured) {
           /* We have to check to see if authn is required because if so we must
-           * return UNAUTHORIZED (401) rather than FORBIDDEN (403) since returning
+           * return DECLINED rather than FORBIDDEN (403) since returning
            * the 403 leaks information about what paths may exist to
-           * unauthenticated users.  We must set a note here in order
-           * to use ap_some_authn_rquired() without triggering an infinite
-           * loop since the call will trigger this function to be called again. */
+           * unauthenticated users.  Returning DECLINED means apache's request
+           * handling will continue until the authn module itself generates
+           * UNAUTHORIZED (401).
+
+           * We must set a note here in order to use
+           * ap_some_authn_rquired() without triggering an infinite
+           * loop since the call will trigger this function to be
+           * called again. */
           apr_table_setn(r->notes, IN_SOME_AUTHN_NOTE, (const char*)1);
           authn_required = ap_some_authn_required(r);
           apr_table_unset(r->notes, IN_SOME_AUTHN_NOTE);
           if (authn_required)
-            {
-              ap_note_auth_failure(r);
-              return HTTP_UNAUTHORIZED;
-            }
+            return DECLINED;
       }
 #else
       if (!authn_required)

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/activity.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/activity.c Fri Apr 29 18:38:53 2016
@@ -227,7 +227,7 @@ dav_svn__store_activity(const dav_svn_re
 
 
 dav_error *
-dav_svn__create_txn(const dav_svn_repos *repos,
+dav_svn__create_txn(dav_svn_repos *repos,
                     const char **ptxn_name,
                     apr_hash_t *revprops,
                     apr_pool_t *pool)
@@ -248,7 +248,7 @@ dav_svn__create_txn(const dav_svn_repos
                     svn_string_create(repos->username, pool));
     }
 
-  serr = svn_fs_youngest_rev(&rev, repos->fs, pool);
+  serr = dav_svn__get_youngest_rev(&rev, repos, pool);
   if (serr != NULL)
     {
       return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,

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=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/dav_svn.h Fri Apr 29 18:38:53 2016
@@ -149,6 +149,9 @@ typedef struct dav_svn_repos {
   /* The path to the activities db */
   const char *activities_db;
 
+  /* Cached yongest revision of the repository. SVN_INVALID_REVNUM if
+     youngest revision is not fetched yet. */
+  svn_revnum_t youngest_rev;
 } dav_svn_repos;
 
 
@@ -296,6 +299,10 @@ struct dav_resource_private {
   /* was keyword substitution requested using our public CGI interface
      (ie: /path/to/item?kw=1)? */
   svn_boolean_t keyword_subst;
+
+  /* whether this resource parameters are fixed and won't change
+     between requests. */
+  svn_boolean_t idempotent;
 };
 
 
@@ -329,6 +336,10 @@ svn_boolean_t dav_svn__get_fulltext_cach
 /* for the repository referred to by this request, is revprop caching active? */
 svn_boolean_t dav_svn__get_revprop_cache_flag(request_rec *r);
 
+/* for the repository referred to by this request, is node prop caching active? */
+svn_boolean_t
+dav_svn__get_nodeprop_cache_flag(request_rec *r);
+
 /* has block read mode been enabled for the repository referred to by this
  * request? */
 svn_boolean_t dav_svn__get_block_read_flag(request_rec *r);
@@ -458,7 +469,7 @@ const char *dav_svn__get_vtxn_root_stub(
    NOTE:  This function will overwrite the svn:author property, if
    any, found in REVPROPS.  */
 dav_error *
-dav_svn__create_txn(const dav_svn_repos *repos,
+dav_svn__create_txn(dav_svn_repos *repos,
                     const char **ptxn_name,
                     apr_hash_t *revprops,
                     apr_pool_t *pool);
@@ -1051,6 +1062,19 @@ int dav_svn__error_response_tag(request_
 int dav_svn__parse_request_skel(svn_skel_t **skel, request_rec *r,
                                 apr_pool_t *pool);
 
+/* Set *YOUNGEST_P to the number of the youngest revision in REPOS.
+ *
+ * Youngest revision will be cached in REPOS->YOUNGEST_REV to avoid
+ * fetching the youngest revision multiple times during proccessing
+ * the request.
+ *
+ * Uses SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+dav_svn__get_youngest_rev(svn_revnum_t *youngest_p,
+                          dav_svn_repos *repos,
+                          apr_pool_t *scratch_pool);
+
 /*** mirror.c ***/
 
 /* Perform the fixup hook for the R request.  */

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/deadprops.c Fri Apr 29 18:38:53 2016
@@ -110,7 +110,12 @@ get_value(dav_db *db, const dav_prop_nam
       return NULL;
     }
 
-  /* ### if db->props exists, then try in there first */
+  /* If db->props exists, then use it to obtain property value. */
+  if (db->props)
+    {
+      *pvalue = svn_hash_gets(db->props, propname);
+      return NULL;
+    }
 
   /* We've got three different types of properties (node, txn, and
      revision), and we've got two different protocol versions to deal
@@ -705,19 +710,14 @@ db_first_name(dav_db *db, dav_prop_name
         }
       else
         {
-          svn_node_kind_t kind;
           serr = svn_fs_node_proplist(&db->props,
                                       db->resource->info->root.root,
                                       get_repos_path(db->resource->info),
                                       db->p);
-          if (! serr)
-            serr = svn_fs_check_path(&kind, db->resource->info->root.root,
-                                     get_repos_path(db->resource->info),
-                                     db->p);
 
           if (! serr)
             {
-              if (kind == svn_node_dir)
+              if (db->resource->collection)
                 action = svn_log__get_dir(db->resource->info->repos_path,
                                           db->resource->info->root.rev,
                                           FALSE, TRUE, 0, db->resource->pool);

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/liveprops.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/liveprops.c Fri Apr 29 18:38:53 2016
@@ -598,8 +598,8 @@ insert_prop_internal(const dav_resource
         {
           svn_revnum_t revnum;
 
-          serr = svn_fs_youngest_rev(&revnum, resource->info->repos->fs,
-                                     scratch_pool);
+          serr = dav_svn__get_youngest_rev(&revnum, resource->info->repos,
+                                           scratch_pool);
           if (serr != NULL)
             {
               ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
@@ -720,7 +720,6 @@ insert_prop_internal(const dav_resource
               || resource->type == DAV_RESOURCE_TYPE_WORKING
               || resource->type == DAV_RESOURCE_TYPE_VERSION))
         {
-          svn_node_kind_t kind;
           svn_checksum_t *checksum;
           svn_checksum_kind_t checksum_kind;
 
@@ -733,14 +732,20 @@ insert_prop_internal(const dav_resource
               checksum_kind = svn_checksum_sha1;
             }
 
-          serr = svn_fs_check_path(&kind, resource->info->root.root,
-                                   resource->info->repos_path, scratch_pool);
-          if (!serr && kind == svn_node_file)
-            serr = svn_fs_file_checksum(&checksum, checksum_kind,
-                                        resource->info->root.root,
-                                        resource->info->repos_path, TRUE,
-                                        scratch_pool);
-          if (serr != NULL)
+          serr = svn_fs_file_checksum(&checksum, checksum_kind,
+                                      resource->info->root.root,
+                                      resource->info->repos_path, TRUE,
+                                      scratch_pool);
+          if (serr && serr->apr_err == SVN_ERR_FS_NOT_FILE)
+            {
+              /* It should not happen since we're already checked
+                 RESOURCE->COLLECTION, but svn_fs_check_path() call
+                 was added in r1239596 for some reason. Keep it for
+                 now. */
+              svn_error_clear(serr);
+              return DAV_PROP_INSERT_NOTSUPP;
+            }
+          else if (serr)
             {
               ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                             resource->info->r,
@@ -756,9 +761,6 @@ insert_prop_internal(const dav_resource
               break;
             }
 
-          if (kind != svn_node_file)
-            return DAV_PROP_INSERT_NOTSUPP;
-
           value = svn_checksum_to_cstring(checksum, scratch_pool);
 
           if (! value)

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/lock.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/lock.c Fri Apr 29 18:38:53 2016
@@ -487,6 +487,18 @@ get_locks(dav_lockdb *lockdb,
       svn_lock_to_dav_lock(&lock, slock, info->lock_break,
                            resource->exists, resource->pool);
 
+      /* If we are talking to an svn client that wants to unlock a
+         path, tell mod_dav that the lock is owned by the user trying
+         to unlock. This stops it from returning an error that we
+         can't use in the client, and allows us to return the actual
+         unlock error */
+      if (info->r->method_number == M_UNLOCK
+          && resource->info->repos->is_svn_client
+          && resource->info->repos->username)
+        {
+          lock->auth_user = resource->info->repos->username;
+        }
+
       /* Let svn clients know the creationdate of the slock. */
       apr_table_setn(info->r->headers_out, SVN_DAV_CREATIONDATE_HEADER,
                      svn_time_to_cstring(slock->creation_date,
@@ -705,7 +717,7 @@ append_locks(dav_lockdb *lockdb,
 
       /* Commit a 0-byte file: */
 
-      if ((serr = svn_fs_youngest_rev(&rev, repos->fs, resource->pool)))
+      if ((serr = dav_svn__get_youngest_rev(&rev, repos, resource->pool)))
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest revision",
                                     resource->pool);
@@ -937,6 +949,11 @@ remove_lock(dav_lockdb *lockdb,
                            APLOG_WARNING);
 
         }
+      else if (serr && serr->apr_err == SVN_ERR_FS_LOCK_OWNER_MISMATCH)
+        {
+            return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                        NULL, resource->pool);
+        }
       else if (serr)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Failed to remove a lock.",

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=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/merge.c Fri Apr 29 18:38:53 2016
@@ -119,32 +119,32 @@ do_resources(const dav_svn_repos *repos,
              apr_bucket_brigade *bb,
              apr_pool_t *pool)
 {
-  apr_hash_t *changes;
-  apr_hash_t *sent = apr_hash_make(pool);
-  apr_hash_index_t *hi;
+  svn_fs_path_change_iterator_t *iterator;
+  svn_fs_path_change3_t *change;
+
+  /* Change lists can have >100000 entries, so we must make sure to release
+     any collection as soon as possible.  Allocate them in SUBPOOL. */
   apr_pool_t *subpool = svn_pool_create(pool);
+  apr_hash_t *sent = apr_hash_make(subpool);
+
+  /* Standard iteration pool. */
+  apr_pool_t *iterpool = svn_pool_create(subpool);
 
   /* Fetch the paths changed in this revision.  This will contain
      everything except otherwise-unchanged parent directories of added
      and deleted things.  Also, note that deleted things don't merit
      responses of their own -- they are considered modifications to
      their parent.  */
-  SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));
+  SVN_ERR(svn_fs_paths_changed3(&iterator, root, subpool, subpool));
+  SVN_ERR(svn_fs_path_change_get(&change, iterator));
 
-  for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi))
+  while (change)
     {
-      const void *key;
-      void *val;
-      const char *path;
-      apr_ssize_t path_len;
-      svn_fs_path_change2_t *change;
       svn_boolean_t send_self;
       svn_boolean_t send_parent;
+      const char *path = change->path.data;
 
-      svn_pool_clear(subpool);
-      apr_hash_this(hi, &key, &path_len, &val);
-      path = key;
-      change = val;
+      svn_pool_clear(iterpool);
 
       /* Figure out who needs to get sent. */
       switch (change->change_kind)
@@ -171,30 +171,38 @@ do_resources(const dav_svn_repos *repos,
         {
           /* If we haven't already sent this path, send it (and then
              remember that we sent it). */
-          if (! apr_hash_get(sent, path, path_len))
+          if (! apr_hash_get(sent, path, change->path.len))
             {
               svn_node_kind_t kind;
-              SVN_ERR(svn_fs_check_path(&kind, root, path, subpool));
-              SVN_ERR(send_response(repos, root, path,
+              SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool));
+              SVN_ERR(send_response(repos, root, change->path.data,
                                     kind == svn_node_dir,
-                                    output, bb, subpool));
-              apr_hash_set(sent, path, path_len, (void *)1);
+                                    output, bb, iterpool));
+
+              /* The paths in CHANGES are unique, i.e. they can only
+               * clash with those that we end in the SEND_PARENT case.
+               *
+               * Because file paths cannot be the parent of other paths,
+               * we only need to track non-file paths. */
+              if (change->node_kind != svn_node_file)
+                {
+                  path = apr_pstrmemdup(subpool, path, change->path.len);
+                  apr_hash_set(sent, path, change->path.len, (void *)1);
+                }
             }
         }
       if (send_parent)
         {
-          /* If it hasn't already been sent, send the parent directory
-             (and then remember that you sent it).  Allocate parent in
-             pool, not subpool, because it stays in the sent hash
-             afterwards. */
-          const char *parent = svn_fspath__dirname(path, pool);
+          const char *parent = svn_fspath__dirname(path, iterpool);
           if (! svn_hash_gets(sent, parent))
             {
               SVN_ERR(send_response(repos, root, parent,
-                                    TRUE, output, bb, subpool));
-              svn_hash_sets(sent, parent, (void *)1);
+                                    TRUE, output, bb, iterpool));
+              svn_hash_sets(sent, apr_pstrdup(subpool, parent), (void *)1);
             }
         }
+
+      SVN_ERR(svn_fs_path_change_get(&change, iterator));
     }
 
   svn_pool_destroy(subpool);
@@ -226,6 +234,7 @@ dav_svn__merge_response(ap_filter_t *out
   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);
   if (serr != NULL)
@@ -268,23 +277,17 @@ dav_svn__merge_response(ap_filter_t *out
 
 
   /* get the creationdate and creator-displayname of the new revision, too. */
-  serr = svn_fs_revision_prop(&creationdate, repos->fs, new_rev,
-                              SVN_PROP_REVISION_DATE, pool);
-  if (serr != NULL)
-    {
-      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
-                                  "Could not get date of newest revision",
-                                  repos->pool);
-    }
-  serr = svn_fs_revision_prop(&creator_displayname, repos->fs, new_rev,
-                              SVN_PROP_REVISION_AUTHOR, pool);
+  serr = svn_fs_revision_proplist2(&revprops, repos->fs, new_rev,
+                                   TRUE, pool, pool);
   if (serr != NULL)
     {
       return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
-                                  "Could not get author of newest revision",
-                                  repos->pool);
+                                  "Could not get date and author of newest "
+                                  "revision", repos->pool);
     }
 
+  creationdate = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
+  creator_displayname = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
 
   status = ap_fputstrs(output, bb,
                      DAV_XML_HEADER DEBUG_CR

Modified: subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/authzperf/subversion/mod_dav_svn/mod_dav_svn.c Fri Apr 29 18:38:53 2016
@@ -105,6 +105,7 @@ typedef struct dir_conf_t {
   enum conf_flag txdelta_cache;      /* whether to enable txdelta caching */
   enum conf_flag fulltext_cache;     /* whether to enable fulltext caching */
   enum conf_flag revprop_cache;      /* whether to enable revprop caching */
+  enum conf_flag nodeprop_cache;     /* whether to enable nodeprop caching */
   enum conf_flag block_read;         /* whether to enable block read mode */
   const char *hooks_env;             /* path to hook script env config file */
 } dir_conf_t;
@@ -240,6 +241,7 @@ create_dir_config(apr_pool_t *p, char *d
   conf->v2_protocol = CONF_FLAG_DEFAULT;
   conf->hooks_env = NULL;
   conf->txdelta_cache = CONF_FLAG_DEFAULT;
+  conf->nodeprop_cache = CONF_FLAG_DEFAULT;
 
   return conf;
 }
@@ -270,6 +272,7 @@ merge_dir_config(apr_pool_t *p, void *ba
   newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
   newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
   newconf->revprop_cache = INHERIT_VALUE(parent, child, revprop_cache);
+  newconf->nodeprop_cache = INHERIT_VALUE(parent, child, nodeprop_cache);
   newconf->block_read = INHERIT_VALUE(parent, child, block_read);
   newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
   newconf->hooks_env = INHERIT_VALUE(parent, child, hooks_env);
@@ -567,6 +570,19 @@ SVNCacheRevProps_cmd(cmd_parms *cmd, voi
 }
 
 static const char *
+SVNCacheNodeProps_cmd(cmd_parms *cmd, void *config, int arg)
+{
+  dir_conf_t *conf = config;
+
+  if (arg)
+    conf->nodeprop_cache = CONF_FLAG_ON;
+  else
+    conf->nodeprop_cache = CONF_FLAG_OFF;
+
+  return NULL;
+}
+
+static const char *
 SVNBlockRead_cmd(cmd_parms *cmd, void *config, int arg)
 {
   dir_conf_t *conf = config;
@@ -991,6 +1007,15 @@ dav_svn__get_revprop_cache_flag(request_
   return conf->revprop_cache == CONF_FLAG_ON;
 }
 
+svn_boolean_t
+dav_svn__get_nodeprop_cache_flag(request_rec *r)
+{
+  dir_conf_t *conf;
+
+  conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+  /* node properties caching is enabled by default. */
+  return get_conf_flag(conf->nodeprop_cache, FALSE);
+}
 
 svn_boolean_t
 dav_svn__get_block_read_flag(request_rec *r)
@@ -1343,6 +1368,13 @@ static const command_rec cmds[] =
                "(default is Off)."),
 
   /* per directory/location */
+  AP_INIT_FLAG("SVNCacheNodeProps", SVNCacheNodeProps_cmd, NULL,
+               ACCESS_CONF|RSRC_CONF,
+               "speeds up data access by caching node properties "
+               "if sufficient in-memory cache is available"
+               "(default is On)."),
+
+  /* per directory/location */
   AP_INIT_FLAG("SVNBlockRead", SVNBlockRead_cmd, NULL,
                ACCESS_CONF|RSRC_CONF,
                "speeds up operations of FSFS 1.9+ repositories if large"

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=1741682&r1=1741681&r2=1741682&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 Fri Apr 29 18:38:53 2016
@@ -183,8 +183,8 @@ dav_svn__get_location_segments_report(co
     {
       svn_revnum_t youngest;
 
-      serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
-                                 resource->pool);
+      serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
+                                       resource->pool);
       if (serr != NULL)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not determine youngest revision",