diff options
| author | Junio C Hamano <gitster@pobox.com> | 2012-04-15 22:50:38 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2012-04-15 22:50:39 -0700 |
| commit | 47de6b0425c79081e64756dcc019bb26344bf7ad (patch) | |
| tree | 74179a74db058b14979c3e7a5a5fc97b97965ce6 /streaming.c | |
| parent | 30fd3a54256a54e5a6006a203c923e97641fb2c2 (diff) | |
| parent | da591a7f4bbe1a208cc5f955523506eb857c45ca (diff) | |
Merge branch 'nd/stream-more'
Use API to read blob data in smaller chunks in more places to reduce the
memory footprint.
By Nguyễn Thái Ngọc Duy (6) and Junio C Hamano (1)
* nd/stream-more:
update-server-info: respect core.bigfilethreshold
fsck: use streaming API for writing lost-found blobs
show: use streaming API for showing blobs
parse_object: avoid putting whole blob in core
cat-file: use streaming API to print blobs
Add more large blob test cases
streaming: make streaming-write-entry to be more reusable
Diffstat (limited to 'streaming.c')
| -rw-r--r-- | streaming.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/streaming.c b/streaming.c index 71072e1b1d..7e7ee2be6f 100644 --- a/streaming.c +++ b/streaming.c @@ -489,3 +489,58 @@ static open_method_decl(incore) return st->u.incore.buf ? 0 : -1; } + + +/**************************************************************** + * Users of streaming interface + ****************************************************************/ + +int stream_blob_to_fd(int fd, unsigned const char *sha1, struct stream_filter *filter, + int can_seek) +{ + struct git_istream *st; + enum object_type type; + unsigned long sz; + ssize_t kept = 0; + int result = -1; + + st = open_istream(sha1, &type, &sz, filter); + if (!st) + return result; + if (type != OBJ_BLOB) + goto close_and_exit; + for (;;) { + char buf[1024 * 16]; + ssize_t wrote, holeto; + ssize_t readlen = read_istream(st, buf, sizeof(buf)); + + if (!readlen) + break; + if (can_seek && sizeof(buf) == readlen) { + for (holeto = 0; holeto < readlen; holeto++) + if (buf[holeto]) + break; + if (readlen == holeto) { + kept += holeto; + continue; + } + } + + if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1) + goto close_and_exit; + else + kept = 0; + wrote = write_in_full(fd, buf, readlen); + + if (wrote != readlen) + goto close_and_exit; + } + if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 || + write(fd, "", 1) != 1)) + goto close_and_exit; + result = 0; + + close_and_exit: + close_istream(st); + return result; +} |
