Commit 8380b39a by Carlos Martín Nieto

odb: perform the stream hashing in the frontend

Hash the data as it's coming into the stream and tell the backend what
its name is when finalizing the write. This makes it consistent with
the way a plain git_odb_write() performs the write.
parent 376e6c9f
...@@ -65,10 +65,13 @@ typedef enum { ...@@ -65,10 +65,13 @@ typedef enum {
GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY), GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY),
} git_odb_stream_t; } git_odb_stream_t;
typedef struct git_hash_ctx git_hash_ctx;
/** A stream to read/write from a backend */ /** A stream to read/write from a backend */
struct git_odb_stream { struct git_odb_stream {
git_odb_backend *backend; git_odb_backend *backend;
unsigned int mode; unsigned int mode;
git_hash_ctx *hash_ctx;
int (*read)(git_odb_stream *stream, char *buffer, size_t len); int (*read)(git_odb_stream *stream, char *buffer, size_t len);
int (*write)(git_odb_stream *stream, const char *buffer, size_t len); int (*write)(git_odb_stream *stream, const char *buffer, size_t len);
......
...@@ -871,11 +871,21 @@ int git_odb_write( ...@@ -871,11 +871,21 @@ int git_odb_write(
return error; return error;
} }
static void hash_header(git_hash_ctx *ctx, size_t size, git_otype type)
{
char header[64];
int hdrlen;
hdrlen = git_odb__format_object_header(header, sizeof(header), size, type);
git_hash_update(ctx, header, hdrlen);
}
int git_odb_open_wstream( int git_odb_open_wstream(
git_odb_stream **stream, git_odb *db, size_t size, git_otype type) git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
{ {
size_t i, writes = 0; size_t i, writes = 0;
int error = GIT_ERROR; int error = GIT_ERROR;
git_hash_ctx *ctx;
assert(stream && db); assert(stream && db);
...@@ -901,16 +911,26 @@ int git_odb_open_wstream( ...@@ -901,16 +911,26 @@ int git_odb_open_wstream(
if (error < 0 && !writes) if (error < 0 && !writes)
error = git_odb__error_unsupported_in_backend("write object"); error = git_odb__error_unsupported_in_backend("write object");
ctx = git__malloc(sizeof(git_hash_ctx));
GITERR_CHECK_ALLOC(ctx);
git_hash_ctx_init(ctx);
hash_header(ctx, size, type);
(*stream)->hash_ctx = ctx;
return error; return error;
} }
int git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len) int git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len)
{ {
git_hash_update(stream->hash_ctx, buffer, len);
return stream->write(stream, buffer, len); return stream->write(stream, buffer, len);
} }
int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream) int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream)
{ {
git_hash_final(out, stream->hash_ctx);
return stream->finalize_write(out, stream); return stream->finalize_write(out, stream);
} }
...@@ -921,6 +941,7 @@ int git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len) ...@@ -921,6 +941,7 @@ int git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len)
void git_odb_stream_free(git_odb_stream *stream) void git_odb_stream_free(git_odb_stream *stream)
{ {
git__free(stream->hash_ctx);
stream->free(stream); stream->free(stream);
} }
......
...@@ -776,8 +776,7 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream) ...@@ -776,8 +776,7 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream)
git_buf final_path = GIT_BUF_INIT; git_buf final_path = GIT_BUF_INIT;
int error = 0; int error = 0;
if (git_filebuf_hash(oid, &stream->fbuf) < 0 || if (object_file_name(&final_path, backend, oid) < 0 ||
object_file_name(&final_path, backend, oid) < 0 ||
object_mkdir(&final_path, backend) < 0) object_mkdir(&final_path, backend) < 0)
error = -1; error = -1;
/* /*
...@@ -848,7 +847,6 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_ ...@@ -848,7 +847,6 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_
if (git_buf_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 || if (git_buf_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 ||
git_filebuf_open(&stream->fbuf, tmp_path.ptr, git_filebuf_open(&stream->fbuf, tmp_path.ptr,
GIT_FILEBUF_HASH_CONTENTS |
GIT_FILEBUF_TEMPORARY | GIT_FILEBUF_TEMPORARY |
(backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT)) < 0 || (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT)) < 0 ||
stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0) stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment