summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-20 19:16:57 (GMT)
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-20 19:16:57 (GMT)
commit4990aadc4cbb872cb71acdc0ca842eacb86f1362 (patch)
tree9c4a0f2062b0d544fc86d70bff41cae84a574499
parent706bc531a19f268bb03dda7551929dee20172548 (diff)
downloadgit-4990aadc4cbb872cb71acdc0ca842eacb86f1362.zip
git-4990aadc4cbb872cb71acdc0ca842eacb86f1362.tar.gz
git-4990aadc4cbb872cb71acdc0ca842eacb86f1362.tar.bz2
Speed up index file writing by chunking it nicely.
No point in making 17,000 small writes when you can make just a couple of hundred nice 8kB writes instead and save a lot of time.
-rw-r--r--read-cache.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/read-cache.c b/read-cache.c
index bfa2de7..c3beb67 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -227,6 +227,42 @@ unmap:
return error("verify header failed");
}
+#define WRITE_BUFFER_SIZE 8192
+static char write_buffer[WRITE_BUFFER_SIZE];
+static unsigned long write_buffer_len;
+
+static int ce_write(int fd, void *data, unsigned int len)
+{
+ while (len) {
+ unsigned int buffered = write_buffer_len;
+ unsigned int partial = WRITE_BUFFER_SIZE - buffered;
+ if (partial > len)
+ partial = len;
+ memcpy(write_buffer + buffered, data, partial);
+ buffered += partial;
+ if (buffered == WRITE_BUFFER_SIZE) {
+ if (write(fd, write_buffer, WRITE_BUFFER_SIZE) != WRITE_BUFFER_SIZE)
+ return -1;
+ buffered = 0;
+ }
+ write_buffer_len = buffered;
+ len -= partial;
+ data += partial;
+ }
+ return 0;
+}
+
+static int ce_flush(int fd)
+{
+ unsigned int left = write_buffer_len;
+ if (left) {
+ write_buffer_len = 0;
+ if (write(fd, write_buffer, left) != left)
+ return -1;
+ }
+ return 0;
+}
+
int write_cache(int newfd, struct cache_entry **cache, int entries)
{
SHA_CTX c;
@@ -246,14 +282,13 @@ int write_cache(int newfd, struct cache_entry **cache, int entries)
}
SHA1_Final(hdr.sha1, &c);
- if (write(newfd, &hdr, sizeof(hdr)) != sizeof(hdr))
+ if (ce_write(newfd, &hdr, sizeof(hdr)) < 0)
return -1;
for (i = 0; i < entries; i++) {
struct cache_entry *ce = cache[i];
- int size = ce_size(ce);
- if (write(newfd, ce, size) != size)
+ if (ce_write(newfd, ce, ce_size(ce)) < 0)
return -1;
}
- return 0;
+ return ce_flush(newfd);
}