summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2021-04-07 16:54:08 -0700
committerJunio C Hamano <gitster@pobox.com>2021-04-07 16:54:08 -0700
commit573c5e50abb5c3898ebd2f4bafd6e22ff3bf3ea9 (patch)
treeb204b3b2e0ef25eff7dcaee21277bfa572b8b0fc
parentMerge branch 'ah/plugleaks' (diff)
parentcsum-file: make hashwrite() more readable (diff)
downloadgit-573c5e50abb5c3898ebd2f4bafd6e22ff3bf3ea9.tar.gz
git-573c5e50abb5c3898ebd2f4bafd6e22ff3bf3ea9.zip
Merge branch 'ds/clarify-hashwrite'
The hashwrite() API uses a buffering mechanism to avoid calling write(2) too frequently. This logic has been refactored to be easier to understand. * ds/clarify-hashwrite: csum-file: make hashwrite() more readable
-rw-r--r--csum-file.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/csum-file.c b/csum-file.c
index 0f35fa5ee4..7510950fa3 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -89,32 +89,35 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result, unsigned int fl
void hashwrite(struct hashfile *f, const void *buf, unsigned int count)
{
while (count) {
- unsigned offset = f->offset;
- unsigned left = sizeof(f->buffer) - offset;
+ unsigned left = sizeof(f->buffer) - f->offset;
unsigned nr = count > left ? left : count;
- const 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;
+ /*
+ * Flush a full batch worth of data directly
+ * from the input, skipping the memcpy() to
+ * the hashfile's buffer. In this block,
+ * f->offset is necessarily zero.
+ */
+ the_hash_algo->update_fn(&f->ctx, buf, nr);
+ flush(f, buf, nr);
} else {
- memcpy(f->buffer + offset, buf, nr);
- data = f->buffer;
+ /*
+ * Copy to the hashfile's buffer, flushing only
+ * if it became full.
+ */
+ memcpy(f->buffer + f->offset, buf, nr);
+ f->offset += nr;
+ left -= nr;
+ if (!left)
+ hashflush(f);
}
count -= nr;
- offset += nr;
buf = (char *) buf + nr;
- left -= nr;
- if (!left) {
- the_hash_algo->update_fn(&f->ctx, data, offset);
- flush(f, data, offset);
- offset = 0;
- }
- f->offset = offset;
}
}