Andrew's git
/
gitweb.git
/ diff
summary
|
log
|
commit
| diff |
tree
commit
grep
author
committer
pickaxe
?
re
streaming_write_entry(): support files with holes
author
Junio C Hamano
<gitster@pobox.com>
Fri, 13 May 2011 22:55:00 +0000
(15:55 -0700)
committer
Junio C Hamano
<gitster@pobox.com>
Sat, 21 May 2011 06:16:53 +0000
(23:16 -0700)
One typical use of a large binary file is to hold a sparse on-disk hash
table with a lot of holes. Help preserving the holes with lseek().
Signed-off-by: Junio C Hamano <gitster@pobox.com>
entry.c
patch
|
blob
|
history
raw
|
patch
|
inline
| side by side (parent:
b0d9c69
)
diff --git
a/entry.c
b/entry.c
index da37d0151413b50dd3e4cc223f71ce55643f349b..e2dc16c13143b97b28e4bc82238bda3c899306f3 100644
(file)
--- a/
entry.c
+++ b/
entry.c
@@
-123,6
+123,7
@@
static int streaming_write_entry(struct cache_entry *ce, char *path,
enum object_type type;
unsigned long sz;
int result = -1;
enum object_type type;
unsigned long sz;
int result = -1;
+ ssize_t kept = 0;
int fd = -1;
st = open_istream(ce->sha1, &type, &sz);
int fd = -1;
st = open_istream(ce->sha1, &type, &sz);
@@
-136,18
+137,34
@@
static int streaming_write_entry(struct cache_entry *ce, char *path,
goto close_and_exit;
for (;;) {
goto close_and_exit;
for (;;) {
- char buf[1024
0
];
- ssize_t wrote;
+ char buf[1024
* 16
];
+ ssize_t wrote
, holeto
;
ssize_t readlen = read_istream(st, buf, sizeof(buf));
if (!readlen)
break;
ssize_t readlen = read_istream(st, buf, sizeof(buf));
if (!readlen)
break;
+ if (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;
}
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;
*fstat_done = fstat_output(fd, state, statbuf);
close_and_exit:
*fstat_done = fstat_output(fd, state, statbuf);
close_and_exit: