subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ne...@apache.org
Subject svn commit: r1158491 - in /subversion/trunk/subversion: include/svn_client.h include/svn_wc.h libsvn_client/status.c libsvn_wc/status.c libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c libsvn_wc/wc_db.h svn/status.c
Date Wed, 17 Aug 2011 02:45:42 GMT
Author: neels
Date: Wed Aug 17 02:45:42 2011
New Revision: 1158491

URL: http://svn.apache.org/viewvc?rev=1158491&view=rev
Log:
Follow-up to r1157292.
Optimize obtaining moved-to and moved-from for status by querying per-dir
where possible (suggested by: rhujiben). The original patch is modified so
that the status structs for nodes return moved-* information *only* on the
roots of a move, and *not* on their moved-along children. (I had intended to
return these on all moved nodes, but that does not perform well at all.)

* subversion/include/svn_client.h (svn_client_status_t),
* subversion/include/svn_wc.h (svn_wc_status3_t):
    Remove MOVED_TO_OP_ROOT_ABSPATH. Tweak comments for the other two MOVED_*
    members (identical changes to both of these status related structs).

* subversion/libsvn_client/status.c
  (svn_client_status_dup, svn_client__create_status):
    Apply removal of MOVED_TO_OP_ROOT_ABSPATH.

* subversion/libsvn_wc/status.c
  (read_info):
    Use suboptimal ways to get MOVED_TO_ABSPATH and MOVED_HERE flag, until
    better ways have been charted (only done for non-recursive status).
  (assemble_status):
    Remove the expensive scan_* calls for the benefit of the information
    available from the per-dir status query. Scan the full MOVED_FROM_ABSPATH
    *only* when MOVED_HERE is TRUE on an op-root.
  (svn_wc_dup_status3):
    Apply removal of MOVED_TO_OP_ROOT_ABSPATH.

* subversion/libsvn_wc/wc_db.c
  (read_children_info):
    Return MOVED_TO_ABSPATH and MOVED_HERE via the modified
    STMT_SELECT_NODE_CHILDREN_INFO query (s.b.).

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_info_t): Add MOVED_TO_ABSPATH and MOVED_HERE.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_NODE_CHILDREN_INFO):
    Also select columns MOVED_HERE and MOVED_TO.

* subversion/svn/status.c
  (print_status):
    Simplify condition as that decision is now taken elsewhere.
    

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_client/status.c
    subversion/trunk/subversion/libsvn_wc/status.c
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h
    subversion/trunk/subversion/svn/status.c

Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Wed Aug 17 02:45:42 2011
@@ -2207,18 +2207,38 @@ typedef struct svn_client_status_t
   const void *backwards_compatibility_baton;
 
   /** Set to the local absolute path that this node was moved from, if this
-   * file or directory has been moved here locally. */
+   * file or directory has been moved here locally and is the root of that
+   * move. Otherwise set to NULL.
+   *
+   * This will be NULL for moved-here nodes that are just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   * 
+   * @since New in 1.8. */
   const char *moved_from_abspath;
 
   /** Set to the local absolute path that this node was moved to, if this file
-   * or directory has been moved away locally. */
+   * or directory has been moved away locally and corresponds to the root
+   * of the destination side of the move. Otherwise set to NULL.
+   *
+   * Note: Saying just "root" here could be misleading. For example:
+   *   svn mv A AA;
+   *   svn mv AA/B BB;
+   * creates a situation where A/B is moved-to BB, but one could argue that
+   * the move source's root actually was AA/B. Note that, as far as the
+   * working copy is concerned, above case is exactly identical to:
+   *   svn mv A/B BB;
+   *   svn mv A AA;
+   * In both situations, @a moved_to_abspath would be set for nodes A (moved
+   * to AA) and A/B (moved to BB), only.
+   *
+   * This will be NULL for moved-away nodes that were just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   *
+   * @since New in 1.8. */
   const char *moved_to_abspath;
 
