Skip to content

Commit 61effed

Browse files
jltoblergitster
authored andcommitted
odb: update struct odb_write_stream read() callback
The `read()` callback used by `struct odb_write_stream` currently returns a pointer to an internal buffer along with the number of bytes read. This makes buffer ownership unclear and provides no way to report errors. Update the interface to instead require the caller to provide a buffer, and have the callback return the number of bytes written to it or a negative value on error. While at it, also move the `struct odb_write_stream` definition to "odb/streaming.h". Call sites are updated accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent ec562fe commit 61effed

File tree

5 files changed

+43
-20
lines changed

5 files changed

+43
-20
lines changed

builtin/unpack-objects.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "hex.h"
1010
#include "object-file.h"
1111
#include "odb.h"
12+
#include "odb/streaming.h"
1213
#include "odb/transaction.h"
1314
#include "object.h"
1415
#include "delta.h"
@@ -360,34 +361,29 @@ static void unpack_non_delta_entry(enum object_type type, unsigned long size,
360361

361362
struct input_zstream_data {
362363
git_zstream *zstream;
363-
unsigned char buf[8192];
364364
int status;
365365
};
366366

367-
static const void *feed_input_zstream(struct odb_write_stream *in_stream,
368-
unsigned long *readlen)
367+
static ssize_t feed_input_zstream(struct odb_write_stream *in_stream,
368+
unsigned char *buf, size_t buf_len)
369369
{
370370
struct input_zstream_data *data = in_stream->data;
371371
git_zstream *zstream = data->zstream;
372372
void *in = fill(1);
373373

374-
if (in_stream->is_finished) {
375-
*readlen = 0;
376-
return NULL;
377-
}
374+
if (in_stream->is_finished)
375+
return 0;
378376

379-
zstream->next_out = data->buf;
380-
zstream->avail_out = sizeof(data->buf);
377+
zstream->next_out = buf;
378+
zstream->avail_out = buf_len;
381379
zstream->next_in = in;
382380
zstream->avail_in = len;
383381

384382
data->status = git_inflate(zstream, 0);
385383

386384
in_stream->is_finished = data->status != Z_OK;
387385
use(len - zstream->avail_in);
388-
*readlen = sizeof(data->buf) - zstream->avail_out;
389-
390-
return data->buf;
386+
return buf_len - zstream->avail_out;
391387
}
392388

393389
static void stream_blob(unsigned long size, unsigned nr)

object-file.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,7 @@ int odb_source_loose_write_stream(struct odb_source *source,
10661066
struct git_hash_ctx c, compat_c;
10671067
struct strbuf tmp_file = STRBUF_INIT;
10681068
struct strbuf filename = STRBUF_INIT;
1069+
unsigned char buf[8192];
10691070
int dirlen;
10701071
char hdr[MAX_HEADER_LEN];
10711072
int hdrlen;
@@ -1098,9 +1099,16 @@ int odb_source_loose_write_stream(struct odb_source *source,
10981099
unsigned char *in0 = stream.next_in;
10991100

11001101
if (!stream.avail_in && !in_stream->is_finished) {
1101-
const void *in = in_stream->read(in_stream, &stream.avail_in);
1102-
stream.next_in = (void *)in;
1103-
in0 = (unsigned char *)in;
1102+
ssize_t read_len = odb_write_stream_read(in_stream, buf,
1103+
sizeof(buf));
1104+
if (read_len < 0) {
1105+
err = -1;
1106+
goto cleanup;
1107+
}
1108+
1109+
stream.avail_in = read_len;
1110+
stream.next_in = buf;
1111+
in0 = buf;
11041112
/* All data has been read. */
11051113
if (in_stream->is_finished)
11061114
flush = 1;

odb.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -529,11 +529,7 @@ static inline int odb_write_object(struct object_database *odb,
529529
return odb_write_object_ext(odb, buf, len, type, oid, NULL, 0);
530530
}
531531

532-
struct odb_write_stream {
533-
const void *(*read)(struct odb_write_stream *, unsigned long *len);
534-
void *data;
535-
int is_finished;
536-
};
532+
struct odb_write_stream;
537533

538534
int odb_write_object_stream(struct object_database *odb,
539535
struct odb_write_stream *stream, size_t len,

odb/streaming.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ struct odb_read_stream *odb_read_stream_open(struct object_database *odb,
232232
return st;
233233
}
234234

235+
ssize_t odb_write_stream_read(struct odb_write_stream *st, void *buf, size_t sz)
236+
{
237+
return st->read(st, buf, sz);
238+
}
239+
235240
int odb_stream_blob_to_fd(struct object_database *odb,
236241
int fd,
237242
const struct object_id *oid,

odb/streaming.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@ int odb_read_stream_close(struct odb_read_stream *stream);
4747
*/
4848
ssize_t odb_read_stream_read(struct odb_read_stream *stream, void *buf, size_t len);
4949

50+
/*
51+
* A stream that provides an object to be written to the object database without
52+
* loading all of it into memory.
53+
*/
54+
struct odb_write_stream {
55+
ssize_t (*read)(struct odb_write_stream *, unsigned char *, size_t);
56+
void *data;
57+
int is_finished;
58+
};
59+
60+
/*
61+
* Read data from the stream into the buffer. Returns 0 when finished and the
62+
* number of bytes read on success. Returns a negative error code in case
63+
* reading from the stream fails.
64+
*/
65+
ssize_t odb_write_stream_read(struct odb_write_stream *stream, void *buf,
66+
size_t len);
67+
5068
/*
5169
* Look up the object by its ID and write the full contents to the file
5270
* descriptor. The object must be a blob, or the function will fail. When

0 commit comments

Comments
 (0)