streaming: create structure for packed object streams
As explained in a preceding commit, we want to get rid of the union of stream-type specific data in `struct odb_read_stream`. Create a new structure for packed object streams to move towards this design. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Nov 23, 2025 at 19:59 UTC
5f0d8d2e8d3f992f58af247b6d21509c3c7595ca
1 file changed
+40
-35
streaming.c
+40
-35
@@ -39,11 +39,6 @@ struct odb_read_stream {
39
enum { z_unused, z_used, z_done, z_error } z_state;
40
41
union {
42
- struct {
43
- struct packed_git *pack;
44
- off_t pos;
45
- } in_pack;
46
-
42
struct filtered_istream filtered;
43
} u;
44
};
@@ -287,16 +282,23 @@ error:
282
*
283
*****************************************************************/
284
290
-static ssize_t read_istream_pack_non_delta(struct odb_read_stream *st, char *buf,
285
+struct odb_packed_read_stream {
286
+ struct odb_read_stream base;
287
+ struct packed_git *pack;
288
+ off_t pos;
289
+};
290
+
291
+static ssize_t read_istream_pack_non_delta(struct odb_read_stream *_st, char *buf,
292
size_t sz)
293
{
294
+ struct odb_packed_read_stream *st = (struct odb_packed_read_stream *)_st;
295
size_t total_read = 0;
296
295
- switch (st->z_state) {
297
+ switch (st->base.z_state) {
298
case z_unused:
297
- memset(&st->z, 0, sizeof(st->z));
298
- git_inflate_init(&st->z);
299
- st->z_state = z_used;
299
+ memset(&st->base.z, 0, sizeof(st->base.z));
300
+ git_inflate_init(&st->base.z);
301
+ st->base.z_state = z_used;
302
break;
303
case z_done:
304
return 0;
@@ -311,21 +313,21 @@ static ssize_t read_istream_pack_non_delta(struct odb_read_stream *st, char *buf
313
struct pack_window *window = NULL;
314
unsigned char *mapped;
315
314
- mapped = use_pack(st->u.in_pack.pack, &window,
315
- st->u.in_pack.pos, &st->z.avail_in);
316
+ mapped = use_pack(st->pack, &window,
317
+ st->pos, &st->base.z.avail_in);
318
317
- st->z.next_out = (unsigned char *)buf + total_read;
318
- st->z.avail_out = sz - total_read;
319
- st->z.next_in = mapped;
320
- status = git_inflate(&st->z, Z_FINISH);
319
+ st->base.z.next_out = (unsigned char *)buf + total_read;
320
+ st->base.z.avail_out = sz - total_read;
321
+ st->base.z.next_in = mapped;
322
+ status = git_inflate(&st->base.z, Z_FINISH);
323
322
- st->u.in_pack.pos += st->z.next_in - mapped;
323
- total_read = st->z.next_out - (unsigned char *)buf;
324
+ st->pos += st->base.z.next_in - mapped;
325
+ total_read = st->base.z.next_out - (unsigned char *)buf;
326
unuse_pack(&window);
327
328
if (status == Z_STREAM_END) {
327
- git_inflate_end(&st->z);
328
- st->z_state = z_done;
329
+ git_inflate_end(&st->base.z);
330
+ st->base.z_state = z_done;
331
break;
332
}
333
@@ -338,17 +340,18 @@ static ssize_t read_istream_pack_non_delta(struct odb_read_stream *st, char *buf
340
* or truncated), then use_pack() catches that and will die().
341
*/
342
if (status != Z_OK && status != Z_BUF_ERROR) {
341
- git_inflate_end(&st->z);
342
- st->z_state = z_error;
343
+ git_inflate_end(&st->base.z);
344
+ st->base.z_state = z_error;
345
return -1;
346
}
347
}
348
return total_read;
349
}
350
349
-static int close_istream_pack_non_delta(struct odb_read_stream *st)
351
+static int close_istream_pack_non_delta(struct odb_read_stream *_st)
352
{
351
- close_deflated_stream(st);
353
+ struct odb_packed_read_stream *st = (struct odb_packed_read_stream *)_st;
354
+ close_deflated_stream(&st->base);
355
return 0;
356
}
357
@@ -358,19 +361,17 @@ static int open_istream_pack_non_delta(struct odb_read_stream **out,
361
struct packed_git *pack,
362
off_t offset)
363
{
361
- struct odb_read_stream stream = {
362
- .close = close_istream_pack_non_delta,
363
- .read = read_istream_pack_non_delta,
364
- };
364
+ struct odb_packed_read_stream *stream;
365
struct pack_window *window;
366
enum object_type in_pack_type;
367
+ size_t size;
368
369
window = NULL;
370
371
in_pack_type = unpack_object_header(pack,
372
&window,
373
&offset,
373
- &stream.size);
374
+ &size);
375
unuse_pack(&window);
376
switch (in_pack_type) {
377
default:
@@ -381,13 +382,17 @@ static int open_istream_pack_non_delta(struct odb_read_stream **out,
382
case OBJ_TAG:
383
break;
384
}
384
- stream.type = in_pack_type;
385
- stream.z_state = z_unused;
386
- stream.u.in_pack.pack = pack;
387
- stream.u.in_pack.pos = offset;
385
389
- CALLOC_ARRAY(*out, 1);
390
- **out = stream;
386
+ CALLOC_ARRAY(stream, 1);
387
+ stream->base.close = close_istream_pack_non_delta;
388
+ stream->base.read = read_istream_pack_non_delta;
389
+ stream->base.type = in_pack_type;
390
+ stream->base.size = size;
391
+ stream->base.z_state = z_unused;
392
+ stream->pack = pack;
393
+ stream->pos = offset;
394
+
395
+ *out = &stream->base;
396
397
return 0;
398
}