[PATCH] don't load and decompress objects twice with parse_object()

It turns out that parse_object() is loading and decompressing given
object to free it just before calling the specific object parsing
function which does mmap and decompress the same object again. This
patch introduces the ability to parse specific objects directly from a
memory buffer.

Without this patch, running git-fsck-cache on the kernel repositorytake:

	real    0m13.006s
	user    0m11.421s
	sys     0m1.218s

With this patch applied:

	real    0m8.060s
	user    0m7.071s
	sys     0m0.710s

The performance increase is significant, and this is kind of a
prerequisite for sane delta object support with fsck.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Nicolas Pitre
2005-05-06 13:48:34 -04:00
committed by Linus Torvalds
parent f4f21ce367
commit bd2c39f58f
9 changed files with 117 additions and 72 deletions

44
tree.c
View File

@ -88,24 +88,14 @@ struct tree *lookup_tree(unsigned char *sha1)
return (struct tree *) obj;
}
int parse_tree(struct tree *item)
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
{
char type[20];
void *buffer, *bufptr;
unsigned long size;
void *bufptr = buffer;
struct tree_entry_list **list_p;
if (item->object.parsed)
return 0;
item->object.parsed = 1;
buffer = bufptr = read_sha1_file(item->object.sha1, type, &size);
if (!buffer)
return error("Could not read %s",
sha1_to_hex(item->object.sha1));
if (strcmp(type, tree_type)) {
free(buffer);
return error("Object %s not a tree",
sha1_to_hex(item->object.sha1));
}
list_p = &item->entries;
while (size) {
struct object *obj;
@ -115,10 +105,8 @@ int parse_tree(struct tree *item)
char *path = strchr(bufptr, ' ');
unsigned int mode;
if (size < len + 20 || !path ||
sscanf(bufptr, "%o", &mode) != 1) {
free(buffer);
sscanf(bufptr, "%o", &mode) != 1)
return -1;
}
entry = xmalloc(sizeof(struct tree_entry_list));
entry->name = strdup(path + 1);
@ -144,6 +132,28 @@ int parse_tree(struct tree *item)
*list_p = entry;
list_p = &entry->next;
}
free(buffer);
return 0;
}
int parse_tree(struct tree *item)
{
char type[20];
void *buffer;
unsigned long size;
int ret;
if (item->object.parsed)
return 0;
buffer = read_sha1_file(item->object.sha1, type, &size);
if (!buffer)
return error("Could not read %s",
sha1_to_hex(item->object.sha1));
if (strcmp(type, tree_type)) {
free(buffer);
return error("Object %s not a tree",
sha1_to_hex(item->object.sha1));
}
ret = parse_tree_buffer(item, buffer, size);
free(buffer);
return ret;
}