mirror of
https://github.com/git/git
synced 2024-11-05 18:59:29 +00:00
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>
This commit is contained in:
parent
313ce8cee6
commit
6d2fa7f1b4
1 changed files with 14 additions and 13 deletions
27
index-pack.c
27
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 "cache.h"
|
||||||
#include "delta.h"
|
#include "delta.h"
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
@ -6,8 +11,6 @@
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include <sys/time.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
static const char index_pack_usage[] =
|
static const char index_pack_usage[] =
|
||||||
"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
|
"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 char input_buffer[4096];
|
||||||
static unsigned long input_offset, input_len, consumed_bytes;
|
static unsigned long input_offset, input_len, consumed_bytes;
|
||||||
static SHA_CTX input_ctx;
|
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. */
|
/* Discard current buffer used content. */
|
||||||
static void flush(void)
|
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);
|
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
|
||||||
if (output_fd < 0)
|
if (output_fd < 0)
|
||||||
die("unable to create %s: %s\n", pack_name, strerror(errno));
|
die("unable to create %s: %s\n", pack_name, strerror(errno));
|
||||||
mmap_fd = output_fd;
|
pack_fd = output_fd;
|
||||||
} else {
|
} else {
|
||||||
input_fd = open(pack_name, O_RDONLY);
|
input_fd = open(pack_name, O_RDONLY);
|
||||||
if (input_fd < 0)
|
if (input_fd < 0)
|
||||||
die("cannot open packfile '%s': %s",
|
die("cannot open packfile '%s': %s",
|
||||||
pack_name, strerror(errno));
|
pack_name, strerror(errno));
|
||||||
output_fd = -1;
|
output_fd = -1;
|
||||||
mmap_fd = input_fd;
|
pack_fd = input_fd;
|
||||||
}
|
}
|
||||||
SHA1_Init(&input_ctx);
|
SHA1_Init(&input_ctx);
|
||||||
return pack_name;
|
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 from = obj[0].offset + obj[0].hdr_size;
|
||||||
unsigned long len = obj[1].offset - from;
|
unsigned long len = obj[1].offset - from;
|
||||||
unsigned pg_offset = from % getpagesize();
|
unsigned char *src, *data;
|
||||||
unsigned char *map, *data;
|
|
||||||
z_stream stream;
|
z_stream stream;
|
||||||
int st;
|
int st;
|
||||||
|
|
||||||
map = mmap(NULL, len + pg_offset, PROT_READ, MAP_PRIVATE,
|
src = xmalloc(len);
|
||||||
mmap_fd, from - pg_offset);
|
if (pread(pack_fd, src, len, from) != len)
|
||||||
if (map == MAP_FAILED)
|
die("cannot pread pack file: %s", strerror(errno));
|
||||||
die("cannot mmap pack file: %s", strerror(errno));
|
|
||||||
data = xmalloc(obj->size);
|
data = xmalloc(obj->size);
|
||||||
memset(&stream, 0, sizeof(stream));
|
memset(&stream, 0, sizeof(stream));
|
||||||
stream.next_out = data;
|
stream.next_out = data;
|
||||||
stream.avail_out = obj->size;
|
stream.avail_out = obj->size;
|
||||||
stream.next_in = map + pg_offset;
|
stream.next_in = src;
|
||||||
stream.avail_in = len;
|
stream.avail_in = len;
|
||||||
inflateInit(&stream);
|
inflateInit(&stream);
|
||||||
while ((st = inflate(&stream, Z_FINISH)) == Z_OK);
|
while ((st = inflate(&stream, Z_FINISH)) == Z_OK);
|
||||||
inflateEnd(&stream);
|
inflateEnd(&stream);
|
||||||
if (st != Z_STREAM_END || stream.total_out != obj->size)
|
if (st != Z_STREAM_END || stream.total_out != obj->size)
|
||||||
die("serious inflate inconsistency");
|
die("serious inflate inconsistency");
|
||||||
munmap(map, len + pg_offset);
|
free(src);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue