]> git.proxmox.com Git - libgit2.git/commitdiff
odb: perform the stream hashing in the frontend
authorCarlos Martín Nieto <cmn@dwim.me>
Thu, 15 Aug 2013 12:29:39 +0000 (14:29 +0200)
committerCarlos Martín Nieto <cmn@dwim.me>
Thu, 15 Aug 2013 12:29:39 +0000 (14:29 +0200)
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.

include/git2/odb_backend.h
src/odb.c
src/odb_loose.c

index af1e3e5b9e5bc94eceff5a0d8da2028cf2b1c8bd..d004238a496f7fb546a57c9f7f9f08d770233db6 100644 (file)
@@ -65,10 +65,13 @@ typedef enum {
        GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY),
 } git_odb_stream_t;
 
+typedef struct git_hash_ctx git_hash_ctx;
+
 /** A stream to read/write from a backend */
 struct git_odb_stream {
        git_odb_backend *backend;
        unsigned int mode;
+       git_hash_ctx *hash_ctx;
 
        int (*read)(git_odb_stream *stream, char *buffer, size_t len);
        int (*write)(git_odb_stream *stream, const char *buffer, size_t len);
index 1581596620bb60d4ded97f49db1d5bbf527efe16..b7f64dfc93ee41971e1d175913e3d966563ebc00 100644 (file)
--- a/src/odb.c
+++ b/src/odb.c
@@ -871,11 +871,21 @@ int git_odb_write(
        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(
        git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
 {
        size_t i, writes = 0;
        int error = GIT_ERROR;
+       git_hash_ctx *ctx;
 
        assert(stream && db);
 
@@ -901,16 +911,26 @@ int git_odb_open_wstream(
        if (error < 0 && !writes)
                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;
 }
 
 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);
 }
 
 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);
 }
 
@@ -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)
 {
+       git__free(stream->hash_ctx);
        stream->free(stream);
 }
 
index 76ed8e232708e146002810814dba22c89a8776cd..a0c2c8c4c53e51aa2bd6bdc5f3ede6c9ba2f7dcb 100644 (file)
@@ -776,8 +776,7 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream)
        git_buf final_path = GIT_BUF_INIT;
        int error = 0;
 
-       if (git_filebuf_hash(oid, &stream->fbuf) < 0 ||
-               object_file_name(&final_path, backend, oid) < 0 ||
+       if (object_file_name(&final_path, backend, oid) < 0 ||
                object_mkdir(&final_path, backend) < 0)
                error = -1;
        /*
@@ -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 ||
                git_filebuf_open(&stream->fbuf, tmp_path.ptr,
-                       GIT_FILEBUF_HASH_CONTENTS |
                        GIT_FILEBUF_TEMPORARY |
                        (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT)) < 0 ||
                stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0)