Author: rhuijben
Date: Fri Apr 15 11:03:48 2011
New Revision: 1092660

URL: http://svn.apache.org/viewvc?rev=1092660&view=rev
Log:
Instead of installing a wq operation to remove records from the database
in the commit processing, just perform the operation directly.

Working queue operations are for synchronizing the working copy with the
database. In this case the working copy doesn't change at all.

To make this work, change an existing wc_db temp operation recursive.
(It assumed that it was a leave operation before or it would break the DB)

* subversion/libsvn_wc/adm_ops.c
  (process_committed_leaf): Determine if we should really install a not present
    node and then call svn_wc__db_op_remove_node() instead of installing a
    wq operation that does the same thing.

  (svn_wc__internal_remove_from_revision_control): Don't perform expensive
    compares if we are not going to use the result. Update caller.

* subversion/libsvn_wc/crop.c
  (crop_children): Update caller.

* subversion/libsvn_wc/wc_db.c
  (remove_node_baton): New struct.
  (remove_node_txn): New function.
  (svn_wc__db_temp_op_remove_entry): Rename to ...
  (svn_wc__db_op_remove_node): ... this to reflect that the function is really
    needed and now recursive.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_temp_op_remove_entry): Rename to ...
  (svn_wc__db_op_remove_node): ... this to reflect that the function is really
    needed and now recursive.

Modified:
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/crop.c
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1092660&r1=1092659&r2=1092660&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Fri Apr 15 11:03:48 2011
@@ -127,8 +127,8 @@ process_committed_leaf(svn_wc__db_t *db,
   svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
   const svn_checksum_t *copied_checksum;
-  const char *adm_abspath;
   svn_revnum_t new_changed_rev = new_revnum;
+  svn_boolean_t have_base;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
@@ -137,21 +137,28 @@ process_committed_leaf(svn_wc__db_t *db,
                                NULL, NULL, NULL,
                                NULL, NULL, &copied_checksum,
                                NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL,
+                               &have_base, NULL, NULL, NULL,
                                db, local_abspath,
                                scratch_pool, scratch_pool));
 
-  if (kind == svn_wc__db_kind_dir)
-    adm_abspath = local_abspath;
-  else
-    adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-  SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
+  {
+    const char *adm_abspath;
+
+    if (kind == svn_wc__db_kind_dir)
+      adm_abspath = local_abspath;
+    else
+      adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+    SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
+  }
 
   if (status == svn_wc__db_status_deleted)
     {
-      return svn_error_return(svn_wc__wq_add_deletion_postcommit(
-                                db, local_abspath, new_revnum, no_unlock,
+      return svn_error_return(
+                svn_wc__db_op_remove_node(
+                                db, local_abspath, 
+                                have_base ? new_revnum : SVN_INVALID_REVNUM,
+                                kind,
                                 scratch_pool));
     }
 
@@ -1789,28 +1796,35 @@ svn_wc__internal_remove_from_revision_co
   if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
     {
       svn_node_kind_t on_disk;
-      svn_boolean_t wc_special, local_special;
       svn_boolean_t text_modified_p;
       const svn_checksum_t *base_sha1_checksum, *working_sha1_checksum;
 
-      /* Only check if the file was modified when it wasn't overwritten with a
-         special file */
-      SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
-                                         &wc_special, db, local_abspath, NULL,
-                                         scratch_pool, scratch_pool));
-      SVN_ERR(svn_io_check_special_path(local_abspath, &on_disk,
-                                        &local_special, scratch_pool));
-      if (wc_special || ! local_special)
+      if (instant_error || destroy_wf)
         {
-          /* Check for local mods. before removing entry */
-          SVN_ERR(svn_wc__internal_file_modified_p(&text_modified_p, NULL,
-                                                   NULL, db,
-                                                   local_abspath, FALSE,
-                                                   TRUE, scratch_pool));
-          if (text_modified_p && instant_error)
-            return svn_error_createf(SVN_ERR_WC_LEFT_LOCAL_MOD, NULL,
-                   _("File '%s' has local modifications"),
-                   svn_dirent_local_style(local_abspath, scratch_pool));
+          svn_boolean_t wc_special, local_special;
+          /* Only check if the file was modified when it wasn't overwritten
+             with a special file */
+
+          SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
+                                             &wc_special, db, local_abspath, 
NULL,
+                                             scratch_pool, scratch_pool));
+          SVN_ERR(svn_io_check_special_path(local_abspath, &on_disk,
+                                            &local_special, scratch_pool));
+          if (wc_special || ! local_special)
+            {
+              /* Check for local mods. before removing entry */
+              SVN_ERR(svn_wc__internal_file_modified_p(&text_modified_p, NULL,
+                                                       NULL, db,
+                                                       local_abspath, FALSE,
+                                                       TRUE, scratch_pool));
+              if (text_modified_p && instant_error)
+                return svn_error_createf(SVN_ERR_WC_LEFT_LOCAL_MOD, NULL,
+                       _("File '%s' has local modifications"),
+                       svn_dirent_local_style(local_abspath, scratch_pool));
+            }
+
+          if (! wc_special && local_special)
+            text_modified_p = TRUE;
         }
 
       /* Find the checksum(s) of the node's one or two pristine texts.  Note
@@ -1844,8 +1858,10 @@ svn_wc__internal_remove_from_revision_co
         SVN_ERR(err);
 
       /* Remove NAME from PATH's entries file: */
