Browse Source

pack-objects: hash basename and direname a bit differently.

...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>
maint
Junio C Hamano 19 years ago
parent
commit
eeef7135fe
  1. 33
      pack-objects.c

33
pack-objects.c

@ -445,18 +445,29 @@ struct name_path {
int len; int len;
}; };


#define DIRBITS 12

static unsigned name_hash(struct name_path *path, const char *name) static unsigned name_hash(struct name_path *path, const char *name)
{ {
struct name_path *p = path; struct name_path *p = path;
const char *n = name + strlen(name); const char *n = name + strlen(name);
unsigned hash = 0; unsigned hash = 0, name_hash = 0, name_done = 0;


if (n != name && n[-1] == '\n') if (n != name && n[-1] == '\n')
n--; n--;
while (name <= --n) { while (name <= --n) {
unsigned char c = *n; unsigned char c = *n;
if (c == '/' && !name_done) {
name_hash = hash;
name_done = 1;
hash = 0;
}
hash = hash * 11 + c; hash = hash * 11 + c;
} }
if (!name_done) {
name_hash = hash;
hash = 0;
}
for (p = path; p; p = p->up) { for (p = path; p; p = p->up) {
hash = hash * 11 + '/'; hash = hash * 11 + '/';
n = p->elem + p->len; n = p->elem + p->len;
@ -465,6 +476,26 @@ static unsigned name_hash(struct name_path *path, const char *name)
hash = hash * 11 + c; 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; return hash;
} }



Loading…
Cancel
Save