Hi again,
>> On Fri, Aug 31, 2001 at 09:19:42AM -0500, Ben Collins-Sussman wrote:
>>>...
>>> The working copy commit-crawler needs to commit N targets spread out
>>> randomly over a large tree.  Because commits are atomic, it describes
>>> the commit as *one* large edit to the tree;  this means starting the
>>> commit from a common "parent" directory and then traversing
>>> directories in an intelligent order.  The rule we want to follow is:
>>> after we leave a directory (go "up"), we want to close the directory.
>>> We don't want to have to randomly re-open it again.
>>
>> That's the idea...
>>
>>> Thus, the crawler
>>> is *already* sorting the targets.  As Mike said, right now the targets
>>> are being qsorted alphabetically, which guarantees that all children
>>> in the same directory will be examined as a group.
>>
>> Nope. It *isn't* doing that, which is why I posted the question in the
first
>> place. If we were doing a proper traversal, then we wouldn't need to
check
>> whether a lock had been taken out already. Thus, Mike's change to look
for
>> an existing lock is merely covering up a deeper issue (that was my
worry).
>
> Right.  I'd like to take on this one tomorrow (Amsterdam time), if you are
> alright with it.  It is only a small patch that will get the behaviour of
> visiting each directory only once (by adjusting the sorting).
I've cooked up a patch that I think will do the trick.  Ofcourse it needs
to be tested.
It has (IMO) one downside: it assumes that strings are NUL terminated.
OTOH this isn't going to be a big problem when I look at the task
list and issue #406.
Oh, I also removed 'else' statements where there was only one path
for the code to take.  The ones like these IOW:
if (a)
  return 1;
else
  return 0;
  ==
if (a)
  return 1;
return 0;
I don't know if this patch is really needed, but I do think that
visiting a dir only once justifies the extra cost of sorting like
this.
Sander
The patch:
--- libsvn_subr/path.c  Fri Aug 31 00:31:20 2001
+++ libsvn_subr/path.c~ Sun Sep  2 21:33:50 2001
@@ -216,19 +216,50 @@
   size_t min_len = ((path1->len) < (path2->len)) ? path1->len : path2->len;
   size_t i;
   char dirsep = get_separator_from_style (style);
+  char *sep1, *sep2;
   /* Skip past common prefix. */
   for (i = 0; (i < min_len) && (path1->data[i] == path2->data[i]); i++)
     ;
-  if ((path1->len == path2->len) && (i >= min_len))
-    return 0;     /* the paths are the same */
-  else if (path1->data[i] == dirsep)
+  if (i >= min_len) {
+    if (path1->len == path2->len)
+      return 0;   /* the paths are the same */
+
+    if (path1->len < path2->len)
+      return -1;
+
+    return 1;
+  }
+
+  if (path1->data[i] == dirsep)
     return 1;     /* path1 child of path2, parent always comes before child
*/
-  else if (path2->data[i] == dirsep)
+
+  if (path2->data[i] == dirsep)
     return -1;    /* path2 child of path1, parent always comes before child
*/
-  else
-    return strncmp (path1->data + i, path2->data + i, (min_len - i));
+
+  /* 'count' directory seperators
+   * This does assume that strings are NUL terminated.
+   */
+  sep1 = &path1[i];
+  sep2 = &path2[i];
+  do {
+    sep1++;
+    sep1 = strchr(sep1, dirsep);
+    sep2++;
+    sep2 = strchr(sep2, dirsep);
+  } while (sep1 && sep2);
+
+  if (sep1)
+      return 1;   /* path1 is deeper in the tree than path2 */
+
+  if (sep2)
+      return -1;  /* path2 is deeper in the tree than path1 */
+
+  /* Since we already checked the common prefix, we only need to
+   * check if the next character is bigger or smaller
+   */
+  return path1->data[i + 1] < path2->data[i + 1] ? -1 : 1;
 }
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:39 2006