-      SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
-                                              scratch_pool));
+      SVN_ERR(svn_wc__db_op_remove_node(db, local_abspath,
+                                        SVN_INVALID_REVNUM,
+                                        svn_wc__db_kind_unknown,
+                                        scratch_pool));
 
       /* Having removed the checksums that reference the pristine texts,
          remove the pristine texts (if now totally unreferenced) from the
@@ -1869,7 +1885,7 @@ svn_wc__internal_remove_from_revision_co
       if (destroy_wf)
         {
           /* Don't kill local mods. */
-          if ((! wc_special && local_special) || text_modified_p)
+          if (text_modified_p)
             return svn_error_create(SVN_ERR_WC_LEFT_LOCAL_MOD, NULL, NULL);
           else  /* The working file is still present; remove it. */
             SVN_ERR(svn_io_remove_file2(local_abspath, TRUE, scratch_pool));
@@ -1907,8 +1923,10 @@ svn_wc__internal_remove_from_revision_co
                                          iterpool));
           if (hidden)
             {
-              SVN_ERR(svn_wc__db_temp_op_remove_entry(db, entry_abspath,
-                                                      iterpool));
+              SVN_ERR(svn_wc__db_op_remove_node(db, entry_abspath,
+                                                SVN_INVALID_REVNUM,
+                                                svn_wc__db_kind_unknown,
+                                                iterpool));
               continue;
             }
 
@@ -1948,8 +1966,10 @@ svn_wc__internal_remove_from_revision_co
            full_path.  We need to remove that entry: */
         if (! is_root)
           {
-            SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
-                                                    iterpool));
+            SVN_ERR(svn_wc__db_op_remove_node(db, local_abspath,
+                                              SVN_INVALID_REVNUM,
+                                              svn_wc__db_kind_unknown,
+                                              iterpool));
           }
       }
 

Modified: subversion/trunk/subversion/libsvn_wc/crop.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/crop.c?rev=1092660&r1=1092659&r2=1092660&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/crop.c (original)
+++ subversion/trunk/subversion/libsvn_wc/crop.c Fri Apr 15 11:03:48 2011
@@ -125,8 +125,10 @@ crop_children(svn_wc__db_t *db,
                                             ? svn_depth_immediates
                                             : svn_depth_files;
           if (depth < remove_below)
-            SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
-                                                    iterpool));
+            SVN_ERR(svn_wc__db_op_remove_node(db, local_abspath, FALSE,
+                                              SVN_INVALID_REVNUM,
+                                              svn_wc__db_kind_unknown,
+                                              iterpool));
 
           continue;
         }

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1092660&r1=1092659&r2=1092660&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri Apr 15 11:03:48 2011
@@ -4359,14 +4359,82 @@ svn_wc__db_op_read_tree_conflict(
   return SVN_NO_ERROR;
 }
 
