diff options
author | Jeff King <peff@peff.net> | 2014-09-10 06:03:52 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-09-10 10:58:32 -0700 |
commit | 9540ce5030853ffbb7e11c30aa59a5e45095d32c (patch) | |
tree | daaa9507ddd96312a5c41708d3554ccf5cf0169b /write_or_die.c | |
parent | 0c72b98f31bf6eabd75be565a08ffcf0d8e74b1f (diff) | |
download | git-9540ce5030853ffbb7e11c30aa59a5e45095d32c.tar.gz |
refs: write packed_refs file using stdiojk/write-packed-refs-via-stdio
We write each line of a new packed-refs file individually
using a write() syscall (and sometimes 2, if the ref is
peeled). Since each line is only about 50-100 bytes long,
this creates a lot of system call overhead.
We can instead open a stdio handle around our descriptor and
use fprintf to write to it. The extra buffering is not a
problem for us, because nobody will read our new packed-refs
file until we call commit_lock_file (by which point we have
flushed everything).
On a pathological repository with 8.5 million refs, this
dropped the time to run `git pack-refs` from 20s to 6s.
Signed-off-by: Jeff King <peff@peff.net>
Reviewed-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'write_or_die.c')
-rw-r--r-- | write_or_die.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/write_or_die.c b/write_or_die.c index b50f99a936..e7afe7a295 100644 --- a/write_or_die.c +++ b/write_or_die.c @@ -49,6 +49,21 @@ void maybe_flush_or_die(FILE *f, const char *desc) } } +void fprintf_or_die(FILE *f, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vfprintf(f, fmt, ap); + va_end(ap); + + if (ret < 0) { + check_pipe(errno); + die_errno("write error"); + } +} + void fsync_or_die(int fd, const char *msg) { if (fsync(fd) < 0) { |