]> wimlib.net Git - wimlib/blobdiff - src/compress_serial.c
Reduce unnecessary copying during chunk compression
[wimlib] / src / compress_serial.c
index b5eb951d8e0391a014311faa44481e3fede60bb5..35470ec531a6ae40bf72d43b91f1a9315fbe9658 100644 (file)
@@ -37,7 +37,9 @@ struct serial_chunk_compressor {
        struct wimlib_compressor *compressor;
        u8 *udata;
        u8 *cdata;
-       u32 ulen;
+       u32 usize;
+       u8 *result_data;
+       u32 result_size;
 };
 
 static void
@@ -54,48 +56,52 @@ serial_chunk_compressor_destroy(struct chunk_compressor *_ctx)
        FREE(ctx);
 }
 
-static bool
-serial_chunk_compressor_submit_chunk(struct chunk_compressor *_ctx,
-                                    const void *chunk, u32 size)
+static void *
+serial_chunk_compressor_get_chunk_buffer(struct chunk_compressor *_ctx)
 {
        struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor*)_ctx;
 
-       if (ctx->ulen != 0)
-               return false;
+       if (ctx->result_data)
+               return NULL;
+       return ctx->udata;
+}
 
-       wimlib_assert(size > 0);
-       wimlib_assert(size <= ctx->base.out_chunk_size);
+static void
+serial_chunk_compressor_signal_chunk_filled(struct chunk_compressor *_ctx, u32 usize)
+{
+       struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor*)_ctx;
+       u32 csize;
 
-       memcpy(ctx->udata, chunk, size);
-       ctx->ulen = size;
-       return true;
+       wimlib_assert(usize > 0);
+       wimlib_assert(usize <= ctx->base.out_chunk_size);
+
+       ctx->usize = usize;
+       csize = wimlib_compress(ctx->udata, usize, ctx->cdata, usize - 1,
+                               ctx->compressor);
+       if (csize) {
+               ctx->result_data = ctx->cdata;
+               ctx->result_size = csize;
+       } else {
+               ctx->result_data = ctx->udata;
+               ctx->result_size = ctx->usize;
+       }
 }
 
 static bool
-serial_chunk_compressor_get_chunk(struct chunk_compressor *_ctx,
-                                 const void **cdata_ret, u32 *csize_ret,
-                                 u32 *usize_ret)
+serial_chunk_compressor_get_compression_result(struct chunk_compressor *_ctx,
+                                              const void **cdata_ret, u32 *csize_ret,
+                                              u32 *usize_ret)
 {
-       struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor*)_ctx;
-       u32 clen;
+       struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor *)_ctx;
 
-       if (ctx->ulen == 0)
+       if (!ctx->result_data)
                return false;
 
-       clen = wimlib_compress(ctx->udata, ctx->ulen,
-                              ctx->cdata, ctx->ulen - 1,
-                              ctx->compressor);
-
-       if (clen) {
-               *cdata_ret = ctx->cdata;
-               *csize_ret = clen;
-       } else {
-               *cdata_ret = ctx->udata;
-               *csize_ret = ctx->ulen;
-       }
-       *usize_ret = ctx->ulen;
+       *cdata_ret = ctx->result_data;
+       *csize_ret = ctx->result_size;
+       *usize_ret = ctx->usize;
 
-       ctx->ulen = 0;
+       ctx->result_data = NULL;
        return true;
 }
 
@@ -116,8 +122,9 @@ new_serial_chunk_compressor(int out_ctype, u32 out_chunk_size,
        ctx->base.out_chunk_size = out_chunk_size;
        ctx->base.num_threads = 1;
        ctx->base.destroy = serial_chunk_compressor_destroy;
-       ctx->base.submit_chunk = serial_chunk_compressor_submit_chunk;
-       ctx->base.get_chunk = serial_chunk_compressor_get_chunk;
+       ctx->base.get_chunk_buffer = serial_chunk_compressor_get_chunk_buffer;
+       ctx->base.signal_chunk_filled = serial_chunk_compressor_signal_chunk_filled;
+       ctx->base.get_compression_result = serial_chunk_compressor_get_compression_result;
 
        ret = wimlib_create_compressor(out_ctype, out_chunk_size,
                                       0, &ctx->compressor);
@@ -126,11 +133,11 @@ new_serial_chunk_compressor(int out_ctype, u32 out_chunk_size,
 
        ctx->udata = MALLOC(out_chunk_size);
        ctx->cdata = MALLOC(out_chunk_size - 1);
-       ctx->ulen = 0;
        if (ctx->udata == NULL || ctx->cdata == NULL) {
                ret = WIMLIB_ERR_NOMEM;
                goto err;
        }
+       ctx->result_data = NULL;
 
        *compressor_ret = &ctx->base;
        return 0;