-  /* If this file or directory has been moved away locally, set this to the
-   * local absolute path that was the root of the move-away, i.e. to the
-   * op-root of the delete-half of the move operation. */
-  const char *moved_to_op_root_abspath;
-
   /* NOTE! Please update svn_client_status_dup() when adding new fields here. */
 } svn_client_status_t;
 

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Wed Aug 17 02:45:42 2011
@@ -3618,18 +3618,38 @@ typedef struct svn_wc_status3_t
   /** @} */
 
   /** Set to the local absolute path that this node was moved from, if this
-   * file or directory has been moved here locally. */
+   * file or directory has been moved here locally and is the root of that
+   * move. Otherwise set to NULL.
+   *
+   * This will be NULL for moved-here nodes that are just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   * 
+   * @since New in 1.8. */
   const char *moved_from_abspath;
 
   /** Set to the local absolute path that this node was moved to, if this file
-   * or directory has been moved away locally. */
+   * or directory has been moved away locally and corresponds to the root
+   * of the destination side of the move. Otherwise set to NULL.
+   *
+   * Note: Saying just "root" here could be misleading. For example:
+   *   svn mv A AA;
+   *   svn mv AA/B BB;
+   * creates a situation where A/B is moved-to BB, but one could argue that
+   * the move source's root actually was AA/B. Note that, as far as the
+   * working copy is concerned, above case is exactly identical to:
+   *   svn mv A/B BB;
+   *   svn mv A AA;
+   * In both situations, @a moved_to_abspath would be set for nodes A (moved
+   * to AA) and A/B (moved to BB), only.
+   *
+   * This will be NULL for moved-away nodes that were just part of a subtree
+   * that was moved along (and are not themselves a root of a different move
+   * operation).
+   *
+   * @since New in 1.8. */
   const char *moved_to_abspath;
 
-  /* If this file or directory has been moved away locally, set this to the
-   * local absolute path that was the root of the move-away, i.e. to the
-   * op-root of the delete-half of the move operation. */
-  const char *moved_to_op_root_abspath;
-
   /* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */
 } svn_wc_status3_t;
 

Modified: subversion/trunk/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/status.c?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/status.c (original)
+++ subversion/trunk/subversion/libsvn_client/status.c Wed Aug 17 02:45:42 2011
@@ -570,10 +570,6 @@ svn_client_status_dup(const svn_client_s
   if (status->moved_to_abspath)
     st->moved_to_abspath = apr_pstrdup(result_pool, status->moved_to_abspath);
 
-  if (status->moved_to_op_root_abspath)
-    st->moved_to_op_root_abspath =
-      apr_pstrdup(result_pool, status->moved_to_op_root_abspath);
-
   return st;
 }
 
@@ -680,7 +676,6 @@ svn_client__create_status(svn_client_sta
 
   (*cst)->moved_from_abspath = status->moved_from_abspath;
   (*cst)->moved_to_abspath = status->moved_to_abspath;
-  (*cst)->moved_to_op_root_abspath = status->moved_to_op_root_abspath;
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/status.c?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/status.c (original)
+++ subversion/trunk/subversion/libsvn_wc/status.c Wed Aug 17 02:45:42 2011
@@ -273,6 +273,68 @@ read_info(const struct svn_wc__db_info_t
                                        &mtb->lock, NULL, NULL,
                                        db, local_abspath,
                                        result_pool, scratch_pool));
