streaming_write_entry(): support files with holes
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>
Junio C Hamano committed
May 13, 2011 at 15:55 UTC
de6182db67d0f53fdc13256042014f2ddf5f8df3
1 file changed
+19
-2
entry.c
+19
-2
@@ -123,6 +123,7 @@ static int streaming_write_entry(struct cache_entry *ce, char *path,
123
enum object_type type;
124
unsigned long sz;
125
int result = -1;
126
+ ssize_t kept = 0;
127
int fd = -1;
128
129
st = open_istream(ce->sha1, &type, &sz);
@@ -136,18 +137,34 @@ static int streaming_write_entry(struct cache_entry *ce, char *path,
137
goto close_and_exit;
138
139
for (;;) {
139
- char buf[10240];
140
- ssize_t wrote;
140
+ char buf[1024 * 16];
141
+ ssize_t wrote, holeto;
142
ssize_t readlen = read_istream(st, buf, sizeof(buf));
143
144
if (!readlen)
145
break;
146
+ if (sizeof(buf) == readlen) {
147
+ for (holeto = 0; holeto < readlen; holeto++)
148
+ if (buf[holeto])
149
+ break;
150
+ if (readlen == holeto) {
151
+ kept += holeto;
152
+ continue;
153
+ }
154
+ }
155
156
+ if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)
157
+ goto close_and_exit;
158
+ else
159
+ kept = 0;
160
wrote = write_in_full(fd, buf, readlen);
161
162
if (wrote != readlen)
163
goto close_and_exit;
164
}
165
+ if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
166
+ write(fd, "", 1) != 1))
167
+ goto close_and_exit;
168
*fstat_done = fstat_output(fd, state, statbuf);
169
170
close_and_exit: