summaryrefslogtreecommitdiff
path: root/index-pack.c
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-12-19 10:53:08 -0500
committerJunio C Hamano <junkio@cox.net>2006-12-20 00:42:10 -0800
commit6d2fa7f1b489c65e677c18eda5c144dbc5d614ab (patch)
tree70a79d44228403c478ed8db0f00c147726331c60 /index-pack.c
parent313ce8cee665447e4476d7e8985b270346a8e5a1 (diff)
downloadgit-6d2fa7f1b489c65e677c18eda5c144dbc5d614ab.tar.gz
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>
Diffstat (limited to 'index-pack.c')
-rw-r--r--index-pack.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/index-pack.c b/index-pack.c
index 6d6c92bf14..c05feae161 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;
}