pack-objects: hash basename and direname a bit differently.
authorJunio C Hamano <junkio@cox.net>
Fri, 24 Feb 2006 07:27:49 +0000 (23:27 -0800)
committerJunio C Hamano <junkio@cox.net>
Fri, 24 Feb 2006 07:51:01 +0000 (23:51 -0800)
...so that "Makefile"s from different revs are sorted together,
separate from "t/Makefile"s, but close enough.

Signed-off-by: Junio C Hamano <junkio@cox.net>
pack-objects.c

index 2320bcf3101558d603e0b8c988c9b5f4abcfc05c..095bcb82860888991ef7d3b5f81e4e022bcbdfff 100644 (file)
@@ -445,18 +445,29 @@ struct name_path {
        int len;
 };
 
+#define DIRBITS 12
+
 static unsigned name_hash(struct name_path *path, const char *name)
 {
        struct name_path *p = path;
        const char *n = name + strlen(name);
-       unsigned hash = 0;
+       unsigned hash = 0, name_hash = 0, name_done = 0;
 
        if (n != name && n[-1] == '\n')
                n--;
        while (name <= --n) {
                unsigned char c = *n;
+               if (c == '/' && !name_done) {
+                       name_hash = hash;
+                       name_done = 1;
+                       hash = 0;
+               }
                hash = hash * 11 + c;
        }
+       if (!name_done) {
+               name_hash = hash;
+               hash = 0;
+       }
        for (p = path; p; p = p->up) {
                hash = hash * 11 + '/';
                n = p->elem + p->len;
@@ -465,6 +476,26 @@ static unsigned name_hash(struct name_path *path, const char *name)
                        hash = hash * 11 + c;
                }
        }
+       /*
+        * Make sure "Makefile" and "t/Makefile" are hashed separately
+        * but close enough.
+        */
+       hash = (name_hash<<DIRBITS) | (hash & ((1U<<DIRBITS )-1));
+
+       if (0) { /* debug */
+               n = name + strlen(name);
+               if (n != name && n[-1] == '\n')
+                       n--;
+               while (name <= --n)
+                       fputc(*n, stderr);
+               for (p = path; p; p = p->up) {
+                       fputc('/', stderr);
+                       n = p->elem + p->len;
+                       while (p->elem <= --n)
+                               fputc(*n, stderr);
+               }
+               fprintf(stderr, "\t%08x\n", hash);
+       }
        return hash;
 }