+/* Baton for remove_post_commit_txn */
+struct remove_node_baton
+{
+  svn_revnum_t not_present_rev;
+  svn_wc__db_kind_t not_present_kind;
+};
+
+/* Implements svn_wc__db_txn_callback_t for svn_wc__db_op_remove_node */
+static svn_error_t *
+remove_node_txn(void *baton,
+                svn_wc__db_wcroot_t *wcroot,
+                const char *local_relpath,
+                apr_pool_t *scratch_pool)
+{
+  struct remove_node_baton *rnb = baton;
+  svn_sqlite__stmt_t *stmt;
+
+  apr_int64_t repos_id;
+  const char *repos_relpath;
+
+  const char *like_arg = construct_like_arg(local_relpath, scratch_pool);
+
+  SVN_ERR_ASSERT(*local_relpath != '\0'); /* Never on a wcroot */
+
+  /* Need info for not_present node? */
+  if (SVN_IS_VALID_REVNUM(rnb->not_present_rev))
+    SVN_ERR(scan_upwards_for_repos(&repos_id, &repos_relpath, wcroot,
+                                   local_relpath, scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_DELETE_NODES_RECURSIVE));
+
+  /* Remove all nodes at or below local_relpath where op_depth >= 0 */
+  SVN_ERR(svn_sqlite__bindf(stmt, "issi", wcroot->wc_id,
+                                          local_relpath,
+                                          like_arg,
+                                          (apr_int64_t)0));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_DELETE_ACTUAL_NODE_RECURSIVE));
+
+  /* Delete all actual nodes at or below local_relpath */
+  SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
+                                         local_relpath,
+                                         like_arg));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  /* Should we leave a not-present node? */
+  if (SVN_IS_VALID_REVNUM(rnb->not_present_rev))
+    {
+      insert_base_baton_t ibb;
+      blank_ibb(&ibb);
+
+      ibb.repos_id = repos_id;
+      ibb.status = svn_wc__db_status_not_present;
+      ibb.kind = rnb->not_present_kind;
+
+      ibb.repos_relpath = repos_relpath;
+      ibb.revision = rnb->not_present_rev;
+
+      SVN_ERR(insert_base_node(&ibb, wcroot, local_relpath, scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
-svn_wc__db_temp_op_remove_entry(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool)
+svn_wc__db_op_remove_node(svn_wc__db_t *db,
+                          const char *local_abspath,
+                          svn_revnum_t not_present_revision,
+                          svn_wc__db_kind_t not_present_kind,
+                          apr_pool_t *scratch_pool)
 {
   svn_wc__db_wcroot_t *wcroot;
-  svn_sqlite__stmt_t *stmt;
+  struct remove_node_baton rnb;
   const char *local_relpath;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -4375,17 +4443,15 @@ svn_wc__db_temp_op_remove_entry(svn_wc__
                               local_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
-  SVN_ERR(flush_entries(wcroot, local_abspath, scratch_pool));
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_DELETE_NODES));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step_done(stmt));
+  rnb.not_present_rev = not_present_revision;
+  rnb.not_present_kind = not_present_kind;
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, remove_node_txn,
+                              &rnb, scratch_pool));
 
-  SVN_ERR(svn_sqlite__step_done(stmt));
+  /* ### Flush everything below this node in all ways */
+  SVN_ERR(flush_entries(wcroot, local_abspath, scratch_pool));
+  SVN_ERR(svn_wc__db_temp_forget_directory(db, local_abspath, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1092660&r1=1092659&r2=1092660&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri Apr 15 11:03:48 2011
@@ -2424,12 +2424,21 @@ svn_wc__db_temp_forget_directory(svn_wc_
                                  const char *local_dir_abspath,
                                  apr_pool_t *scratch_pool);
 
-/* Removes all references of LOCAL_ABSPATH from its working copy
-   using DB. */
+/* Removes all references to LOCAL_ABSPATH from DB, while optionally leaving
+   tree conflicts and/or a not present node.
+
+   This operation always recursively removes all nodes at and below
+   LOCAL_ABSPATH from NODES and ACTUAL.
+
+   If NOT_PRESENT_REVISION specifies a valid revision, leave a not_present
+   BASE node at local_abspath. (Requires an existing BASE node before removing)
+ */
 svn_error_t *
-svn_wc__db_temp_op_remove_entry(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_pool_t *scratch_pool);
+svn_wc__db_op_remove_node(svn_wc__db_t *db,
+                          const char *local_abspath,
+                          svn_revnum_t not_present_revision,
+                          svn_wc__db_kind_t not_present_kind,
+                          apr_pool_t *scratch_pool);
 
 /* Remove the WORKING_NODE row of LOCAL_ABSPATH in DB. */
 svn_error_t *


Reply via email to