Author: rhuijben
Date: Sun May  8 02:48:33 2011
New Revision: 1100674

URL: http://svn.apache.org/viewvc?rev=1100674&view=rev
Log:
Simplify a lot of conditions in the adm crawler.

* subversion/libsvn_wc/adm_crawler.c
  (report_revisions_and_depths): Use an abspath as argument instead of
    calculating the abspath again. Rename path variable to show that it is a
    relpath. Handle the file external condition before everything else.
    Remove old obstruction check (which assumed that obstructed dirs
    would be skipped anyway). Update check when a node should be available.

  (find_base_rev): Remove function.

  (svn_wc_crawl_revisions5): When a node is not present in BASE, directly
    report that we don't know it instead of doing a lot of work and then
    report that we don't know it.

    Normalize target depth to infinity before using its value.

    Update check when a node should be available.

    Rename anchor depth to report depth and pass that as the value to compare
    against to report_revisions_and_depths.

    Just pass depth infinity for files and symlinks.
    (depth unknown is not supported here).

    Remove checks for values that can only be set in old error conditions.

Modified:
    subversion/trunk/subversion/libsvn_wc/adm_crawler.c

Modified: subversion/trunk/subversion/libsvn_wc/adm_crawler.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_crawler.c?rev=1100674&r1=1100673&r2=1100674&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_crawler.c Sun May  8 02:48:33 2011
@@ -231,14 +231,15 @@ read_externals_info(svn_wc__db_t *db,
 /* The recursive crawler that describes a mixed-revision working
    copy to an RA layer.  Used to initiate updates.
 
-   This is a depth-first recursive walk of DIR_PATH under ANCHOR_ABSPATH,
-   using DB.  Look at each entry and check if its revision is different
-   than DIR_REV.  If so, report this fact to REPORTER.  If an entry is
-   missing from disk, report its absence to REPORTER.  If an entry has
+   This is a depth-first recursive walk of DIR_ABSPATH using DB.  Look
+   at each entry and check if its revision is different than DIR_REV.
+   If so, report this fact to REPORTER.  If an entry is.  If a node has
    a different URL than expected, report that to REPORTER.  If an
    entry has a different depth than its parent, report that to
    REPORTER.
 
+   Report DIR_ABSPATH to the reporter as REPORT_RELPATH.
+
    Alternatively, if REPORT_EVERYTHING is set, then report all
    children unconditionally.
 
@@ -276,8 +277,8 @@ read_externals_info(svn_wc__db_t *db,
    passed to restore_file() helper. */
 static svn_error_t *
 report_revisions_and_depths(svn_wc__db_t *db,
-                            const char *anchor_abspath,
-                            const char *dir_path,
+                            const char *dir_abspath,
+                            const char *report_relpath,
                             svn_revnum_t dir_rev,
                             const char *dir_repos_relpath,
                             const char *dir_repos_root,
@@ -299,7 +300,6 @@ report_revisions_and_depths(svn_wc__db_t
                             void *notify_baton,
                             apr_pool_t *scratch_pool)
 {
-  const char *dir_abspath;
   apr_hash_t *base_children;
   apr_hash_t *dirents;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
@@ -310,7 +310,6 @@ report_revisions_and_depths(svn_wc__db_t
   /* Get both the SVN Entries and the actual on-disk entries.   Also
      notice that we're picking up hidden entries too (read_children never
      hides children). */
-  dir_abspath = svn_dirent_join(anchor_abspath, dir_path, scratch_pool);
   SVN_ERR(svn_wc__db_base_get_children_info(&base_children, db, dir_abspath,
                                             scratch_pool, iterpool));
 
@@ -345,7 +344,8 @@ report_revisions_and_depths(svn_wc__db_t
        hi = apr_hash_next(hi))
     {
       const char *child = svn__apr_hash_index_key(hi);
-      const char *this_path, *this_abspath;
+      const char *this_report_relpath;
+      const char *this_abspath;
       svn_boolean_t this_switched = FALSE;
       struct svn_wc__db_base_info_t *ths = svn__apr_hash_index_val(hi);
 
@@ -357,9 +357,16 @@ report_revisions_and_depths(svn_wc__db_t
       svn_pool_clear(iterpool);
 
       /* Compute the paths and URLs we need. */
-      this_path = svn_dirent_join(dir_path, child, iterpool);
+      this_report_relpath = svn_relpath_join(report_relpath, child, iterpool);
       this_abspath = svn_dirent_join(dir_abspath, child, iterpool);
 
+      /*** File Externals **/
+      if (ths->update_root)
+        {
+          /* File externals are ... special.  We ignore them. */;
+          continue;
+        }
+
       /* First check for exclusion */
       if (ths->status == svn_wc__db_status_excluded)
         {
@@ -375,7 +382,7 @@ report_revisions_and_depths(svn_wc__db_t
                  path. We explicitly prohibit this situation in
                  svn_wc_crop_tree(). */
               SVN_ERR(reporter->set_path(report_baton,
-                                         this_path,
+                                         this_report_relpath,
                                          dir_rev,
                                          svn_depth_exclude,
                                          FALSE,
@@ -388,7 +395,7 @@ report_revisions_and_depths(svn_wc__db_t
                  deleted, and server will respond properly. */
               if (! report_everything)
                 SVN_ERR(reporter->delete_path(report_baton,
-                                              this_path, iterpool));
+                                              this_report_relpath, iterpool));
             }
           continue;
         }
@@ -406,7 +413,8 @@ report_revisions_and_depths(svn_wc__db_t
              now available (an addition after a not-present state), or if
              it is now authorized (change in authz for the absent item).  */
           if (! report_everything)
-            SVN_ERR(reporter->delete_path(report_baton, this_path, iterpool));
+            SVN_ERR(reporter->delete_path(report_baton, this_report_relpath,
+                                          iterpool));
           continue;
         }
 
@@ -430,12 +438,9 @@ report_revisions_and_depths(svn_wc__db_t
                                              db, this_abspath,
                                              iterpool, iterpool));
 
-          if (restore_files
-              && wrk_status != svn_wc__db_status_added
-              && wrk_status != svn_wc__db_status_deleted
-              && wrk_status != svn_wc__db_status_excluded
-              && wrk_status != svn_wc__db_status_not_present
-              && wrk_status != svn_wc__db_status_absent)
+          if (wrk_status == svn_wc__db_status_normal
+              || wrk_status == svn_wc__db_status_copied
+              || wrk_status == svn_wc__db_status_moved_here)
             {
               svn_node_kind_t dirent_kind;
 
@@ -476,22 +481,8 @@ report_revisions_and_depths(svn_wc__db_t
       if (ths->depth == svn_depth_unknown)
         ths->depth = svn_depth_infinity;
 
-      /* Obstructed nodes might report SVN_INVALID_REVNUM. Tweak it.
-
-         ### it seems that obstructed nodes should be handled quite a
-         ### bit differently. maybe reported as missing, like not-present
-         ### or absent nodes?  */
-      if (!SVN_IS_VALID_REVNUM(ths->revnum))
-        ths->revnum = dir_rev;
-
-      /*** File Externals **/
-      if (ths->update_root)
-        {
-          /* File externals are ... special.  We ignore them. */;
-        }
-
       /*** Files ***/
-      else if (ths->kind == svn_wc__db_kind_file ||
+      if (ths->kind == svn_wc__db_kind_file ||
                ths->kind == svn_wc__db_kind_symlink)
         {
           if (report_everything)
@@ -499,7 +490,7 @@ report_revisions_and_depths(svn_wc__db_t
               /* Report the file unconditionally, one way or another. */
               if (this_switched)
                 SVN_ERR(reporter->link_path(report_baton,
-                                            this_path,
+                                            this_report_relpath,
                                             svn_path_url_add_component2(
                                                 dir_repos_root,
                                                 ths->repos_relpath, iterpool),
@@ -510,7 +501,7 @@ report_revisions_and_depths(svn_wc__db_t
                                             iterpool));
               else
                 SVN_ERR(reporter->set_path(report_baton,
-                                           this_path,
+                                           this_report_relpath,
                                            ths->revnum,
                                            ths->depth,
                                            FALSE,
@@ -521,7 +512,7 @@ report_revisions_and_depths(svn_wc__db_t
           /* Possibly report a disjoint URL ... */
           else if (this_switched)
             SVN_ERR(reporter->link_path(report_baton,
-                                        this_path,
+                                        this_report_relpath,
                                         svn_path_url_add_component2(
                                                 dir_repos_root,
                                                 ths->repos_relpath, iterpool),
@@ -536,7 +527,7 @@ report_revisions_and_depths(svn_wc__db_t
                    || ths->lock
                    || dir_depth == svn_depth_empty)
             SVN_ERR(reporter->set_path(report_baton,
-                                       this_path,
+                                       this_report_relpath,
                                        ths->revnum,
                                        ths->depth,
                                        FALSE,
@@ -567,7 +558,7 @@ report_revisions_and_depths(svn_wc__db_t
               /* Report the dir unconditionally, one way or another... */
               if (this_switched)
                 SVN_ERR(reporter->link_path(report_baton,
-                                            this_path,
+                                            this_report_relpath,
                                             svn_path_url_add_component2(
                                                 dir_repos_root,
                                                 ths->repos_relpath, iterpool),
@@ -579,7 +570,7 @@ report_revisions_and_depths(svn_wc__db_t
                                             iterpool));
               else
                 SVN_ERR(reporter->set_path(report_baton,
-                                           this_path,
+                                           this_report_relpath,
                                            ths->revnum,
                                            ths->depth,
                                            start_empty,
@@ -590,7 +581,7 @@ report_revisions_and_depths(svn_wc__db_t
             {
               /* ...or possibly report a disjoint URL ... */
               SVN_ERR(reporter->link_path(report_baton,
-                                          this_path,
+                                          this_report_relpath,
                                           svn_path_url_add_component2(
                                               dir_repos_root,
                                               ths->repos_relpath, iterpool),
@@ -617,7 +608,7 @@ report_revisions_and_depths(svn_wc__db_t
                  depth-empty.  Also describe shallow subdirs if we are
                  trying to set depth to infinity. */
               SVN_ERR(reporter->set_path(report_baton,
-                                         this_path,
+                                         this_report_relpath,
                                          ths->revnum,
                                          ths->depth,
                                          start_empty,
@@ -637,8 +628,8 @@ report_revisions_and_depths(svn_wc__db_t
                 }
 
               SVN_ERR(report_revisions_and_depths(db,
-                                                  anchor_abspath,
-                                                  this_path,
+                                                  this_abspath,
+                                                  this_report_relpath,
                                                   ths->revnum,
                                                   repos_relpath,
                                                   dir_repos_root,
@@ -665,67 +656,6 @@ report_revisions_and_depths(svn_wc__db_t
   return SVN_NO_ERROR;
 }
 
-/* Helper for svn_wc_crawl_revisions5() that finds a base revision for a node
-   that doesn't have one itself. */
-static svn_error_t *
-find_base_rev(svn_revnum_t *base_rev,
-              svn_wc__db_t *db,
-              const char *local_abspath,
-              const char *top_local_abspath,
-              apr_pool_t *pool)
-{
-  const char *op_root_abspath;
-  svn_wc__db_status_t status;
-  svn_boolean_t have_base;
-
-  SVN_ERR(svn_wc__db_read_info(&status, NULL, base_rev, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL,
-                               &have_base, NULL, NULL,
-                               db, local_abspath, pool, pool));
-
-  if (SVN_IS_VALID_REVNUM(*base_rev))
-      return SVN_NO_ERROR;
-
-  if (have_base)
-    return svn_error_return(
-        svn_wc__db_base_get_info(NULL, NULL, base_rev, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL,
-                                 db, local_abspath, pool, pool));
-
-  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, pool, pool));
-
-      return svn_error_return(
-                 find_base_rev(base_rev,
-                               db, svn_dirent_dirname(op_root_abspath, pool),
-                               top_local_abspath,
-                               pool));
-    }
-  else if (status == svn_wc__db_status_deleted)
-    {
-      const char *work_del_abspath;
-       SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, &work_del_abspath,
-                                       db, local_abspath, pool, pool));
-
-      if (work_del_abspath != NULL)
-        return svn_error_return(
-                 find_base_rev(base_rev,
-                               db, work_del_abspath,
-                               top_local_abspath,
-                               pool));
-    }
-
-  return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
-                           _("Can't retrieve base revision for %s"),
-                           svn_dirent_local_style(top_local_abspath, pool));
-}
-
 
 /*------------------------------------------------------------------*/
 /*** Public Interfaces ***/
@@ -754,13 +684,13 @@ svn_wc_crawl_revisions5(svn_wc_context_t
   svn_revnum_t target_rev = SVN_INVALID_REVNUM;
   svn_boolean_t start_empty;
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t target_kind = svn_wc__db_kind_unknown;
-  const char *repos_relpath=NULL, *repos_root_url=NULL;
-  svn_depth_t target_depth = svn_depth_unknown;
-  svn_wc__db_lock_t *target_lock = NULL;
+  svn_wc__db_kind_t target_kind;
+  const char *repos_relpath, *repos_root_url;
+  svn_depth_t target_depth;
+  svn_wc__db_lock_t *target_lock;
   svn_node_kind_t disk_kind;
-  svn_boolean_t explicit_rev;
   svn_boolean_t had_props;
+  svn_depth_t report_depth;
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
   /* The first thing we do is get the base_rev from the working copy's
@@ -774,45 +704,26 @@ svn_wc_crawl_revisions5(svn_wc_context_t
                                  db, local_abspath, scratch_pool,
                                  scratch_pool);
 
-  if (err)
+  if (err
+      || (status != svn_wc__db_status_normal
+          && status != svn_wc__db_status_incomplete))
     {
-      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+      if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
         return svn_error_return(err);
 
       svn_error_clear(err);
-      had_props = FALSE;
-      SVN_ERR(svn_wc__db_read_kind(&target_kind, db, local_abspath, TRUE,
-                                   scratch_pool));
-
-      if (target_kind == svn_wc__db_kind_file
-          || target_kind == svn_wc__db_kind_symlink)
-        status = svn_wc__db_status_absent; /* Crawl via parent dir */
-      else
-        status = svn_wc__db_status_not_present; /* As checkout */
-    }
-  else if (repos_root_url == NULL || repos_relpath == NULL)
-    SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url, NULL,
-                                       db, local_abspath,
-                                       scratch_pool, scratch_pool));
 
-  if (status == svn_wc__db_status_not_present
-      || status == svn_wc__db_status_absent
-      || (target_kind == svn_wc__db_kind_dir
-          && status != svn_wc__db_status_normal
-          && status != svn_wc__db_status_incomplete))
-    {
-      /* The target does not exist or is a local addition */
+      /* We don't know about this node, so all we have to do is tell
+         the reporter that we don't know this node.
 
-      if (!SVN_IS_VALID_REVNUM(target_rev))
-        target_rev = 0;
+         But first we have to start the report by sending some basic
+         information for the root. */
 
       if (depth == svn_depth_unknown)
         depth = svn_depth_infinity;
 
-      SVN_ERR(reporter->set_path(report_baton, "", target_rev, depth,
-                                 FALSE,
-                                 NULL,
-                                 scratch_pool));
+      SVN_ERR(reporter->set_path(report_baton, "", 0, depth, FALSE,
+                                 NULL, scratch_pool));
       SVN_ERR(reporter->delete_path(report_baton, "", scratch_pool));
 
       /* Finish the report, which causes the update editor to be
@@ -822,14 +733,13 @@ svn_wc_crawl_revisions5(svn_wc_context_t
       return SVN_NO_ERROR;
     }
 
-  if (!SVN_IS_VALID_REVNUM(target_rev))
-    {
-      SVN_ERR(find_base_rev(&target_rev, db, local_abspath, local_abspath,
-                            scratch_pool));
-      explicit_rev = TRUE;
-    }
-  else
-    explicit_rev = FALSE;
+  if (! repos_relpath)
+    SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
+
+  if (target_depth == svn_depth_unknown)
+    target_depth = svn_depth_infinity;
 
   start_empty = (status == svn_wc__db_status_incomplete);
   if (depth_compatibility_trick
@@ -839,9 +749,6 @@ svn_wc_crawl_revisions5(svn_wc_context_t
       start_empty = TRUE;
     }
 
-  if (target_depth == svn_depth_unknown)
-    target_depth = svn_depth_infinity;
-
   if (restore_files)
     SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
   else
@@ -852,10 +759,12 @@ svn_wc_crawl_revisions5(svn_wc_context_t
       && disk_kind == svn_node_none)
     {
       svn_wc__db_status_t wrk_status;
-      err = svn_wc__db_read_info(&wrk_status, NULL, NULL, NULL, NULL, NULL,
+      svn_wc__db_kind_t wrk_kind;
+      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, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL,
                                  db, local_abspath,
                                  scratch_pool, scratch_pool);
 
@@ -874,31 +783,29 @@ svn_wc_crawl_revisions5(svn_wc_context_t
                                          db, local_abspath,
                                          scratch_pool, scratch_pool));
 
-      if (wrk_status != svn_wc__db_status_added
-          && wrk_status != svn_wc__db_status_deleted
-          && wrk_status != svn_wc__db_status_excluded
-          && wrk_status != svn_wc__db_status_not_present
-          && wrk_status != svn_wc__db_status_absent)
+      if (wrk_status == svn_wc__db_status_normal
+          || wrk_status == svn_wc__db_status_copied
+          || wrk_status == svn_wc__db_status_moved_here)
         {
           SVN_ERR(restore_node(wc_ctx->db, local_abspath,
-                               target_kind, use_commit_times,
+                               wrk_kind, use_commit_times,
                                notify_func, notify_baton,
                                scratch_pool));
         }
     }
 
   {
-    svn_depth_t anchor_depth = target_depth;
+    report_depth = target_depth;
 
     if (honor_depth_exclude 
         && depth != svn_depth_unknown
         && depth < target_depth)
-      anchor_depth = depth;
+      report_depth = depth;
 
     /* The first call to the reporter merely informs it that the
        top-level directory being updated is at BASE_REV.  Its PATH
        argument is ignored. */
-    SVN_ERR(reporter->set_path(report_baton, "", target_rev, anchor_depth,
+    SVN_ERR(reporter->set_path(report_baton, "", target_rev, report_depth,
                                start_empty, NULL, scratch_pool));
   }
   if (target_kind == svn_wc__db_kind_dir)
@@ -913,7 +820,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
                                             target_rev,
                                             repos_relpath,
                                             repos_root_url,
-                                            target_depth,
+                                            report_depth,
                                             reporter, report_baton,
                                             restore_files, depth,
                                             honor_depth_exclude,
@@ -933,7 +840,6 @@ svn_wc_crawl_revisions5(svn_wc_context_t
   else if (target_kind == svn_wc__db_kind_file ||
            target_kind == svn_wc__db_kind_symlink)
     {
-      svn_boolean_t skip_set_path  = FALSE;
       const char *parent_abspath, *base;
       svn_wc__db_status_t parent_status;
       const char *parent_repos_relpath;
@@ -969,16 +875,14 @@ svn_wc_crawl_revisions5(svn_wc_context_t
                                                     repos_relpath,
                                                     scratch_pool),
                                     target_rev,
-                                    target_depth,
+                                    svn_depth_infinity,
                                     FALSE,
                                     target_lock ? target_lock->token : NULL,
                                     scratch_pool);
           if (err)
             goto abort_report;
-          skip_set_path = TRUE;
         }
-
-      if (!skip_set_path && (explicit_rev || target_lock))
+      else if (target_lock)
         {
           /* If this entry is a file node, we just want to report that
              node's revision.  Since we are looking at the actual target
@@ -986,7 +890,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
              directory), and that target is a file, we need to pass an
              empty string to set_path. */
           err = reporter->set_path(report_baton, "", target_rev,
-                                   target_depth,
+                                   svn_depth_infinity,
                                    FALSE,
                                    target_lock ? target_lock->token : NULL,
                                    scratch_pool);


Reply via email to