You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/06 22:02:24 UTC

svn commit: r993141 [18/25] - in /subversion/branches/performance: ./ build/ac-macros/ build/generator/ contrib/server-side/ notes/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/...

Modified: subversion/branches/performance/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/wc_db.h?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/performance/subversion/libsvn_wc/wc_db.h Mon Sep  6 20:02:15 2010
@@ -126,7 +126,7 @@ typedef struct svn_wc__db_t svn_wc__db_t
 
 
 /* Enumerated constants for how to open a WC datastore.  */
-typedef enum {
+typedef enum svn_wc__db_openmode_t {
   svn_wc__db_openmode_default,    /* Open in the default mode (r/w now). */
   svn_wc__db_openmode_readonly,   /* Changes will definitely NOT be made. */
   svn_wc__db_openmode_readwrite   /* Changes will definitely be made. */
@@ -148,7 +148,7 @@ typedef enum {
    ###   cannot simply be added. it would surprise too much code.
    ###   (we could probably create svn_node_kind2_t though)
 */
-typedef enum {
+typedef enum svn_wc__db_kind_t {
     /* The node is a directory. */
     svn_wc__db_kind_dir,
 
@@ -162,20 +162,11 @@ typedef enum {
        deletion, or incomplete status. */
     svn_wc__db_kind_unknown,
 
-    /* This directory node is a placeholder; the actual information is
-       held within the subdirectory.
-
-       Note: users of this API shouldn't see this kind. It will be
-       handled internally to wc_db.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_kind_subdir
-
 } svn_wc__db_kind_t;
 
 
 /* Enumerated values describing the state of a node. */
-typedef enum {
+typedef enum svn_wc__db_status_t {
     /* The node is present and has no known modifications applied to it. */
     svn_wc__db_status_normal,
 
@@ -202,32 +193,6 @@ typedef enum {
        will be present. */
     svn_wc__db_status_deleted,
 
-    /* The information for this directory node is obstructed by something
-       in the local filesystem. Full details are not available.
-
-       This is only returned by an unshadowed BASE node. If a WORKING node
-       is present, then obstructed_delete or obstructed_add is returned as
-       appropriate.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_status_obstructed,
-
-    /* The information for this directory node is obstructed by something
-       in the local filesystem. Full details are not available.
-
-       The directory has been marked for deletion.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_status_obstructed_delete,
-
-    /* The information for this directory node is obstructed by something
-       in the local filesystem. Full details are not available.
-
-       The directory has been marked for addition.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_status_obstructed_add,
-
     /* This node was named by the server, but no information was provided. */
     svn_wc__db_status_absent,
 
@@ -259,7 +224,7 @@ typedef enum {
 
 /* Lock information.  We write/read it all as one, so let's use a struct
    for convenience.  */
-typedef struct {
+typedef struct svn_wc__db_lock_t {
   /* The lock token */
   const char *token;
 
@@ -347,13 +312,17 @@ svn_wc__db_close(svn_wc__db_t *db);
    A REPOSITORY row will be constructed for the repository identified by
    REPOS_ROOT_URL and REPOS_UUID. Neither of these may be NULL.
 
-   A node will be created for the directory at REPOS_RELPATH will be added.
+   A BASE_NODE row will be created for the directory at REPOS_RELPATH at
+   revision INITIAL_REV.
    If INITIAL_REV is greater than zero, then the node will be marked as
    "incomplete" because we don't know its children. Contrary, if the
    INITIAL_REV is zero, then this directory should represent the root and
    we know it has no children, so the node is complete.
 
-   DEPTH is the initial depth of the working copy, it must be a definite
+   ### Is there any benefit to marking it 'complete' if rev==0?  Seems like
+   ### an unnecessary special case.
+
+   DEPTH is the initial depth of the working copy; it must be a definite
    depth, not svn_depth_unknown.
 
    Use SCRATCH_POOL for temporary allocations.
@@ -413,6 +382,34 @@ svn_wc__db_from_relpath(const char **loc
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 
+/* Compute the working copy root WCROOT_ABSPATH for WRI_ABSPATH using DB.
+ */
+svn_error_t *
+svn_wc__db_get_wcroot(const char **wcroot_abspath,
+                      svn_wc__db_t *db,
+                      const char *wri_abspath,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool);
+
+typedef svn_error_t * (*svn_wc__db_sqlite_lock_cb)(svn_wc__db_t *db,
+                                                   void *baton,
+                                                   apr_pool_t *scratch_pool);
+
+/* Obtain a sqlite lock to efficiently use the working copy database for
+   WRI_ABSPATH and call LOCK_CB with CB_BATON while this lock exist.
+
+   On returning from this function all operations will be committed, but
+   operations might have been committed before returning from this function.
+
+   ### See svn_sqlite__with_lock() for more details.
+ */
+svn_error_t *
+svn_wc__db_with_sqlite_lock(svn_wc__db_t *db,
+                            const char *wri_abspath,
+                            svn_wc__db_sqlite_lock_cb lock_cb,
+                            void *cb_baton,
+                            apr_pool_t *scratch_pool);
+
 /* @} */
 
 /* Different kinds of trees
@@ -425,11 +422,16 @@ svn_wc__db_from_relpath(const char **loc
 
 /* @defgroup svn_wc__db_base  BASE tree management
 
-   BASE should be what we get from the server. The *absolute* pristine copy.
-   Nothing can change it -- it is always a reflection of the repository.
+   BASE is what we get from the server.  It is the *absolute* pristine copy.
    You need to use checkout, update, switch, or commit to alter your view of
    the repository.
 
+   In the BASE tree, each node corresponds to a particular node-rev in the
+   repository.  It can be a mixed-revision tree.  Each node holds either a
+   copy of the node-rev as it exists in the repository (if presence =
+   'normal'), or a place-holder (if presence = 'absent' or 'excluded' or
+   'not-present').
+
    @{
 */
 
@@ -848,53 +850,6 @@ svn_wc__db_base_clear_dav_cache_recursiv
    @{
 */
 
-/* Enumerated constants for how hard svn_wc__db_pristine_check() should
-   work on checking for the pristine file.
-*/
-typedef enum {
-
-  /* ### bah. this is bogus. we open the sqlite database "all the time",
-     ### and don't worry about optimizing that. so: given the db is always
-     ### open, then the following modes are overengineered, premature
-     ### optimizations. ... will clean up in a future rev.  */
-
-  /* The caller wants to be sure the pristine file is present and usable.
-     This is the typical mode to use.
-
-     Implementation note: the SQLite database is opened (if not already)
-       and its state is verified against the file in the filesystem. */
-  svn_wc__db_checkmode_usable,
-
-  /* The caller is performing just this one check. The implementation will
-     optimize around the assumption no further calls to _check() will occur
-     (but of course has no problem if they do).
-
-     Note: this test is best used for detecting a *missing* file
-     rather than for detecting a usable file.
-
-     Implementation note: this will examine the presence of the pristine file
-       in the filesystem. The SQLite database is untouched, though if it is
-       (already) open, then it will be used instead. */
-  svn_wc__db_checkmode_single,
-
-  /* The caller is going to perform multiple calls, so the implementation
-     should optimize its operation around that.
-
-     Note: this test is best used for detecting a *missing* file
-     rather than for detecting a usable file.
-
-     Implementation note: the SQLite database will be opened (if not already),
-     and all checks will simply look in the TEXT_BASE table to see if the
-     given key is present. Note that the file may not be present. */
-  svn_wc__db_checkmode_multi,
-
-  /* Similar to _usable, but the file is checksum'd to ensure that it has
-     not been corrupted in some way. */
-  svn_wc__db_checkmode_validate
-
-} svn_wc__db_checkmode_t;
-
-
 /* Set *PRISTINE_ABSPATH to the path to the pristine text file
    identified by SHA1_CHECKSUM.  Error if it does not exist.
 
@@ -1014,15 +969,14 @@ svn_wc__db_pristine_cleanup(svn_wc__db_t
                             apr_pool_t *scratch_pool);
 
 
-/* ### check for presence, according to the given mode (on how hard we
-   ### should examine things)
+/* Set *PRESENT to true if the pristine store for WRI_ABSPATH in DB contains
+   a pristine text with SHA-1 checksum SHA1_CHECKSUM, and to false otherwise.
 */
 svn_error_t *
 svn_wc__db_pristine_check(svn_boolean_t *present,
                           svn_wc__db_t *db,
                           const char *wri_abspath,
                           const svn_checksum_t *sha1_checksum,
-                          svn_wc__db_checkmode_t mode,
                           apr_pool_t *scratch_pool);
 
 
@@ -1202,6 +1156,8 @@ svn_wc__db_op_set_props(svn_wc__db_t *db
                         const svn_skel_t *work_items,
                         apr_pool_t *scratch_pool);
 
+/* See props.h  */
+#ifdef SVN__SUPPORT_BASE_MERGE
 /* ### Set the properties of the node LOCAL_ABSPATH in the BASE tree to PROPS.
    ###
    ### This function should not exist because properties should be stored
@@ -1234,7 +1190,7 @@ svn_wc__db_temp_working_set_props(svn_wc
                                   const char *local_abspath,
                                   const apr_hash_t *props,
                                   apr_pool_t *scratch_pool);
-
+#endif
 
 /* ### KFF: This handles files, dirs, symlinks, anything else? */
 /* ### dlr: Does this support recursive dir deletes (e.g. _revert)? Document. */
@@ -1706,15 +1662,11 @@ svn_wc__db_is_wcroot(svn_boolean_t *is_r
 
    ### Assuming the future ability to copy across repositories, should we
    ### refrain from resetting the copyfrom information in this operation?
-
-   ### SINGLE_DB is a temp argument, and should be TRUE if using compressed
-   ### metadata.  When *all* metadata gets compressed, it should disappear.
 */
 svn_error_t *
 svn_wc__db_global_relocate(svn_wc__db_t *db,
                            const char *local_dir_abspath,
                            const char *repos_root_url,
-                           svn_boolean_t single_db,
                            apr_pool_t *scratch_pool);
 
 
@@ -2084,6 +2036,7 @@ svn_wc__db_upgrade_begin(svn_sqlite__db_
 
 svn_error_t *
 svn_wc__db_upgrade_apply_dav_cache(svn_sqlite__db_t *sdb,
+                                   const char *dir_relpath,
                                    apr_hash_t *cache_values,
                                    apr_pool_t *scratch_pool);
 
@@ -2246,28 +2199,6 @@ svn_wc__db_temp_forget_directory(svn_wc_
                                  apr_pool_t *scratch_pool);
 
 
-/* A temporary API similar to svn_wc__db_base_add_directory() and
-   svn_wc__db_base_add_file(), in that it adds a subdirectory to the given
-   DB.  * Arguments are the same as those to svn_wc__db_base_add_directory().
-
-   Note: Since the subdir node type is a fiction created to satisfy our
-   current backward-compat hacks, this is a temporary API expected to
-   disappear with that node type does.
-*/
-svn_error_t *
-svn_wc__db_temp_base_add_subdir(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                const char *repos_relpath,
-                                const char *repos_root_url,
-                                const char *repos_uuid,
-                                svn_revnum_t revision,
-                                const apr_hash_t *props,
-                                svn_revnum_t changed_rev,
-                                apr_time_t changed_date,
-                                const char *changed_author,
-                                svn_depth_t depth,
-                                apr_pool_t *scratch_pool);
-
 svn_error_t *
 svn_wc__db_temp_is_dir_deleted(svn_boolean_t *not_present,
                                svn_revnum_t *base_revision,
@@ -2275,6 +2206,7 @@ svn_wc__db_temp_is_dir_deleted(svn_boole
                                const char *local_abspath,
                                apr_pool_t *scratch_pool);
 
+#ifndef SVN_WC__SINGLE_DB
 /* For a deleted node, determine its keep_local flag. (This flag will
    go away once we have a consolidated administrative area) */
 svn_error_t *
@@ -2290,6 +2222,7 @@ svn_wc__db_temp_set_keep_local(svn_wc__d
                                const char *local_abspath,
                                svn_boolean_t keep_local,
                                apr_pool_t *scratch_pool);
+#endif
 
 /* Removes all references of LOCAL_ABSPATH from its working copy
    using DB. */
@@ -2434,11 +2367,13 @@ svn_wc__db_temp_get_file_external(const 
                                   apr_pool_t *scratch_pool);
 
 
+#ifndef SVN_WC__SINGLE_DB
 /* Remove a stray "subdir" record in the BASE_NODE table.  */
 svn_error_t *
 svn_wc__db_temp_remove_subdir_record(svn_wc__db_t *db,
                                      const char *local_abspath,
                                      apr_pool_t *scratch_pool);
+#endif
 
 /* Set file external information on LOCAL_ABSPATH to REPOS_RELPATH
    at PEG_REV with revision REV*/
@@ -2468,6 +2403,7 @@ svn_wc__db_temp_op_set_property_conflict
                                                      const char *prej_basename,
                                                      apr_pool_t *scratch_pool);
 
+#ifndef SVN_WC__SINGLE_DB
 /* Ensure that the parent stub of LOCAL_ABSPATH contains a BASE_NODE record with
    a normal status and optionally remove the WORKING_NODE record for the node;
    this assumes that the parent directory is in the incomplete state, or the
@@ -2481,11 +2417,14 @@ svn_wc__db_temp_set_parent_stub_to_norma
                                           const char *local_abspath,
                                           svn_boolean_t delete_working,
                                           apr_pool_t *scratch_pool);
+#endif
 
 /* Sets a base nodes revision and/or repository relative path. If
    LOCAL_ABSPATH's rev (REV) is valid, set is revision and if SET_REPOS_RELPATH
    is TRUE set its repository relative path to REPOS_RELPATH (and make sure its
    REPOS_ROOT_URL and REPOS_ROOT_UUID are still valid).
+
+   ### TODO(SINGLE_DB): Remove the 'update_stub' argument.
  */
 svn_error_t *
 svn_wc__db_temp_op_set_rev_and_repos_relpath(svn_wc__db_t *db,
@@ -2515,8 +2454,16 @@ svn_wc__db_temp_op_set_new_dir_to_incomp
                                              const char *repos_root_url,
                                              const char *repos_uuid,
                                              svn_revnum_t revision,
+                                             svn_depth_t depth,
                                              apr_pool_t *scratch_pool);
 
+/* Close the wc root LOCAL_ABSPATH and remove any per-directory
+   handles associated with it. */
+svn_error_t *
+svn_wc__db_drop_root(svn_wc__db_t *db,
+                     const char *local_abspath,
+                     apr_pool_t *scratch_pool);
+
 /* @} */
 
 

Modified: subversion/branches/performance/subversion/libsvn_wc/wc_db_pdh.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/wc_db_pdh.c?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/wc_db_pdh.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/wc_db_pdh.c Mon Sep  6 20:02:15 2010
@@ -809,4 +809,41 @@ svn_wc__db_pdh_navigate_to_parent(svn_wc
   child_pdh->parent = *parent_pdh;
 
   return SVN_NO_ERROR;
-}
\ No newline at end of file
+}
+
+svn_error_t *
+svn_wc__db_drop_root(svn_wc__db_t *db,
+                     const char *local_abspath,
+                     apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *root_pdh = apr_hash_get(db->dir_data, local_abspath,
+                                            APR_HASH_KEY_STRING);
+  apr_hash_index_t *hi;
+  apr_status_t result;
+
+  if (!root_pdh)
+    return SVN_NO_ERROR;
+
+  if (!root_pdh->wcroot || strcmp(root_pdh->wcroot->abspath, local_abspath))
+    return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
+                             _("'%s' is not a working copy root"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  for (hi = apr_hash_first(scratch_pool, db->dir_data);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      svn_wc__db_pdh_t *pdh = svn__apr_hash_index_val(hi);
+
+      if (pdh->wcroot == root_pdh->wcroot)
+        apr_hash_set(db->dir_data,
+                     pdh->local_abspath, svn__apr_hash_index_klen(hi), NULL);
+    }
+
+  result = apr_pool_cleanup_run(db->state_pool, root_pdh->wcroot, close_wcroot);
+  if (result != APR_SUCCESS)
+    return svn_error_wrap_apr(result, NULL);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/performance/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/workqueue.c?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/workqueue.c Mon Sep  6 20:02:15 2010
@@ -35,7 +35,6 @@
 #include "workqueue.h"
 #include "adm_files.h"
 #include "translate.h"
-#include "log.h"
 
 #include "svn_private_config.h"
 #include "private/svn_skel.h"
@@ -43,23 +42,19 @@
 
 /* Workqueue operation names.  */
 #define OP_REVERT "revert"
-#define OP_PREPARE_REVERT_FILES "prep-rev-files"
 #define OP_KILLME "killme"
-#define OP_LOGGY "loggy"
+#define OP_BASE_REMOVE "base-remove"
 #define OP_DELETION_POSTCOMMIT "deletion-postcommit"
 /* Arguments of OP_POSTCOMMIT:
  *   (local_abspath, revnum, date, [author], [checksum],
  *    [dav_cache/wc_props], keep_changelist, [tmp_text_base_abspath]). */
 #define OP_POSTCOMMIT "postcommit"
-#define OP_INSTALL_PROPERTIES "install-properties-2"
-#define OP_DELETE "delete"
 #define OP_FILE_INSTALL "file-install"
 #define OP_FILE_REMOVE "file-remove"
 #define OP_FILE_MOVE "file-move"
 #define OP_FILE_COPY_TRANSLATED "file-translate"
 #define OP_SYNC_FILE_FLAGS "sync-file-flags"
 #define OP_PREJ_INSTALL "prej-install"
-#define OP_WRITE_OLD_PROPS "write-old-props"
 #define OP_RECORD_FILEINFO "record-fileinfo"
 #define OP_TMP_SET_TEXT_CONFLICT_MARKERS "tmp-set-text-conflict-markers"
 #define OP_TMP_SET_PROPERTY_CONFLICT_MARKER "tmp-set-property-conflict-marker"
@@ -144,30 +139,6 @@ get_and_record_fileinfo(svn_wc__db_t *db
 }
 
 
-/* If SOURCE_ABSPATH is present, then move it to DEST_ABSPATH. Ignore any
-   ENOENT message for a missing source, which may indicate the move has
-   already been performed.  */
-static svn_error_t *
-move_if_present(const char *source_abspath,
-                const char *dest_abspath,
-                apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-
-  err = svn_io_file_rename(source_abspath, dest_abspath, scratch_pool);
-  if (err)
-    {
-      if (!APR_STATUS_IS_ENOENT(err->apr_err))
-        return svn_error_return(err);
-
-      /* Not there. Maybe the node was moved in a prior run.  */
-      svn_error_clear(err);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
 /* ------------------------------------------------------------------------ */
 
 /* OP_REVERT  */
@@ -212,7 +183,7 @@ run_revert(svn_wc__db_t *db,
   const char *local_abspath;
   svn_boolean_t replaced;
   svn_wc__db_kind_t kind;
-  const char *working_props_path;
+  svn_wc__db_status_t status;
   const char *parent_abspath;
   svn_boolean_t conflicted;
 
@@ -226,46 +197,13 @@ run_revert(svn_wc__db_t *db,
      (yet) allowed. If we read any conflict files, then we (obviously) have
      not removed them from the metadata (yet).  */
   SVN_ERR(svn_wc__db_read_info(
-            NULL, &kind, NULL, NULL, NULL, NULL,
+            &status, &kind, NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
             &conflicted, NULL,
             db, local_abspath,
             scratch_pool, scratch_pool));
 
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  /* Move the "revert" props over/on the "base" props.  */
-  if (replaced)
-    {
-      const char *revert_props_path;
-      const char *base_props_path;
-
-      SVN_ERR(svn_wc__prop_path(&revert_props_path, local_abspath,
-                                kind, svn_wc__props_revert, scratch_pool));
-      SVN_ERR(svn_wc__prop_path(&base_props_path, local_abspath,
-                                kind, svn_wc__props_base, scratch_pool));
-
-      SVN_ERR(move_if_present(revert_props_path, base_props_path,
-                              scratch_pool));
-
-      /* ### we should also be setting BASE props. and really... we shouldn't
-         ### even bother zero-ing out these props. the WORKING node should
-         ### be disappearing after a revert.  */
-#if 0
-      SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath,
-                                                apr_hash_make(scratch_pool),
-                                                scratch_pool));
-#endif
-    }
-#endif
-
-  /* The "working" props contain changes. Nuke 'em from orbit.  */
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  SVN_ERR(svn_wc__prop_path(&working_props_path, local_abspath,
-                            kind, svn_wc__props_working, scratch_pool));
-  SVN_ERR(svn_io_remove_file2(working_props_path, TRUE, scratch_pool));
-#endif
-
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, NULL, NULL, NULL,
                                   scratch_pool));
 
@@ -354,6 +292,16 @@ run_revert(svn_wc__db_t *db,
     {
       SVN__NOT_IMPLEMENTED();
     }
+#ifdef SVN_WC__SINGLE_DB
+  else if (kind == svn_wc__db_kind_dir)
+    {
+      svn_node_kind_t disk_kind;
+      SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
+
+      if (disk_kind == svn_node_none)
+        SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
+    }
+#endif
 
   if (kind == svn_wc__db_kind_dir)
     parent_abspath = local_abspath;
@@ -401,8 +349,22 @@ run_revert(svn_wc__db_t *db,
     /* ### A working copy root can't have a working node and trying
        ### to delete it fails because the root doesn't have a stub. */
     if (!is_wc_root)
-      SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
-                                                scratch_pool));
+      {
+        const char *op_root_abspath = NULL;
+
+        /* If the node is not the operation root, we should not delete
+           the working node */
+        if (status == svn_wc__db_status_added)
+          SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+        if (!op_root_abspath
+            || (strcmp(op_root_abspath, local_abspath) == 0))
+          SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
+                                                    scratch_pool));
+      }
   }
 
   return SVN_NO_ERROR;
@@ -421,14 +383,6 @@ verify_pristine_present(svn_wc__db_t *db
 {
   const svn_checksum_t *base_checksum;
 
-  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL,
-                                   &base_checksum, NULL, NULL, NULL,
-                                   db, local_abspath,
-                                   scratch_pool, scratch_pool));
-  if (base_checksum != NULL)
-    return SVN_NO_ERROR;
-
   SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, &base_checksum,
                                NULL, NULL, NULL, NULL, NULL, NULL,
@@ -438,6 +392,14 @@ verify_pristine_present(svn_wc__db_t *db
   if (base_checksum != NULL)
     return SVN_NO_ERROR;
 
+  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL,
+                                   &base_checksum, NULL, NULL, NULL,
+                                   db, local_abspath,
+                                   scratch_pool, scratch_pool));
+  if (base_checksum != NULL)
+    return SVN_NO_ERROR;
+
   /* A real file must have either a regular or a revert text-base.
      If it has neither, we could be looking at the situation described
      in issue #2101, in which case all we can do is deliver the expected
@@ -564,99 +526,8 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
   return SVN_NO_ERROR;
 }
 
-
-/* ------------------------------------------------------------------------ */
-
-/* OP_PREPARE_REVERT_FILES  */
-
-
-/* Process the OP_PREPARE_REVERT_FILES work item WORK_ITEM.
- * See svn_wc__wq_prepare_revert_files() which generates this work item.
- * Implements (struct work_item_dispatch).func.
- * With the Pristine Store, the "revert-base" concept no longer applies
- * to texts, so this only deals with properties. */
-static svn_error_t *
-run_prepare_revert_files(svn_wc__db_t *db,
-                         const svn_skel_t *work_item,
-                         const char *wri_abspath,
-                         svn_cancel_func_t cancel_func,
-                         void *cancel_baton,
-                         apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg1 = work_item->children->next;
-  const char *local_abspath;
-  svn_wc__db_kind_t kind;
-  const char *revert_prop_abspath;
-  const char *base_prop_abspath;
-  svn_node_kind_t on_disk;
-
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
-
-  /* Rename the original text base over to the revert text base.  */
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, scratch_pool));
-
-  /* Set up the revert props.  */
-
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  SVN_ERR(svn_wc__prop_path(&revert_prop_abspath, local_abspath, kind,
-                            svn_wc__props_revert, scratch_pool));
-  SVN_ERR(svn_wc__prop_path(&base_prop_abspath, local_abspath, kind,
-                            svn_wc__props_base, scratch_pool));
-
-  /* First: try to move any base properties to the revert location.  */
-  SVN_ERR(move_if_present(base_prop_abspath, revert_prop_abspath,
-                          scratch_pool));
-
-  /* If no props exist at the revert location, then drop a set of empty
-     props there. They are expected to be present.  */
-  SVN_ERR(svn_io_check_path(revert_prop_abspath, &on_disk, scratch_pool));
-  if (on_disk == svn_node_none)
-    {
-      svn_stream_t *stream;
-
-      /* A set of empty props is just an empty file. */
-      SVN_ERR(svn_stream_open_writable(&stream, revert_prop_abspath,
-                                       scratch_pool, scratch_pool));
-      SVN_ERR(svn_stream_close(stream));
-      SVN_ERR(svn_io_set_file_read_only(revert_prop_abspath, FALSE,
-                                        scratch_pool));
-    }
-#endif
-
-  /* Put some blank properties into the WORKING node.  */
-  /* ### this seems bogus. something else should come along and put the
-     ### correct values in here. we shouldn't put empty values in.  */
-#if 0
-  SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath,
-                                            apr_hash_make(scratch_pool),
-                                            scratch_pool));
-#endif
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__wq_prepare_revert_files(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool)
-{
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
-
-  /* These skel atoms hold references to very transitory state, but
-     we only need the work_item to survive for the duration of wq_add.  */
-  svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_PREPARE_REVERT_FILES, work_item, scratch_pool);
-
-  SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
 /* ------------------------------------------------------------------------ */
-
+#ifndef SVN_WC__SINGLE_DB
 /* OP_KILLME  */
 
 /* Process the OP_KILLME work item WORK_ITEM.
@@ -779,61 +650,236 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
 
   return SVN_NO_ERROR;
 }
-
+#endif
 
 /* ------------------------------------------------------------------------ */
+/* OP_REMOVE_BASE  */
+
+/* Removes a BASE_NODE and all it's data, leaving any adds and copies as is.
+   Do this as a depth first traversal to make sure than any parent still exists
+   on error conditions. 
+   
+   ### This function needs review for 4th tree behavior.*/
+static svn_error_t *
+remove_base_node(svn_wc__db_t *db,
+                 const char *local_abspath,
+                 svn_cancel_func_t cancel_func,
+                 void *cancel_baton,
+                 apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t base_status, wrk_status;
+  svn_wc__db_kind_t base_kind, wrk_kind;
+  svn_boolean_t have_base, have_work;
+
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
+
+  SVN_ERR(svn_wc__db_read_info(&wrk_status, &wrk_kind, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, &have_base,
+                               &have_work, NULL, NULL,
+                               db, local_abspath, scratch_pool, scratch_pool));
+
+#ifndef SVN_WC__SINGLE_DB
+  if (!have_base)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("Node '%s' not found."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+#else
+  SVN_ERR_ASSERT(have_base); /* Verified in caller and _base_get_children() */
+#endif
+
+  if (wrk_status == svn_wc__db_status_normal
+      || wrk_status == svn_wc__db_status_not_present
+      || wrk_status == svn_wc__db_status_absent)
+    {
+      base_status = wrk_status;
+      base_kind = wrk_kind;
+    }
+  else
+    SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL,
+                                     db, local_abspath,
+                                     scratch_pool, scratch_pool));
+
+  /* Children first */
+  if (base_kind == svn_wc__db_kind_dir
+      && base_status == svn_wc__db_status_normal)
+    {
+      const apr_array_header_t *children;
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+      int i;
 
-/* OP_LOGGY  */
+      SVN_ERR(svn_wc__db_base_get_children(&children, db, local_abspath,
+                                           scratch_pool, iterpool));
 
-/* Process the OP_LOGGY work item WORK_ITEM.
- * See svn_wc__wq_add_loggy() which generates this work item.
+      for (i = 0; i < children->nelts; i++)
+        {
+          const char *child_name = APR_ARRAY_IDX(children, i, const char *);
+          const char *child_abspath;
+
+          svn_pool_clear(iterpool);
+
+          child_abspath = svn_dirent_join(local_abspath, child_name, iterpool);
+
+          SVN_ERR(remove_base_node(db, child_abspath, cancel_func, cancel_baton,
+                                   iterpool));
+        }
+
+      svn_pool_destroy(iterpool);
+    }
+
+  if (base_status == svn_wc__db_status_normal
+      && wrk_status != svn_wc__db_status_added
+#ifndef SVN_WC__SINGLE_DB
+      && wrk_status != svn_wc__db_status_obstructed_add
+#endif
+      && wrk_status != svn_wc__db_status_excluded)
+    {
+#ifndef SVN_WC__SINGLE_DB
+      if (base_kind == svn_wc__db_kind_dir)
+        SVN_ERR(svn_wc__adm_destroy(db, local_abspath, cancel_func, cancel_baton,
+                                    scratch_pool));
+#endif
+
+      if (wrk_status != svn_wc__db_status_deleted
+          && (base_kind == svn_wc__db_kind_file
+              || base_kind == svn_wc__db_kind_symlink))
+        {
+          SVN_ERR(svn_io_remove_file2(local_abspath, TRUE, scratch_pool));
+        }
+      else if (base_kind == svn_wc__db_kind_dir
+#ifdef SVN_WC__SINGLE_DB
+               && wrk_status != svn_wc__db_status_deleted
+#endif
+              )
+        {
+          svn_error_t *err = svn_io_dir_remove_nonrecursive(local_abspath,
+                                                            scratch_pool);
+
+          if (err && (APR_STATUS_IS_ENOENT(err->apr_err)
+                      || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)
+                      || APR_STATUS_IS_ENOTEMPTY(err->apr_err)))
+            svn_error_clear(err);
+          else
+            SVN_ERR(err);
+        }
+
+      /* This should remove just BASE and ACTUAL, but for now also remove
+         not existing WORKING_NODE data. */
+      SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
+    }
+  else if (wrk_status == svn_wc__db_status_added
+#ifndef SVN_WC__SINGLE_DB
+           || wrk_status == svn_wc__db_status_obstructed_add
+#endif
+           || (have_work && wrk_status == svn_wc__db_status_excluded))
+    /* ### deletes of working additions should fall in this case, but
+       ### we can't express these without the 4th tree */
+    {
+      /* Just remove the BASE_NODE data */
+      SVN_ERR(svn_wc__db_base_remove(db, local_abspath, scratch_pool));
+    }
+  else
+    SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Process the OP_REMOVE_BASE work item WORK_ITEM.
+ * See svn_wc__wq_build_remove_base() which generates this work item.
  * Implements (struct work_item_dispatch).func. */
+
 static svn_error_t *
-run_loggy(svn_wc__db_t *db,
-          const svn_skel_t *work_item,
-          const char *wri_abspath,
-          svn_cancel_func_t cancel_func,
-          void *cancel_baton,
-          apr_pool_t *scratch_pool)
+run_base_remove(svn_wc__db_t *db,
+                const svn_skel_t *work_item,
+                const char *wri_abspath,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg1 = work_item->children->next;
-  const char *adm_abspath;
+  const char *local_abspath;
+  svn_boolean_t keep_not_present;
+  svn_revnum_t revision;
+  const char *repos_relpath, *repos_root_url, *repos_uuid;
+  svn_wc__db_kind_t kind;
 
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  adm_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+  keep_not_present = svn_skel__parse_int(arg1->next, scratch_pool) != 0;
 
-  return svn_error_return(svn_wc__run_xml_log(
-                            db, adm_abspath,
-                            arg1->next->data, arg1->next->len,
-                            scratch_pool));
-}
+  if (keep_not_present)
+    {
+      SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision, &repos_relpath,
+                                       &repos_root_url, &repos_uuid, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
 
+      if (!repos_relpath)
+        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+                                           &repos_uuid,
+                                           db, local_abspath, scratch_pool,
+                                           scratch_pool));
 
-svn_error_t *
-svn_wc__wq_build_loggy(svn_skel_t **work_item,
-                       svn_wc__db_t *db,
-                       const char *adm_abspath,
-                       const svn_stringbuf_t *log_content,
-                       apr_pool_t *result_pool)
-{
-  if (log_content == NULL || svn_stringbuf_isempty(log_content))
+#ifndef SVN_WC__SINGLE_DB
+      /* ### When LOCAL_ABSPATH is obstructed, we might not receive a valid
+         ### revision here. For the small time that is left until Single-DB
+         ### just mark the not-present node as revision 0, as we are not
+         ### interested in the revision of not-present nodes anyway.
+
+         ### Triggered by update_tests.py 15: issue #919, updates that delete
+       */
+      if (!SVN_IS_VALID_REVNUM(revision))
+        revision = 0;
+#endif
+    }
+
+  SVN_ERR(remove_base_node(db, local_abspath,
+                           cancel_func, cancel_baton,
+                           scratch_pool));
+
+  if (keep_not_present)
     {
-      *work_item = NULL;
-      return SVN_NO_ERROR;
+      SVN_ERR(svn_wc__db_base_add_absent_node(db, local_abspath,
+                                              repos_relpath,
+                                              repos_root_url,
+                                              repos_uuid,
+                                              revision,
+                                              kind,
+                                              svn_wc__db_status_not_present,
+                                              NULL,
+                                              NULL,
+                                              scratch_pool));
     }
 
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+                             svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t keep_not_present,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
   *work_item = svn_skel__make_empty_list(result_pool);
 
-  /* NOTE: the skel still points at ADM_ABSPATH and LOG_CONTENT, but we
-     require these parameters to be allocated in RESULT_POOL.  */
-  svn_skel__prepend_str(log_content->data, *work_item, result_pool);
-  svn_skel__prepend_str(adm_abspath, *work_item, result_pool);
-  svn_skel__prepend_str(OP_LOGGY, *work_item, result_pool);
+  /* If a SOURCE_ABSPATH was provided, then put it into the skel. If this
+     value is not provided, then the file's pristine contents will be used.  */
+
+  svn_skel__prepend_int(keep_not_present, *work_item, result_pool);
+  svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
+                        *work_item, result_pool);
+  svn_skel__prepend_str(OP_BASE_REMOVE, *work_item, result_pool);
 
   return SVN_NO_ERROR;
 }
 
-
 /* ------------------------------------------------------------------------ */
 
 /* OP_DELETION_POSTCOMMIT  */
@@ -873,6 +919,7 @@ run_deletion_postcommit(svn_wc__db_t *db
       const char *repos_uuid;
       svn_revnum_t parent_revision;
 
+#ifndef SVN_WC__SINGLE_DB
       /* If we are suppose to delete "this dir", drop a 'killme' file
          into my own administrative dir as a signal for svn_wc__run_log()
          to blow away the administrative area after it is finished
@@ -904,6 +951,7 @@ run_deletion_postcommit(svn_wc__db_t *db
                                     keep_local /* adm_only */,
                                     scratch_pool));
         }
+#endif
 
       /* Get hold of repository info, if we are going to need it,
          before deleting the file, */
@@ -924,7 +972,9 @@ run_deletion_postcommit(svn_wc__db_t *db
                 db, local_abspath,
                 FALSE, FALSE, cancel_func, cancel_baton, scratch_pool));
 
-      /* If the parent entry's working rev 'lags' behind new_rev... */
+      /* If the parent entry's working rev 'lags' behind new_rev... 
+         ### Maybe we should also add a not-present node if the
+         ### deleted node was switched? */
       if (new_revision > parent_revision)
         {
           /* ...then the parent's revision is now officially a
@@ -934,7 +984,7 @@ run_deletion_postcommit(svn_wc__db_t *db
           SVN_ERR(svn_wc__db_base_add_absent_node(
                     db, local_abspath,
                     repos_relpath, repos_root_url, repos_uuid,
-                    new_revision, svn_wc__db_kind_file,
+                    new_revision, kind,
                     svn_wc__db_status_not_present,
                     NULL, NULL,
                     scratch_pool));
@@ -1247,7 +1297,10 @@ log_do_committed(svn_wc__db_t *db,
 
           /* Committing a deletion should remove the local nodes.  */
           if (child_status == svn_wc__db_status_deleted
-              || child_status == svn_wc__db_status_obstructed_delete)
+#ifndef SVN_WC__SINGLE_DB
+              || child_status == svn_wc__db_status_obstructed_delete
+#endif
+              )
             {
               SVN_ERR(svn_wc__internal_remove_from_revision_control(
                         db, child_abspath,
@@ -1289,9 +1342,6 @@ log_do_committed(svn_wc__db_t *db,
                 set_read_write = TRUE;
             }
         }
-
-      /* Install LOCAL_ABSPATHs working props as base props. */
-      SVN_ERR(svn_wc__working_props_committed(db, local_abspath, pool));
     }
 
   /* If it's a file, install the tree changes and the file's text. */
@@ -1413,9 +1463,11 @@ log_do_committed(svn_wc__db_t *db,
       return SVN_NO_ERROR;
   }
 
+#ifndef SVN_WC__SINGLE_DB
   /* Make sure we have a parent stub in a clean/unmodified state.  */
   SVN_ERR(svn_wc__db_temp_set_parent_stub_to_normal(db, local_abspath,
                                                     TRUE, scratch_pool));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -1559,204 +1611,6 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
 
 /* ------------------------------------------------------------------------ */
 
-/* OP_INSTALL_PROPERTIES */
-
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-
-/* Process the OP_INSTALL_PROPERTIES work item WORK_ITEM.
- * See svn_wc__wq_add_install_properties() which generates this work item.
- * Implements (struct work_item_dispatch).func. */
-static svn_error_t *
-run_install_properties(svn_wc__db_t *db,
-                       const svn_skel_t *work_item,
-                       const char *wri_abspath,
-                       svn_cancel_func_t cancel_func,
-                       void *cancel_baton,
-                       apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg = work_item->children->next;
-  const char *local_abspath;
-  apr_hash_t *base_props;
-  apr_hash_t *actual_props;
-
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
-
-  arg = arg->next;
-  if (arg->is_atom)
-    base_props = NULL;
-  else
-    SVN_ERR(svn_skel__parse_proplist(&base_props, arg, scratch_pool));
-
-  arg = arg->next;
-  if (arg->is_atom)
-    actual_props = NULL;
-  else
-    SVN_ERR(svn_skel__parse_proplist(&actual_props, arg, scratch_pool));
-
-  if (base_props != NULL)
-    {
-        svn_boolean_t written = FALSE;
-
-          {
-            svn_error_t *err;
-
-            /* Try writing to the WORKING tree first.  */
-            err = svn_wc__db_temp_working_set_props(db, local_abspath,
-                                                    base_props,
-                                                    scratch_pool);
-            if (err)
-              {
-                if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-                  return svn_error_return(err);
-                svn_error_clear(err);
-                /* The WORKING node is not present.  */
-              }
-            else
-              {
-                /* The WORKING node is present, and we wrote the props.  */
-                written = TRUE;
-              }
-          }
-
-        if (!written)
-          SVN_ERR(svn_wc__db_temp_base_set_props(db, local_abspath,
-                                                 base_props, scratch_pool));
-    }
-
-  /* Okay. It's time to save the ACTUAL props.  */
-  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
-                                  NULL, NULL, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__wq_add_install_properties(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  apr_hash_t *base_props,
-                                  apr_hash_t *actual_props,
-                                  apr_pool_t *scratch_pool)
-{
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
-  svn_skel_t *props;
-
-  if (actual_props != NULL)
-    {
-      SVN_ERR(svn_skel__unparse_proplist(&props, actual_props, scratch_pool));
-      svn_skel__prepend(props, work_item);
-    }
-  else
-    svn_skel__prepend_str("", work_item, scratch_pool);
-
-  if (base_props != NULL)
-    {
-      SVN_ERR(svn_skel__unparse_proplist(&props, base_props, scratch_pool));
-      svn_skel__prepend(props, work_item);
-    }
-  else
-    svn_skel__prepend_str("", work_item, scratch_pool);
-
-  svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_INSTALL_PROPERTIES, work_item, scratch_pool);
-
-  SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-#endif /* SVN__SUPPORT_BASE_MERGE  */
-
-
-/* ------------------------------------------------------------------------ */
-
-/* OP_DELETE */
-
-/* Process the OP_DELETE work item WORK_ITEM.
- * See svn_wc__wq_add_delete() which generates this work item.
- * Implements (struct work_item_dispatch).func. */
-static svn_error_t *
-run_delete(svn_wc__db_t *db,
-           const svn_skel_t *work_item,
-           const char *wri_abspath,
-           svn_cancel_func_t cancel_func,
-           void *cancel_baton,
-           apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg = work_item->children->next;
-  const char *local_abspath;
-  svn_wc__db_kind_t kind;
-  svn_boolean_t was_added, was_copied, was_replaced;
-
-  local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
-  arg = arg->next;
-  kind = (int) svn_skel__parse_int(arg, scratch_pool);
-  arg = arg->next;
-  was_added = svn_skel__parse_int(arg, scratch_pool) != 0;
-  arg = arg->next;
-  was_copied = svn_skel__parse_int(arg, scratch_pool) != 0;
-  arg = arg->next;
-  was_replaced = svn_skel__parse_int(arg, scratch_pool) != 0;
-
-  if (was_replaced && was_copied)
-    {
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-      const char *props_base, *props_revert;
-
-      SVN_ERR(svn_wc__prop_path(&props_base, local_abspath, kind,
-                                svn_wc__props_base, scratch_pool));
-      SVN_ERR(svn_wc__prop_path(&props_revert, local_abspath, kind,
-                                svn_wc__props_revert, scratch_pool));
-      SVN_ERR(move_if_present(props_revert, props_base, scratch_pool));
-#endif
-    }
-#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
-  if (was_added)
-    {
-      const char *props_base, *props_working;
-
-      SVN_ERR(svn_wc__prop_path(&props_base, local_abspath, kind,
-                                svn_wc__props_base, scratch_pool));
-      SVN_ERR(svn_wc__prop_path(&props_working, local_abspath, kind,
-                                svn_wc__props_working, scratch_pool));
-
-      SVN_ERR(svn_io_remove_file2(props_base, TRUE, scratch_pool));
-      SVN_ERR(svn_io_remove_file2(props_working, TRUE, scratch_pool));
-    }
-#endif
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__wq_add_delete(svn_wc__db_t *db,
-                      const char *parent_abspath,
-                      const char *local_abspath,
-                      svn_wc__db_kind_t kind,
-                      svn_boolean_t was_added,
-                      svn_boolean_t was_copied,
-                      svn_boolean_t was_replaced,
-                      apr_pool_t *scratch_pool)
-{
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
-
-  svn_skel__prepend_int(was_replaced, work_item, scratch_pool);
-  svn_skel__prepend_int(was_copied, work_item, scratch_pool);
-  svn_skel__prepend_int(was_added, work_item, scratch_pool);
-  svn_skel__prepend_int(kind, work_item, scratch_pool);
-  svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_DELETE, work_item, scratch_pool);
-
-  SVN_ERR(svn_wc__db_wq_add(db, parent_abspath, work_item, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
 /* OP_FILE_INSTALL */
 
 /* Process the OP_FILE_INSTALL work item WORK_ITEM.
@@ -2003,8 +1857,7 @@ run_file_move(svn_wc__db_t *db,
   err = svn_io_file_move(src_abspath, dst_abspath, scratch_pool);
 
   /* If the source is not found, we assume the wq op is already handled */
-  if (err && (APR_STATUS_IS_ENOENT(err->apr_err) 
-              || APR_STATUS_IS_ENODIR(err->apr_err)))
+  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
     svn_error_clear(err);
   else
     SVN_ERR(err);
@@ -2245,85 +2098,6 @@ svn_wc__wq_build_prej_install(svn_skel_t
 
 /* ------------------------------------------------------------------------ */
 
-/* OP_WRITE_OLD_PROPS  */
-
-
-static svn_error_t *
-run_write_old_props(svn_wc__db_t *db,
-                    const svn_skel_t *work_item,
-                    const char *wri_abspath,
-                    svn_cancel_func_t cancel_func,
-                    void *cancel_baton,
-                    apr_pool_t *scratch_pool)
-{
-  const svn_skel_t *arg1 = work_item->children->next;
-  const char *props_abspath;
-  svn_stream_t *stream;
-  apr_hash_t *props;
-
-  props_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
-
-  /* Torch whatever may be there.  */
-  SVN_ERR(svn_io_remove_file2(props_abspath, TRUE, scratch_pool));
-
-  if (arg1->next == NULL)
-    {
-      /* PROPS == NULL means the file should be removed. Note that an
-         empty set of properties has an entirely different meaning.
-
-         The file has already been removed. Simply exit.  */
-      return SVN_NO_ERROR;
-    }
-  SVN_ERR(svn_skel__parse_proplist(&props, arg1->next, scratch_pool));
-
-  SVN_ERR(svn_stream_open_writable(&stream, props_abspath,
-                                   scratch_pool, scratch_pool));
-
-  /* An empty file is shorthand for an empty set of properties.  */
-  if (apr_hash_count(props) != 0)
-    SVN_ERR(svn_hash_write2(props, stream, SVN_HASH_TERMINATOR, scratch_pool));
-
-  SVN_ERR(svn_stream_close(stream));
-
-  SVN_ERR(svn_io_set_file_read_only(props_abspath,
-                                    FALSE /* ignore_enoent */,
-                                    scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__wq_build_write_old_props(svn_skel_t **work_item,
-                                 const char *props_abspath,
-                                 apr_hash_t *props,
-                                 apr_pool_t *result_pool)
-{
-#if (SVN_WC__VERSION >= SVN_WC__PROPS_IN_DB)
-  *work_item = NULL;
-#else
-  *work_item = svn_skel__make_empty_list(result_pool);
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(props_abspath));
-
-  if (props != NULL)
-    {
-      svn_skel_t *props_skel;
-
-      SVN_ERR(svn_skel__unparse_proplist(&props_skel, props, result_pool));
-      svn_skel__prepend(props_skel, *work_item);
-    }
-  svn_skel__prepend_str(apr_pstrdup(result_pool, props_abspath),
-                        *work_item, result_pool);
-  svn_skel__prepend_str(OP_WRITE_OLD_PROPS, *work_item, result_pool);
-#endif
-
-  return SVN_NO_ERROR;
-}
-
-
-/* ------------------------------------------------------------------------ */
-
 /* OP_RECORD_FILEINFO  */
 
 
@@ -2606,27 +2380,22 @@ svn_wc__wq_build_pristine_get_translated
 
 static const struct work_item_dispatch dispatch_table[] = {
   { OP_REVERT, run_revert },
-  { OP_PREPARE_REVERT_FILES, run_prepare_revert_files },
-  { OP_KILLME, run_killme },
-  { OP_LOGGY, run_loggy },
   { OP_DELETION_POSTCOMMIT, run_deletion_postcommit },
   { OP_POSTCOMMIT, run_postcommit },
-  { OP_DELETE, run_delete },
   { OP_FILE_INSTALL, run_file_install },
   { OP_FILE_REMOVE, run_file_remove },
   { OP_FILE_MOVE, run_file_move },
   { OP_FILE_COPY_TRANSLATED, run_file_copy_translated },
   { OP_SYNC_FILE_FLAGS, run_sync_file_flags },
   { OP_PREJ_INSTALL, run_prej_install },
-  { OP_WRITE_OLD_PROPS, run_write_old_props },
   { OP_RECORD_FILEINFO, run_record_fileinfo },
+  { OP_BASE_REMOVE, run_base_remove },
   { OP_TMP_SET_TEXT_CONFLICT_MARKERS, run_set_text_conflict_markers },
   { OP_TMP_SET_PROPERTY_CONFLICT_MARKER, run_set_property_conflict_marker },
   { OP_PRISTINE_GET_TRANSLATED, run_pristine_get_translated },
 
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-  { OP_INSTALL_PROPERTIES, run_install_properties },
+#ifndef SVN_WC__SINGLE_DB
+  { OP_KILLME, run_killme },
 #endif
 
   /* Sentinel.  */

Modified: subversion/branches/performance/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/workqueue.h?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/performance/subversion/libsvn_wc/workqueue.h Mon Sep  6 20:02:15 2010
@@ -173,18 +173,6 @@ svn_wc__wq_build_prej_install(svn_skel_t
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool);
 
-
-/* Set *WORK_ITEM to a new work item that will install PROPS at PROPS_ABSPATH.
-   If PROPS is NULL, then the target props file will will be removed.
-
-   ### this will go away when we fully move to in-db properties.  */
-svn_error_t *
-svn_wc__wq_build_write_old_props(svn_skel_t **work_item,
-                                 const char *props_abspath,
-                                 apr_hash_t *props,
-                                 apr_pool_t *result_pool);
-
-
 /* Set *WORK_ITEM to a new work item that will record file information of
    LOCAL_ABSPATH into the TRANSLATED_SIZE and LAST_MOD_TIME of the node via
    the svn_wc__db_global_record_fileinfo() function.
@@ -208,15 +196,24 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
                       svn_boolean_t use_commit_times,
                       apr_pool_t *scratch_pool);
 
+/* Set *WORK_ITEM to a new work item that will remove all the data of
+   the BASE_NODE of LOCAL_ABSPATH and all it's descendants, but keeping
+   any WORKING_NODE data.
 
-/* Record a work item to prepare the "revert props" and "revert text base"
-   for LOCAL_ABSPATH.  */
-svn_error_t *
-svn_wc__wq_prepare_revert_files(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool);
+   This function doesn't check for local modifications of the text files
+   as these would have triggered a tree conflict before.
 
+   ### This is only used from update_editor.c's do_entry_deletion().
+ */
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+                             svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t keep_not_present,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
 
+#ifndef SVN_WC__SINGLE_DB
 /* Handle the old "KILLME" concept -- perform the actual deletion of a
    subdir (or just its admin area) during post-commit processing of a
    deleted subdir.  */
@@ -225,24 +222,7 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
                       const char *adm_abspath,
                       svn_boolean_t adm_only,
                       apr_pool_t *scratch_pool);
-
-
-/* ### temporary compat for mapping the old loggy into workqueue space.
-
-   Set *WORK_ITEM to a new work item ...
-
-   LOG_CONTENT may be NULL or reference an empty log.  Set *WORK_ITEM to
-   NULL in this case.
-
-   NOTE: ADM_ABSPATH and LOG_CONTENT must live at least as long as
-   RESULT_POOL (typically, they'll be allocated within RESULT_POOL).
-*/
-svn_error_t *
-svn_wc__wq_build_loggy(svn_skel_t **work_item,
-                       svn_wc__db_t *db,
-                       const char *adm_abspath,
-                       const svn_stringbuf_t *log_content,
-                       apr_pool_t *result_pool);
+#endif
 
 
 /* ### Temporary helper to store text conflict marker locations as a wq
@@ -321,35 +301,6 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
                           svn_boolean_t no_unlock,
                           apr_pool_t *scratch_pool);
 
-
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-svn_error_t *
-svn_wc__wq_add_install_properties(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  apr_hash_t *pristine_props,
-                                  apr_hash_t *actual_props,
-                                  apr_pool_t *scratch_pool);
-#endif
-
-/* Add a work item to delete a node.
-
-   ### LOCAL_ABSPATH is the node to be deleted and the queue exists in
-   PARENT_ABSPATH (because when LOCAL_ABSPATH is a directory it might
-   not exist on disk).  This use of PARENT_ABSPATH is inherited from
-   the log file conversion but perhaps we don't need to use a work
-   queue when deleting a directory that does not exist on disk.
- */
-svn_error_t *
-svn_wc__wq_add_delete(svn_wc__db_t *db,
-                      const char *parent_abspath,
-                      const char *local_abspath,
-                      svn_wc__db_kind_t kind,
-                      svn_boolean_t was_added,
-                      svn_boolean_t was_copied,
-                      svn_boolean_t was_replaced,
-                      apr_pool_t *scratch_pool);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/performance/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/dav_svn.h?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/dav_svn.h Mon Sep  6 20:02:15 2010
@@ -37,6 +37,7 @@
 #include "svn_path.h"
 #include "svn_xml.h"
 #include "private/svn_dav_protocol.h"
+#include "private/svn_skel.h"
 #include "mod_authz_svn.h"
 
 #ifdef __cplusplus
@@ -419,7 +420,7 @@ dav_svn__store_activity(const dav_svn_re
                         const char *txn_name);
 
 
-/* HTTP protocol v2:  client does POST against 'me' resource. */
+/* POST request handler.  (Used by HTTP protocol v2 clients only.)  */
 int dav_svn__method_post(request_rec *r);
 
 
@@ -640,6 +641,23 @@ dav_svn__get_deleted_rev_report(const da
                                 const apr_xml_doc *doc,
                                 ap_filter_t *output);
 
+
+/*** posts/ ***/
+
+/* The list of Subversion's custom POSTs. */
+/* ### should move these report names to a public header to share with
+   ### the client (and third parties). */
+static const char * dav_svn__posts_list[] = {
+  "create-txn",
+  NULL
+};
+
+/* The various POST handlers, defined in posts/, and used by repos.c.  */
+dav_error *
+dav_svn__post_create_txn(const dav_resource *resource,
+                         svn_skel_t *request_skel,
+                         ap_filter_t *output);
+
 /*** authz.c ***/
 
 /* A baton needed by dav_svn__authz_read_func(). */
@@ -890,6 +908,13 @@ dav_svn__final_flush_or_error(request_re
  */
 int dav_svn__error_response_tag(request_rec *r, dav_error *err);
 
+
+/* Set *SKEL to a parsed skel read from the body of request R, and
+ * allocated in POOL.
+ */
+int dav_svn__parse_request_skel(svn_skel_t **skel, request_rec *r,
+                                apr_pool_t *pool);
+
 /*** mirror.c ***/
 
 /* Perform the fixup hook for the R request.  */

Modified: subversion/branches/performance/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/deadprops.c?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/deadprops.c Mon Sep  6 20:02:15 2010
@@ -389,7 +389,7 @@ db_output_value(dav_db *db,
           const svn_string_t *enc_propval
             = svn_base64_encode_string2(propval, TRUE, pool);
           xml_safe = enc_propval->data;
-          encoding = apr_pstrcat(pool, " V:encoding=\"base64\"", NULL);
+          encoding = " V:encoding=\"base64\"";
         }
       else
         {
@@ -424,23 +424,15 @@ db_map_namespaces(dav_db *db,
 
 
 static dav_error *
-db_store(dav_db *db,
-         const dav_prop_name *name,
-         const apr_xml_elem *elem,
-         dav_namespace_map *mapping)
+decode_property_value(const svn_string_t **out_propval_p,
+                      const svn_string_t *maybe_encoded_propval,
+                      const apr_xml_elem *elem,
+                      apr_pool_t *pool)
 {
-  const svn_string_t *propval;
-  apr_pool_t *pool = db->p;
   apr_xml_attr *attr = elem->attr;
 
-  /* SVN sends property values as a big blob of bytes. Thus, there should be
-     no child elements of the property-name element. That also means that
-     the entire contents of the blob is located in elem->first_cdata. The
-     dav_xml_get_cdata() will figure it all out for us, but (normally) it
-     should be awfully fast and not need to copy any data. */
-
-  propval = svn_string_create
-    (dav_xml_get_cdata(elem, pool, 0 /* strip_white */), pool);
+  /* Default: no "encoding" attribute. */
+  *out_propval_p = maybe_encoded_propval;
 
   /* Check for special encodings of the property value. */
   while (attr)
@@ -451,7 +443,7 @@ db_store(dav_db *db,
 
           /* Handle known encodings here. */
           if (enc_type && (strcmp(enc_type, "base64") == 0))
-            propval = svn_base64_decode_string(propval, pool);
+            *out_propval_p = svn_base64_decode_string(maybe_encoded_propval, pool);
           else
             return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                                  "Unknown property encoding");
@@ -461,6 +453,32 @@ db_store(dav_db *db,
       attr = attr->next;
     }
 
+  return NULL;
+}
+
+static dav_error *
+db_store(dav_db *db,
+         const dav_prop_name *name,
+         const apr_xml_elem *elem,
+         dav_namespace_map *mapping)
+{
+  const svn_string_t *propval;
+  apr_pool_t *pool = db->p;
+  dav_error *derr;
+
+  /* SVN sends property values as a big blob of bytes. Thus, there should be
+     no child elements of the property-name element. That also means that
+     the entire contents of the blob is located in elem->first_cdata. The
+     dav_xml_get_cdata() will figure it all out for us, but (normally) it
+     should be awfully fast and not need to copy any data. */
+
+  propval = svn_string_create
+    (dav_xml_get_cdata(elem, pool, 0 /* strip_white */), pool);
+
+  derr = decode_property_value(&propval, propval, elem, pool);
+  if (derr)
+    return derr;
+
   return save_value(db, name, propval);
 }
 

Propchange: subversion/branches/performance/subversion/mod_dav_svn/posts/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Sep  6 20:02:15 2010
@@ -0,0 +1 @@
+.libs

Modified: subversion/branches/performance/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/reports/update.c?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/reports/update.c Mon Sep  6 20:02:15 2010
@@ -782,6 +782,8 @@ struct window_handler_baton
   svn_boolean_t seen_first_window;  /* False until first window seen. */
   update_ctx_t *uc;
 
+  const char *base_checksum; /* For transfer as part of the S:txdelta element */
+
   /* The _real_ window handler and baton. */
   svn_txdelta_window_handler_t handler;
   void *handler_baton;
@@ -797,7 +799,14 @@ window_handler(svn_txdelta_window_t *win
   if (! wb->seen_first_window)
     {
       wb->seen_first_window = TRUE;
-      SVN_ERR(dav_svn__brigade_puts(wb->uc->bb, wb->uc->output, "<S:txdelta>"));
+
+      if (!wb->base_checksum)
+        SVN_ERR(dav_svn__brigade_puts(wb->uc->bb, wb->uc->output,
+                                      "<S:txdelta>"));
+      else
+        SVN_ERR(dav_svn__brigade_printf(wb->uc->bb, wb->uc->output,
+                                        "<S:txdelta base-checksum=\"%s\">",
+                                        wb->base_checksum));
     }
 
   SVN_ERR(wb->handler(window, wb->handler_baton));
@@ -850,6 +859,7 @@ upd_apply_textdelta(void *file_baton,
   wb = apr_palloc(file->pool, sizeof(*wb));
   wb->seen_first_window = FALSE;
   wb->uc = file->uc;
+  wb->base_checksum = file->base_checksum;
   base64_stream = dav_svn__make_base64_output_stream(wb->uc->bb,
                                                      wb->uc->output,
                                                      file->pool);

Modified: subversion/branches/performance/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/repos.c?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/repos.c Mon Sep  6 20:02:15 2010
@@ -3391,7 +3391,8 @@ deliver(const dav_resource *resource, ap
               */
               ap_fputs(output, bb,
                        " </ul>\n <hr noshade><em>Powered by "
-                       "<a href=\"http://subversion.apache.org/\">Subversion"
+                       "<a href=\"http://subversion.apache.org/\">"
+                       "Apache Subversion"
                        "</a> version " SVN_VERSION "."
                        "</em>\n</body></html>");
             }
@@ -4263,58 +4264,73 @@ dav_svn__create_version_resource(dav_res
 }
 
 
-/* POST handler for HTTP protocol v2.
- 
-   Currently we allow POSTs only against the "me resource", which may
-   in the future act as a dispatcher of sorts for handling potentially
-   many different kinds of operations as specified by the body of the
-   POST request itself.
-
-   ### TODO: Define what the format of those POST bodies might be.  If
-   ### XML, we have access to Apache's streamy XML parsing code, but
-   ### ... it's XML.  Meh.  If skels, we get skels!  But we need to
-   ### write our own streamy skel parsing routine around a brigade
-   ### read loop.  Ewww...
-   ###
-   ### Today we only support transaction creation requests, but we
-   ### could conceivable support the likes of a multi-path lock
-   ### and/or unlock request, or some other thing for which stock
-   ### WebDAV doesn't work or doesn't work well enough.
-   ###
-   ### Fortunately, today we don't use the POST body at all, and we'll
-   ### be able to get away with not defining the body format in the
-   ### future thanks to the following:
-
-   As a special consideration, an empty POST body is interpreted as a
-   simple request to create a new commit transaction based on the HEAD
-   revision.  The new transaction name will be returned via a custom
-   response header SVN_DAV_TXN_NAME_HEADER.
-*/
+
+static dav_error *
+handle_post_request(request_rec *r,
+                    dav_resource *resource,
+                    ap_filter_t *output)
+{
+  svn_skel_t *request_skel;
+  int status;
+  apr_pool_t *pool = resource->pool;
+
+  /* Make sure our skel-based request parses okay, has an initial atom
+     that identifies what kind of action is expected, and that that
+     action is something we understand.  */
+  status = dav_svn__parse_request_skel(&request_skel, r, pool);
+
+  if (status != OK)
+    return dav_new_error(pool, status, 0,
+                         "Error parsing skel POST request body.");
+
+  if (svn_skel__list_length(request_skel) < 1)
+    return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
+                         "Unable to identify skel POST request flavor.");
+
+  if (svn_skel__matches_atom(request_skel->children, "create-txn"))
+    {
+      return dav_svn__post_create_txn(resource, request_skel, output);
+    }
+  else
+    {
+      return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
+                           "Unsupported skel POST request flavor.");
+    }
+  /* NOTREACHED */
+}
+
 int dav_svn__method_post(request_rec *r)
 {
   dav_resource *resource;
   dav_error *derr;
-  const char *txn_name;
+  const char *content_type;
 
+  /* We only allow POSTs against the "me resource" right now. */
   derr = get_resource(r, dav_svn__get_root_dir(r),
                       "ignored", 0, &resource);
   if (derr != NULL)
     return derr->status;
-
   if (resource->info->restype != DAV_SVN_RESTYPE_ME)
     return HTTP_BAD_REQUEST;
 
-  /* Create a Subversion repository transaction based on HEAD. */
-  derr = dav_svn__create_txn(resource->info->repos, &txn_name, resource->pool);
+  /* Pass skel-type POST request handling off to a dispatcher; any
+     other type of request is considered bogus. */
+  content_type = apr_table_get(r->headers_in, "content-type");
+  if (content_type && (strcmp(content_type, SVN_SKEL_MIME_TYPE) == 0))
+    {
+      derr = handle_post_request(r, resource, r->output_filters);
+    }
+  else
+    {
+      derr = dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                           "Unsupported POST request type.");
+    }
+
+  /* If something went wrong above, we'll generate a response back to
+     the client with (hopefully) some helpful information. */
   if (derr)
     return dav_svn__error_response_tag(r, derr);
-
-  /* Build a "201 Created" response with header that tells the client
-     our new transaction's name. */
-  apr_table_set(resource->info->r->headers_out, SVN_DAV_TXN_NAME_HEADER,
-                txn_name);
-  r->status = HTTP_CREATED;
-
+    
   return OK;
 }
 

Modified: subversion/branches/performance/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/util.c?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/util.c Mon Sep  6 20:02:15 2010
@@ -28,6 +28,7 @@
 
 #include <mod_dav.h>
 #include <http_protocol.h>
+#include <http_core.h>
 
 #include "svn_error.h"
 #include "svn_fs.h"
@@ -611,3 +612,140 @@ dav_svn__error_response_tag(request_rec 
    */
   return DONE;
 }
+
+
+/* Set *REQUEST_STR to a string containing the contents of the body of
+   request R, allocated from POOL.
+
+   NOTE: This was shamelessly stolen and modified from Apache's
+   ap_xml_parse_input().  */
+static int
+request_body_to_string(svn_string_t **request_str,
+                       request_rec *r,
+                       apr_pool_t *pool)
+{
+  apr_bucket_brigade *brigade;
+  int seen_eos;
+  apr_status_t status;
+  apr_off_t total_read = 0;
+  apr_off_t limit_req_body = ap_get_limit_req_body(r);
+  int result = HTTP_BAD_REQUEST;
+  const char *content_length_str;
+  char *endp;
+  apr_off_t content_length;
+  svn_stringbuf_t *buf;
+
+  *request_str = NULL;
+
+  content_length_str = apr_table_get(r->headers_in, "Content-Length");
+  if (content_length_str)
+    {
+      if (apr_strtoff(&content_length, content_length_str, &endp, 10)
+          || endp == content_length_str || *endp || content_length < 0)
+        {
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid Content-Length");
+          return HTTP_REQUEST_ENTITY_TOO_LARGE;
+        }
+    }
+  else
+    content_length = 0;
+
+  if (limit_req_body && (limit_req_body < content_length))
+    {
+      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                    "Requested content-length of %" APR_OFF_T_FMT " is larger "
+                    "than the configured limit of %" APR_OFF_T_FMT,
+                    content_length, limit_req_body);
+      return HTTP_REQUEST_ENTITY_TOO_LARGE;
+    }
+
+  if (content_length)
+    {
+      buf = svn_stringbuf_create_ensure(content_length, pool);
+    }
+  else
+    {
+      buf = svn_stringbuf_create("", pool);
+    }
+
+  brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+  seen_eos = 0;
+  total_read = 0;
+
+  do
+    {
+      apr_bucket *bucket;
+
+      status = ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES,
+                              APR_BLOCK_READ, 2048);
+      if (status != APR_SUCCESS)
+        goto cleanup;
+
+      for (bucket = APR_BRIGADE_FIRST(brigade);
+           bucket != APR_BRIGADE_SENTINEL(brigade);
+           bucket = APR_BUCKET_NEXT(bucket))
+        {
+          const char *data;
+          apr_size_t len;
+          
+          if (APR_BUCKET_IS_EOS(bucket))
+            {
+              seen_eos = 1;
+              break;
+            }
+          
+          if (APR_BUCKET_IS_METADATA(bucket))
+            continue;
+          
+          status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+          if (status != APR_SUCCESS)
+            goto cleanup;
+          
+          total_read += len;
+          if (limit_req_body && total_read > limit_req_body)
+            {
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                            "Request body is larger than the configured "
+                            "limit of %lu", (unsigned long)limit_req_body);
+              result = HTTP_REQUEST_ENTITY_TOO_LARGE;
+              goto cleanup;
+            }
+          
+          svn_stringbuf_appendbytes(buf, data, len);
+        }
+      
+      apr_brigade_cleanup(brigade);
+    }
+  while (!seen_eos);
+
+  apr_brigade_destroy(brigade);
+
+  /* Make an svn_string_t from our svn_stringbuf_t. */
+  *request_str = svn_string_create("", pool);
+  (*request_str)->data = buf->data;
+  (*request_str)->len = buf->len;
+  return OK;
+
+ cleanup:
+  apr_brigade_destroy(brigade);
+  
+  /* Apache will supply a default error, plus the error log above. */
+  return result;
+}
+
+int
+dav_svn__parse_request_skel(svn_skel_t **skel,
+                            request_rec *r,
+                            apr_pool_t *pool)
+{
+  svn_string_t *skel_str;
+  int status;
+
+  *skel = NULL;
+  status = request_body_to_string(&skel_str, r, pool);
+  if (status != OK)
+    return OK;
+
+  *skel = svn_skel__parse(skel_str->data, skel_str->len, pool);
+  return OK;
+}

Modified: subversion/branches/performance/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/version.c?rev=993141&r1=993140&r2=993141&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/version.c Mon Sep  6 20:02:15 2010
@@ -41,6 +41,7 @@
 #include "private/svn_log.h"
 
 #include "dav_svn.h"
+#include "mod_dav_svn.h"
 
 
 svn_error_t *
@@ -1014,6 +1015,22 @@ deliver_report(request_rec *r,
 
   if (doc->root->ns == ns)
     {
+      const char *cleaned_uri, *relative_path, *repos_path;
+      int trailing_slash;
+      /* During SVNPathAuthz short_circuit
+       * resource->info->repos->repo_name becomes NULL.*/
+      if (resource->info->repos->repo_name == NULL)
+        {
+          dav_error *err;
+          err = dav_svn_split_uri(r, r->uri, dav_svn__get_root_dir(r),
+                                  &cleaned_uri, &trailing_slash,
+                                  &(resource->info->repos->repo_name), 
+                                  &relative_path, &repos_path);
+          if (err)
+            {
+              return err;
+            }
+        }
       /* ### note that these report names should have symbols... */
 
       if (strcmp(doc->root->name, "update-report") == 0)