streaming: create structure for loose 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 loose 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
b7774c0f0de43379c40984b4ede265a512c1a4f0
1 file changed
+44
-41
streaming.c
+44
-41
@@ -39,14 +39,6 @@ struct odb_read_stream {
39
enum { z_unused, z_used, z_done, z_error } z_state;
40
41
union {
42
- struct {
43
- void *mapped;
44
- unsigned long mapsize;
45
- char hdr[32];
46
- int hdr_avail;
47
- int hdr_used;
48
- } loose;
49
-
42
struct {
43
struct packed_git *pack;
44
off_t pos;
@@ -165,11 +157,21 @@ static struct odb_read_stream *attach_stream_filter(struct odb_read_stream *st,
157
*
158
*****************************************************************/
159
168
-static ssize_t read_istream_loose(struct odb_read_stream *st, char *buf, size_t sz)
160
+struct odb_loose_read_stream {
161
+ struct odb_read_stream base;
162
+ void *mapped;
163
+ unsigned long mapsize;
164
+ char hdr[32];
165
+ int hdr_avail;
166
+ int hdr_used;
167
+};
168
+
169
+static ssize_t read_istream_loose(struct odb_read_stream *_st, char *buf, size_t sz)
170
{
171
+ struct odb_loose_read_stream *st = (struct odb_loose_read_stream *)_st;
172
size_t total_read = 0;
173
172
- switch (st->z_state) {
174
+ switch (st->base.z_state) {
175
case z_done:
176
return 0;
177
case z_error:
@@ -178,42 +180,43 @@ static ssize_t read_istream_loose(struct odb_read_stream *st, char *buf, size_t
180
break;
181
}
182
181
- if (st->u.loose.hdr_used < st->u.loose.hdr_avail) {
182
- size_t to_copy = st->u.loose.hdr_avail - st->u.loose.hdr_used;
183
+ if (st->hdr_used < st->hdr_avail) {
184
+ size_t to_copy = st->hdr_avail - st->hdr_used;
185
if (sz < to_copy)
186
to_copy = sz;
185
- memcpy(buf, st->u.loose.hdr + st->u.loose.hdr_used, to_copy);
186
- st->u.loose.hdr_used += to_copy;
187
+ memcpy(buf, st->hdr + st->hdr_used, to_copy);
188
+ st->hdr_used += to_copy;
189
total_read += to_copy;
190
}
191
192
while (total_read < sz) {
193
int status;
194
193
- st->z.next_out = (unsigned char *)buf + total_read;
194
- st->z.avail_out = sz - total_read;
195
- status = git_inflate(&st->z, Z_FINISH);
195
+ st->base.z.next_out = (unsigned char *)buf + total_read;
196
+ st->base.z.avail_out = sz - total_read;
197
+ status = git_inflate(&st->base.z, Z_FINISH);
198
197
- total_read = st->z.next_out - (unsigned char *)buf;
199
+ total_read = st->base.z.next_out - (unsigned char *)buf;
200
201
if (status == Z_STREAM_END) {
200
- git_inflate_end(&st->z);
201
- st->z_state = z_done;
202
+ git_inflate_end(&st->base.z);
203
+ st->base.z_state = z_done;
204
break;
205
}
206
if (status != Z_OK && (status != Z_BUF_ERROR || total_read < sz)) {
205
- git_inflate_end(&st->z);
206
- st->z_state = z_error;
207
+ git_inflate_end(&st->base.z);
208
+ st->base.z_state = z_error;
209
return -1;
210
}
211
}
212
return total_read;
213
}
214
213
-static int close_istream_loose(struct odb_read_stream *st)
215
+static int close_istream_loose(struct odb_read_stream *_st)
216
{
215
- close_deflated_stream(st);
216
- munmap(st->u.loose.mapped, st->u.loose.mapsize);
217
+ struct odb_loose_read_stream *st = (struct odb_loose_read_stream *)_st;
218
+ close_deflated_stream(&st->base);
219
+ munmap(st->mapped, st->mapsize);
220
return 0;
221
}
222
@@ -222,7 +225,7 @@ static int open_istream_loose(struct odb_read_stream **out,
225
const struct object_id *oid)
226
{
227
struct object_info oi = OBJECT_INFO_INIT;
225
- struct odb_read_stream *st;
228
+ struct odb_loose_read_stream *st;
229
struct odb_source *source;
230
unsigned long mapsize;
231
void *mapped;
@@ -244,8 +247,8 @@ static int open_istream_loose(struct odb_read_stream **out,
247
*/
248
CALLOC_ARRAY(st, 1);
249
247
- switch (unpack_loose_header(&st->z, mapped, mapsize, st->u.loose.hdr,
248
- sizeof(st->u.loose.hdr))) {
250
+ switch (unpack_loose_header(&st->base.z, mapped, mapsize, st->hdr,
251
+ sizeof(st->hdr))) {
252
case ULHR_OK:
253
break;
254
case ULHR_BAD:
@@ -253,26 +256,26 @@ static int open_istream_loose(struct odb_read_stream **out,
256
goto error;
257
}
258
256
- oi.sizep = &st->size;
257
- oi.typep = &st->type;
259
+ oi.sizep = &st->base.size;
260
+ oi.typep = &st->base.type;
261
259
- if (parse_loose_header(st->u.loose.hdr, &oi) < 0 || st->type < 0)
262
+ if (parse_loose_header(st->hdr, &oi) < 0 || st->base.type < 0)
263
goto error;
264
262
- st->u.loose.mapped = mapped;
263
- st->u.loose.mapsize = mapsize;
264
- st->u.loose.hdr_used = strlen(st->u.loose.hdr) + 1;
265
- st->u.loose.hdr_avail = st->z.total_out;
266
- st->z_state = z_used;
267
- st->close = close_istream_loose;
268
- st->read = read_istream_loose;
265
+ st->mapped = mapped;
266
+ st->mapsize = mapsize;
267
+ st->hdr_used = strlen(st->hdr) + 1;
268
+ st->hdr_avail = st->base.z.total_out;
269
+ st->base.z_state = z_used;
270
+ st->base.close = close_istream_loose;
271
+ st->base.read = read_istream_loose;
272
270
- *out = st;
273
+ *out = &st->base;
274
275
return 0;
276
error:
274
- git_inflate_end(&st->z);
275
- munmap(st->u.loose.mapped, st->u.loose.mapsize);
277
+ git_inflate_end(&st->base.z);
278
+ munmap(st->mapped, st->mapsize);
279
free(st);
280
return -1;
281
}