git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] sha1write: don't copy full sized buffers
@ 2008-09-02 14:22 Nicolas Pitre
  2008-09-02 14:22 ` [PATCH] pack-objects: don't include missing preferred base objects Nicolas Pitre
  0 siblings, 1 reply; 3+ messages in thread
From: Nicolas Pitre @ 2008-09-02 14:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

No need to memcpy() source buffer data when we might just process the
data in place instead of accumulating it into a separate buffer.
This is the case when a whole buffer would have been copied, summed,
written out and then discarded right away.

Also move the CRC32 processing within the loop so the data is more likely
to remain in the L1 CPU cache between the CRC32 sum, SHA1 sum and the
write call.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
 csum-file.c |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/csum-file.c b/csum-file.c
index 2838954..bb70c75 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -11,10 +11,8 @@
 #include "progress.h"
 #include "csum-file.h"
 
-static void sha1flush(struct sha1file *f, unsigned int count)
+static void sha1flush(struct sha1file *f, void *buf, unsigned int count)
 {
-	void *buf = f->buffer;
-
 	for (;;) {
 		int ret = xwrite(f->fd, buf, count);
 		if (ret > 0) {
@@ -39,7 +37,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
 
 	if (offset) {
 		SHA1_Update(&f->ctx, f->buffer, offset);
-		sha1flush(f, offset);
+		sha1flush(f, f->buffer, offset);
 		f->offset = 0;
 	}
 	SHA1_Final(f->buffer, &f->ctx);
@@ -47,7 +45,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
 		hashcpy(result, f->buffer);
 	if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
 		/* write checksum and close fd */
-		sha1flush(f, 20);
+		sha1flush(f, f->buffer, 20);
 		if (flags & CSUM_FSYNC)
 			fsync_or_die(f->fd, f->name);
 		if (close(f->fd))
@@ -62,21 +60,30 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
 
 int sha1write(struct sha1file *f, void *buf, unsigned int count)
 {
-	if (f->do_crc)
-		f->crc32 = crc32(f->crc32, buf, count);
 	while (count) {
 		unsigned offset = f->offset;
 		unsigned left = sizeof(f->buffer) - offset;
 		unsigned nr = count > left ? left : count;
+		void *data;
+
+		if (f->do_crc)
+			f->crc32 = crc32(f->crc32, buf, nr);
+
+		if (nr == sizeof(f->buffer)) {
+			/* process full buffer directly without copy */
+			data = buf;
+		} else {
+			memcpy(f->buffer + offset, buf, nr);
+			data = f->buffer;
+		}
 
-		memcpy(f->buffer + offset, buf, nr);
 		count -= nr;
 		offset += nr;
 		buf = (char *) buf + nr;
 		left -= nr;
 		if (!left) {
-			SHA1_Update(&f->ctx, f->buffer, offset);
-			sha1flush(f, offset);
+			SHA1_Update(&f->ctx, data, offset);
+			sha1flush(f, data, offset);
 			offset = 0;
 		}
 		f->offset = offset;
-- 
1.6.0.1.276.g59b81

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-09-02 14:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-02 14:22 [PATCH] sha1write: don't copy full sized buffers Nicolas Pitre
2008-09-02 14:22 ` [PATCH] pack-objects: don't include missing preferred base objects Nicolas Pitre
2008-09-02 14:22   ` [PATCH] t5300: improve SHA1 collision test Nicolas Pitre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).