You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/07/12 20:36:21 UTC

svn commit: r1690504 - /subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/missing-branches.c

Author: stefan2
Date: Sun Jul 12 18:36:21 2015
New Revision: 1690504

URL: http://svn.apache.org/r1690504
Log:
On the svn-mergeinfo-normalizer branch:
Another significant reduction in the number of remote path lookups.

The idea is that most branches are created under a common repository path,
e.g. /myProject/branches.  After the first such lookup, we know "branches"
to exist.  Instead of walking up the path, we first check whether the
level just below "branches" still exists.  That will often not be the case
and we found the deletion boundary with a single lookup.

* tools/client-side/svn-mergeinfo-normalizer/missing-branches.c
  (remote_lookup): When looking for the deletion boundary, find the nearest
                   known exisiting path and check right below that one.
                   Only if that did not help, proceed with the normal
                   bottom-up search.

Modified:
    subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/missing-branches.c

Modified: subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/missing-branches.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/missing-branches.c?rev=1690504&r1=1690503&r2=1690504&view=diff
==============================================================================
--- subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/missing-branches.c (original)
+++ subversion/branches/svn-mergeinfo-normalizer/tools/client-side/svn-mergeinfo-normalizer/missing-branches.c Sun Jul 12 18:36:21 2015
@@ -160,7 +160,6 @@ remote_lookup(svn_boolean_t *deleted,
               apr_pool_t *scratch_pool)
 {
   svn_stringbuf_t *path = svn_stringbuf_create(branch, scratch_pool);
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   /* We shall call this function only after the local lookup failed. */
   assert(local_lookup(lookup, branch) == svn_tristate_unknown);
@@ -171,12 +170,65 @@ remote_lookup(svn_boolean_t *deleted,
   /* If the path did not exist, store the furthest non-existent parent. */
   if (*deleted)
     {
-      svn_boolean_t parent_deleted;
+      apr_pool_t *iterpool;
+      svn_boolean_t is_deleted;
       const char *deleted_path;
       apr_size_t len;
 
+      /* Find the closest parent that exists.  Often, that is something like
+         "branches" and the next level already does not exist.  So, use that
+         as a heuristics to minimize the number of lookups. */
+
+      /* Set LEN to the length of the last unknown to exist sub-path. */
+      svn_stringbuf_t *temp = svn_stringbuf_dup(path, scratch_pool);
+      do
+        {
+          len = temp->len;
+          to_parent(temp);
+        }
+      while (local_lookup(lookup, temp->data) != svn_tristate_true);
+
+      /* Check whether that path actually does not exist. */
+      if (len == path->len)
+        {
+          /* We already know that the full PATH does not exist.
+             We get here if the immediate parent of PATH is known to exist. */
+          is_deleted = TRUE;
+        }
+      else
+        {
+          temp = svn_stringbuf_ncreate(branch, len, scratch_pool);
+          SVN_ERR(path_deleted(&is_deleted, lookup->session, temp->data,
+                               scratch_pool));
+        }
+
+      /* Whether or not that path does not exist, we know now and should
+         store that in LOOKUP. */
+      if (is_deleted)
+        {
+          /* We are almost done here. The existing parent is already in
+             LOOKUP and we only need to add the deleted path. */
+          deleted_path = apr_pstrmemdup(apr_hash_pool_get(lookup->deleted),
+                                        branch, len);
+          apr_hash_set(lookup->deleted, deleted_path, len, deleted_path);
+
+          return SVN_NO_ERROR;
+        }
+      else
+        {
+          /* We just learned that TEMP does exist. Remember this fact and
+             later continue the search for the deletion boundary. */
+          const char *hash_path
+            = apr_pstrmemdup(apr_hash_pool_get(lookup->existing), temp->data,
+                             temp->len);
+
+          /* Only add HASH_PATH.  Its parents are already in that hash. */
+          apr_hash_set(lookup->existing, hash_path, path->len, hash_path);
+        }
+
       /* Find the closest parent that does exist.
         "/" exists, hence, this will terminate. */
+      iterpool = svn_pool_create(scratch_pool);
       do
         {
           svn_pool_clear(iterpool);
@@ -184,16 +236,17 @@ remote_lookup(svn_boolean_t *deleted,
           len = path->len;
           to_parent(path);
 
-          /* We often know that "/branches" etc. to exist.  So, we can skip
+          /* We often know that "/branches" etc. exist.  So, we can skip
              the final lookup in that case. */
           if (local_lookup(lookup, path->data) == svn_tristate_true)
             break;
 
           /* Get the info from the repository. */
-          SVN_ERR(path_deleted(&parent_deleted, lookup->session, path->data,
-                               iterpool));
+          SVN_ERR(path_deleted(&is_deleted, lookup->session, path->data,
+                              iterpool));
         }
-      while (parent_deleted);
+      while (is_deleted);
+      svn_pool_destroy(iterpool);
 
       /* PATH exists, it's sub-path of length LEN does not. */
       deleted_path = apr_pstrmemdup(apr_hash_pool_get(lookup->deleted),
@@ -217,8 +270,6 @@ remote_lookup(svn_boolean_t *deleted,
         apr_hash_set(lookup->existing, hash_path, path->len, hash_path);
     }
 
-  svn_pool_destroy(iterpool);
-
   return SVN_NO_ERROR;
 }