diff options
author | Nicolas Pitre <nico@cam.org> | 2006-12-19 10:53:08 -0500 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-12-20 00:42:10 -0800 |
commit | 6d2fa7f1b489c65e677c18eda5c144dbc5d614ab (patch) | |
tree | 70a79d44228403c478ed8db0f00c147726331c60 | |
parent | 313ce8cee665447e4476d7e8985b270346a8e5a1 (diff) | |
download | git-6d2fa7f1b489c65e677c18eda5c144dbc5d614ab.tar.gz git-6d2fa7f1b489c65e677c18eda5c144dbc5d614ab.tar.xz |
index-pack usage of mmap() is unacceptably slower on many OSes other than Linux
It was reported by Randal L. Schwartz <merlyn@stonehenge.com> that
indexing the Linux repository ~150MB pack takes about an hour on OS x
while it's a minute on Linux. It seems that the OS X mmap()
implementation is more than 2 orders of magnitude slower than the Linux
one.
Linus proposed a patch replacing mmap() with pread() bringing index-pack
performance on OS X in line with the Linux one. The performances on
Linux also improved by a small margin.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r-- | index-pack.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/index-pack.c b/index-pack.c index 6d6c92bf1..c05feae16 100644 --- a/index-pack.c +++ b/index-pack.c @@ -1,3 +1,8 @@ +#define _XOPEN_SOURCE 600 +#include <unistd.h> +#include <sys/time.h> +#include <signal.h> + #include "cache.h" #include "delta.h" #include "pack.h" @@ -6,8 +11,6 @@ #include "commit.h" #include "tag.h" #include "tree.h" -#include <sys/time.h> -#include <signal.h> static const char index_pack_usage[] = "git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }"; @@ -87,7 +90,7 @@ static unsigned display_progress(unsigned n, unsigned total, unsigned last_pc) static unsigned char input_buffer[4096]; static unsigned long input_offset, input_len, consumed_bytes; static SHA_CTX input_ctx; -static int input_fd, output_fd, mmap_fd; +static int input_fd, output_fd, pack_fd; /* Discard current buffer used content. */ static void flush(void) @@ -148,14 +151,14 @@ static const char *open_pack_file(const char *pack_name) output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600); if (output_fd < 0) die("unable to create %s: %s\n", pack_name, strerror(errno)); - mmap_fd = output_fd; + pack_fd = output_fd; } else { input_fd = open(pack_name, O_RDONLY); if (input_fd < 0) die("cannot open packfile '%s': %s", pack_name, strerror(errno)); output_fd = -1; - mmap_fd = input_fd; + pack_fd = input_fd; } SHA1_Init(&input_ctx); return pack_name; @@ -279,27 +282,25 @@ static void *get_data_from_pack(struct object_entry *obj) { unsigned long from = obj[0].offset + obj[0].hdr_size; unsigned long len = obj[1].offset - from; - unsigned pg_offset = from % getpagesize(); - unsigned char *map, *data; + unsigned char *src, *data; z_stream stream; int st; - map = mmap(NULL, len + pg_offset, PROT_READ, MAP_PRIVATE, - mmap_fd, from - pg_offset); - if (map == MAP_FAILED) - die("cannot mmap pack file: %s", strerror(errno)); + src = xmalloc(len); + if (pread(pack_fd, src, len, from) != len) + die("cannot pread pack file: %s", strerror(errno)); data = xmalloc(obj->size); memset(&stream, 0, sizeof(stream)); stream.next_out = data; stream.avail_out = obj->size; - stream.next_in = map + pg_offset; + stream.next_in = src; stream.avail_in = len; inflateInit(&stream); while ((st = inflate(&stream, Z_FINISH)) == Z_OK); inflateEnd(&stream); if (st != Z_STREAM_END || stream.total_out != obj->size) die("serious inflate inconsistency"); - munmap(map, len + pg_offset); + free(src); return data; } |