Skip to content

Commit 93aa7bd

Browse files
committed
streaming: read loose objects incrementally
Helped-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f0270ef commit 93aa7bd

File tree

1 file changed

+82
-3
lines changed

1 file changed

+82
-3
lines changed

streaming.c

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@ struct git_istream {
6161
} incore;
6262

6363
struct {
64-
int fd; /* open for reading */
65-
/* NEEDSWORK: what else? */
64+
void *mapped;
65+
unsigned long mapsize;
66+
char hdr[32];
67+
int hdr_avail;
68+
int hdr_used;
6669
} loose;
6770

6871
struct {
@@ -150,9 +153,85 @@ static void close_deflated_stream(struct git_istream *st)
150153
*
151154
*****************************************************************/
152155

156+
static read_method_decl(loose)
157+
{
158+
size_t total_read = 0;
159+
160+
switch (st->z_state) {
161+
case z_done:
162+
return 0;
163+
case z_error:
164+
return -1;
165+
default:
166+
break;
167+
}
168+
169+
if (st->u.loose.hdr_used < st->u.loose.hdr_avail) {
170+
size_t to_copy = st->u.loose.hdr_avail - st->u.loose.hdr_used;
171+
if (sz < to_copy)
172+
to_copy = sz;
173+
memcpy(buf, st->u.loose.hdr + st->u.loose.hdr_used, to_copy);
174+
st->u.loose.hdr_used += to_copy;
175+
total_read += to_copy;
176+
}
177+
178+
while (total_read < sz) {
179+
int status;
180+
181+
st->z.next_out = (unsigned char *)buf + total_read;
182+
st->z.avail_out = sz - total_read;
183+
status = git_inflate(&st->z, Z_FINISH);
184+
185+
total_read = st->z.next_out - (unsigned char *)buf;
186+
187+
if (status == Z_STREAM_END) {
188+
git_inflate_end(&st->z);
189+
st->z_state = z_done;
190+
break;
191+
}
192+
if (status != Z_OK && status != Z_BUF_ERROR) {
193+
git_inflate_end(&st->z);
194+
st->z_state = z_error;
195+
return -1;
196+
}
197+
}
198+
return total_read;
199+
}
200+
201+
static close_method_decl(loose)
202+
{
203+
close_deflated_stream(st);
204+
munmap(st->u.loose.mapped, st->u.loose.mapsize);
205+
return 0;
206+
}
207+
208+
static struct stream_vtbl loose_vtbl = {
209+
close_istream_loose,
210+
read_istream_loose,
211+
};
212+
153213
static open_method_decl(loose)
154214
{
155-
return -1; /* for now */
215+
st->u.loose.mapped = map_sha1_file(sha1, &st->u.loose.mapsize);
216+
if (!st->u.loose.mapped)
217+
return -1;
218+
if (unpack_sha1_header(&st->z,
219+
st->u.loose.mapped,
220+
st->u.loose.mapsize,
221+
st->u.loose.hdr,
222+
sizeof(st->u.loose.hdr)) < 0) {
223+
git_inflate_end(&st->z);
224+
munmap(st->u.loose.mapped, st->u.loose.mapsize);
225+
return -1;
226+
}
227+
228+
parse_sha1_header(st->u.loose.hdr, &st->size);
229+
st->u.loose.hdr_used = strlen(st->u.loose.hdr) + 1;
230+
st->u.loose.hdr_avail = st->z.total_out;
231+
st->z_state = z_used;
232+
233+
st->vtbl = &loose_vtbl;
234+
return 0;
156235
}
157236

158237

0 commit comments

Comments
 (0)