Changeset: 70c698cf9f7e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=70c698cf9f7e
Modified Files:
        sql/storage/store.c
Branch: hot-snapshot
Log Message:

Refactor tar writing

Move the block boundary and padding logic to a separate function


diffs (150 lines):

diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -2433,22 +2433,17 @@ tar_write_header(stream *tarfile, const 
        return GDK_SUCCEED;
 }
 
+/* Write data to the stream, padding it with zeroes up to the next
+ * multiple of TAR_BLOCK_SIZE.  Make sure all writes are in multiples
+ * of TAR_BLOCK_SIZE.
+ */
 static gdk_return
-tar_write_data(stream *tarfile, const char *path, time_t mtime, const char 
*data, size_t size)
-{
-       int res;
-
-       res = tar_write_header(tarfile, path, mtime, size);
-       if (res != GDK_SUCCEED)
-               return res;
-
-       // The spec requires us to only write complete blocks.
-       // So first we write all full blocks and then we copy the remainder
-       // into a buffer so we can write a tail block
-
-       size_t tail = size % TAR_BLOCK_SIZE;
-       size_t bulk = size - tail;
-       size_t written = mnstr_write(tarfile, data, 1, bulk);
+tar_write(stream *outfile, const char *data, size_t size)
+{
+       const size_t tail = size % TAR_BLOCK_SIZE;
+       const size_t bulk = size - tail;
+
+       size_t written = mnstr_write(outfile, data, 1, bulk);
        if (written != bulk) {
                GDKerror("Wrote only %ld bytes instead of first %ld", written, 
bulk);
                return GDK_FAIL;
@@ -2457,7 +2452,7 @@ tar_write_data(stream *tarfile, const ch
        if (tail) {
                char buf[TAR_BLOCK_SIZE] = {0};
                memcpy(buf, data + bulk, tail);
-               written = mnstr_write(tarfile, buf, 1, TAR_BLOCK_SIZE);
+               written = mnstr_write(outfile, buf, 1, TAR_BLOCK_SIZE);
                if (written != TAR_BLOCK_SIZE) {
                        GDKerror("Wrote only %ld tail bytes instead of %d", 
written, TAR_BLOCK_SIZE);
                        return GDK_FAIL;
@@ -2467,21 +2462,38 @@ tar_write_data(stream *tarfile, const ch
        return GDK_SUCCEED;
 }
 
+static gdk_return
+tar_write_data(stream *tarfile, const char *path, time_t mtime, const char 
*data, size_t size)
+{
+       int res;
+
+       res = tar_write_header(tarfile, path, mtime, size);
+       if (res != GDK_SUCCEED)
+               return res;
+       
+       return tar_write(tarfile, data, size);
+}
+
 
 static gdk_return
-tar_copy_data(stream *tarfile, const char *path, time_t mtime, stream 
*contents, ssize_t size)
-{
+tar_copy_stream(stream *tarfile, const char *path, time_t mtime, stream 
*contents, ssize_t size)
+{
+       const ssize_t bufsize = 64 * 1024;
        gdk_return ret = GDK_FAIL;
-       ssize_t file_size = getFileSize(contents);
-       const ssize_t bufsize = 64 * 1024;
-       char *buf = malloc(bufsize);
-       ssize_t nbytes;
-
+       ssize_t file_size;
+       char *buf;
+       ssize_t to_read;
+
+       file_size = getFileSize(contents);
        if (file_size < size) {
                GDKerror("Have to copy %ld bytes but only %ld exist in %s", 
size, file_size, path);
                goto end;
        }
 
+       assert( (bufsize % TAR_BLOCK_SIZE) == 0);
+       assert(bufsize > TAR_BLOCK_SIZE);
+
+       buf = malloc(bufsize);
        if (!buf) {
                GDKerror("could not allocate buffer");
                goto end;
@@ -2490,41 +2502,19 @@ tar_copy_data(stream *tarfile, const cha
        if (tar_write_header(tarfile, path, mtime, size) != GDK_SUCCEED)
                goto end;
 
-       assert(bufsize > TAR_BLOCK_SIZE);
-       assert(bufsize % TAR_BLOCK_SIZE == 0);
-
-       // Again, we need to be careful to not write partial blocks.
-
-       while (size > TAR_BLOCK_SIZE) {
-               ssize_t chunk = size <= bufsize ? size : bufsize;
-               chunk -= chunk % TAR_BLOCK_SIZE;
-               assert(chunk > 0);
-               assert(chunk % TAR_BLOCK_SIZE == 0);
-               nbytes = mnstr_read(contents, buf, 1, chunk);
+       to_read = size;
+
+       while (to_read > 0) {
+               ssize_t chunk = (to_read <= bufsize) ? to_read : bufsize;
+               ssize_t nbytes = mnstr_read(contents, buf, 1, chunk);
                if (nbytes != chunk) {
                        GDKerror("Read only %ld/%ld bytes of component %s: %s", 
nbytes, chunk, path, mnstr_error(contents));
                        goto end;
                }
-               nbytes = mnstr_write(tarfile, buf, 1, chunk);
-               if (nbytes != chunk){
-                       GDKerror("Wrote only %ld/%ld bytes of component %s to 
tar file: %s", nbytes, chunk, path, mnstr_error(tarfile));
+               ret = tar_write(tarfile, buf, chunk);
+               if (ret != GDK_SUCCEED)
                        goto end;
-               }
-               size -= chunk;
-       }
-
-       if (size > 0) {
-               memset(buf, 0, TAR_BLOCK_SIZE);
-               nbytes = mnstr_read(contents, buf, 1, size);
-               if (nbytes != size) {
-                       GDKerror("Read only %ld/%ld final bytes of component 
%s: %s", nbytes, size, path, mnstr_error(contents));
-                       goto end;
-               }
-               nbytes = mnstr_write(tarfile, buf, 1, TAR_BLOCK_SIZE);
-               if (nbytes != TAR_BLOCK_SIZE) {
-                       GDKerror("Only wrote %ld/%ld bytes of block of 
component %s to tar file: %s", nbytes, size, path, mnstr_error(tarfile));
-                       goto end;
-               }
+               to_read -= chunk;
        }
 
        ret = GDK_SUCCEED;
@@ -2576,7 +2566,7 @@ hot_snapshot_write_tar(stream *out, cons
                                        GDKerror("Could not open %s", 
abs_src_path);
                                        goto end;
                                }
-                               if (tar_copy_data(out, dest_path, timestamp, 
infile, size) != GDK_SUCCEED)
+                               if (tar_copy_stream(out, dest_path, timestamp, 
infile, size) != GDK_SUCCEED)
                                        goto end;
                                mnstr_close(infile);
                                break;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to