+
+      if (mtb->status == svn_wc__db_status_deleted)
+        {
+          const char *moved_to_abspath;
+          const char *moved_to_op_root_abspath;
+          
+          /* NOTE: we can't use op-root-ness as a condition here since a base
+           * node can be the root of a move and still not be an explicit
+           * op-root (having a working node with op_depth == pathelements).
+           *
+           * Both these (almost identical) situations showcase this:
+           *   svn mv a/b bb
+           *   svn del a
+           * and
+           *   svn mv a aa  
+           *   svn mv aa/b bb
+           * In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0
+           * node at all, as its parent 'a' is locally deleted. */
+
+          SVN_ERR(svn_wc__db_scan_deletion(NULL,
+                                           &moved_to_abspath,
+                                           NULL,
+                                           &moved_to_op_root_abspath,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+          if (moved_to_abspath != NULL
+              && moved_to_op_root_abspath != NULL
+              && strcmp(moved_to_abspath, moved_to_op_root_abspath) == 0)
+            {
+              mtb->moved_to_abspath = apr_pstrdup(result_pool,
+                                                  moved_to_abspath);
+            }
+          /* ### ^^^ THIS SUCKS. For at least two reasons:
+           * 1) We scan the node deletion and that's technically not necessary.
+           *    We'd be fine to know if this is an actual root of a move.
+           * 2) From the elaborately calculated results, we backwards-guess
+           *    whether this is a root.
+           * It works ok, and this code only gets called when a node is an
+           * explicit target of a 'status'. But it would be better to do this
+           * differently.
+           * We could return moved-to via svn_wc__db_base_get_info() (called
+           * just above), but as moved-to is only intended to be returned for
+           * roots of a move, that doesn't fit too well. */
+        }
+    }
+
+  /* ### svn_wc__db_read_info() could easily return the moved-here flag. But
+   * for now... (The per-dir query for recursive status is far more optimal.)
+   * Note that this actually scans around to get the full path, for a bool.
+   * This bool then gets returned, later is evaluated, and if true leads to
+   * the same paths being scanned again. We'd want to obtain this bool here as
+   * cheaply as svn_wc__db_read_children_info() does. */
+  if (mtb->status == svn_wc__db_status_added)
+    {
+      const char *moved_from_abspath = NULL;
+      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL,
+                                       &moved_from_abspath,
+                                       NULL,
+                                       db, local_abspath,
+                                       result_pool, scratch_pool));
+      mtb->moved_here = (moved_from_abspath != NULL);
     }
 
   mtb->has_checksum = (checksum != NULL);
@@ -404,8 +466,6 @@ assemble_status(svn_wc_status3_t **statu
   const char *repos_root_url;
   const char *repos_uuid;
   const char *moved_from_abspath = NULL;
-  const char *moved_to_abspath = NULL;
-  const char *moved_to_op_root_abspath = NULL;
   svn_filesize_t filesize = (dirent && (dirent->kind == svn_node_file))
                                 ? dirent->filesize
                                 : SVN_INVALID_FILESIZE;
@@ -608,26 +668,20 @@ assemble_status(svn_wc_status3_t **statu
               else if (schedule == svn_wc_schedule_replace)
                 node_status = svn_wc_status_replaced;
             }
+
+          /* Get moved-from info (only for potential op-roots of a move). */
+          if (node_status == svn_wc_status_added
+              && info->moved_here
+              && info->op_root)
+            SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+                                             NULL, NULL, NULL, NULL,
+                                             &moved_from_abspath,
+                                             NULL,
+                                             db, local_abspath,
+                                             result_pool, scratch_pool));
         }
     }
 
-  /* Get moved-to info. */
-  if (info->status == svn_wc__db_status_deleted)
-    SVN_ERR(svn_wc__db_scan_deletion(NULL,
-                                     &moved_to_abspath,
-                                     NULL,
-                                     &moved_to_op_root_abspath,
-                                     db, local_abspath,
-                                     result_pool, scratch_pool));
-
-  /* Get moved-from info. */
-  if (info->status == svn_wc__db_status_added)
-    SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
-                                     NULL, NULL, NULL, NULL,
-                                     &moved_from_abspath,
-                                     NULL,
-                                     db, local_abspath,
-                                     result_pool, scratch_pool));
 
   if (node_status == svn_wc_status_normal)
     node_status = text_status;
@@ -722,8 +776,7 @@ assemble_status(svn_wc_status3_t **statu
   stat->repos_uuid = repos_uuid;
 
   stat->moved_from_abspath = moved_from_abspath;
-  stat->moved_to_abspath = moved_to_abspath;
-  stat->moved_to_op_root_abspath = moved_to_op_root_abspath;
+  stat->moved_to_abspath = info->moved_to_abspath;
 
   *status = stat;
 
@@ -2624,10 +2677,6 @@ svn_wc_dup_status3(const svn_wc_status3_
     new_stat->moved_to_abspath
       = apr_pstrdup(pool, orig_stat->moved_to_abspath);
 
-  if (orig_stat->moved_to_op_root_abspath)
-    new_stat->moved_to_op_root_abspath
-      = apr_pstrdup(pool, orig_stat->moved_to_op_root_abspath);
-
   /* Return the new hotness. */
   return new_stat;
 }

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Aug 17 02:45:42 2011
@@ -119,7 +119,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
   depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
-  lock_comment, lock_date, local_relpath
+  lock_comment, lock_date, local_relpath, moved_here, moved_to
 FROM nodes
 LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
   AND nodes.repos_path = lock.repos_relpath

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Aug 17 02:45:42 2011
@@ -7038,6 +7038,8 @@ read_children_info(void *baton,
 
       if (op_depth == 0)
         {
+          const char *moved_to_relpath;
+
           child_item->info.have_base = TRUE;
 
           /* Get the lock info. The query only reports lock info in the row at
@@ -7045,11 +7047,20 @@ read_children_info(void *baton,
           if (op_depth == 0)
             child_item->info.lock = lock_from_columns(stmt, 15, 16, 17, 18,
                                                       result_pool);
+
+          /* Moved-to is only stored at op_depth 0. */
+          moved_to_relpath = svn_sqlite__column_text(stmt, 21, NULL); 
+          if (moved_to_relpath)
+            child_item->info.moved_to_abspath =
+              svn_dirent_join(wcroot->abspath, moved_to_relpath, result_pool);
         }
       else
         {
           child_item->nr_layers++;
           child_item->info.have_more_work = (child_item->nr_layers > 1);
+
+          /* Moved-here can only exist at op_depth > 0. */
+          child_item->info.moved_here = svn_sqlite__column_boolean(stmt, 20);
         }
 
       err = svn_sqlite__step(&have_row, stmt);

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Aug 17 02:45:42 2011
@@ -1842,6 +1842,9 @@ struct svn_wc__db_info_t {
 
   svn_boolean_t locked;     /* WC directory lock */
   svn_wc__db_lock_t *lock;  /* Repository file lock */
+
+  const char *moved_to_abspath; /* Only on op-roots. See svn_wc_status3_t. */
+  svn_boolean_t moved_here;     /* On both op-roots and children. */
 };
 
 /* Return in *NODES a hash mapping name->struct svn_wc__db_info_t for

Modified: subversion/trunk/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/status.c?rev=1158491&r1=1158490&r2=1158491&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/status.c (original)
+++ subversion/trunk/subversion/svn/status.c Wed Aug 17 02:45:42 2011
@@ -272,6 +272,10 @@ print_status(const char *path,
         (*prop_conflicts)++;
     }
 
+  /* Note that moved-from and moved-to information is only available in STATUS
+   * for (op-)roots of a move. Those are exactly the nodes we want to show
+   * move info for in 'svn status'. See also comments in svn_wc_status3_t. */
+
   if (status->moved_from_abspath)
     {
       const char *cwd;
@@ -285,13 +289,7 @@ print_status(const char *path,
                                     (char *)NULL);
     }
 
-  /* Only print an extra moved-to line for the op-root of a move-away.
-   * As each and every child node of a deleted tree is printed in status
-   * output, each of them would be "duplicated" with a moved-to line. */
-  if (status->moved_to_abspath
-      && status->moved_to_op_root_abspath
-      && 0 == strcmp(status->moved_to_op_root_abspath,
-                     status->moved_to_abspath))
+  if (status->moved_to_abspath)
     {
       const char *cwd;
       const char *relpath;



Mime
View raw message