diff options
Diffstat (limited to 'test/use_append_chunk.c')
-rw-r--r-- | test/use_append_chunk.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/test/use_append_chunk.c b/test/use_append_chunk.c new file mode 100644 index 0000000..1dd76c9 --- /dev/null +++ b/test/use_append_chunk.c @@ -0,0 +1,233 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Use Case 1.7 Appending a single chunk + * Description: + * Appending a single chunk of raw data to a dataset along an unlimited + * dimension within a pre-created file and reading the new data back. + * Goal: + * Read data appended by the Writer to a pre-existing dataset in a + * file. The dataset has one or more unlimited dimensions. The data is + * appended by a hyperslab that is contained in one chunk (for example, + * appending 2-dim planes along the slowest changing dimension in the + * 3-dim dataset). + * Level: + * User Level + * Guarantees: + * o Readers will see the modified dimension sizes after the Writer + * finishes HDF5 metadata updates and issues H5Fflush or H5Oflush calls. + * o Readers will see newly appended data after the Writer finishes + * the flush operation. + * + * Preconditions: + * o Readers are not allowed to modify the file. o All datasets + * that are modified by the Writer exist when the Writer opens the file. + * o All datasets that are modified by the Writer exist when a Reader + * opens the file. o Data is written by a hyperslab contained in + * one chunk. + * + * Main Success Scenario: + * 1. An application creates a file with required objects (groups, + * datasets, and attributes). + * 2. The Writer application opens the file and datasets in the file + * and starts adding data along the unlimited dimension using a hyperslab + * selection that corresponds to an HDF5 chunk. + * 3. A Reader opens the file and a dataset in a file, and queries + * the sizes of the dataset; if the extent of the dataset has changed, + * reads the appended data back. + * + * Discussion points: + * 1. Since the new data is written to the file, and metadata update + * operation of adding pointer to the newly written chunk is atomic and + * happens after the chunk is on the disk, only two things may happen + * to the Reader: + * o The Reader will not see new data. + * o The Reader will see all new data written by Writer. + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Created: Albert Cheng, 2013/5/28 */ + +#include "h5test.h" + +/* This test uses many POSIX things that are not available on + * Windows. We're using a check for fork(2) here as a proxy for + * all POSIX/Unix/Linux things until this test can be made + * more platform-independent. + */ +#ifdef H5_HAVE_FORK + +#include "use.h" + +/* Global Variable definitions */ +options_t UC_opts; /* Use Case Options */ +const char *progname_g="use_append_chunk"; /* program name */ + +/* Setup parameters for the use case. + * Return: 0 succeed; -1 fail. + */ +int setup_parameters(int argc, char * const argv[]) +{ + /* use case defaults */ + HDmemset(&UC_opts, 0, sizeof(options_t)); + UC_opts.chunksize = Chunksize_DFT; + UC_opts.use_swmr = 1; /* use swmr open */ + UC_opts.iterations = 1; + UC_opts.chunkplanes = 1; + + /* parse options */ + if (parse_option(argc, argv) < 0){ + return(-1); + } + /* set chunk dims */ + UC_opts.chunkdims[0] = UC_opts.chunkplanes; + UC_opts.chunkdims[1]=UC_opts.chunkdims[2]=UC_opts.chunksize; + + /* set dataset initial and max dims */ + UC_opts.dims[0] = 0; + UC_opts.max_dims[0] = H5S_UNLIMITED; + UC_opts.dims[1] = UC_opts.dims[2] = UC_opts.max_dims[1]=UC_opts.max_dims[2]=UC_opts.chunksize; + + /* set nplanes */ + if (UC_opts.nplanes == 0) + UC_opts.nplanes = UC_opts.chunksize; + + /* show parameters and return */ + show_parameters(); + return(0); +} + + +/* Overall Algorithm: + * Parse options from user; + * Generate/pre-created test files needed and close it; + * fork: child process becomes the reader process; + * while parent process continues as the writer process; + * both run till ending conditions are met. + */ +int +main(int argc, char *argv[]) +{ + pid_t childpid=0; + pid_t mypid, tmppid; + int child_status; + int child_wait_option=0; + int ret_value = 0; + int child_ret_value; + hbool_t send_wait = 0; + + /* initialization */ + if (setup_parameters(argc, argv) < 0){ + Hgoto_error(1); + } + + /* Determine the need to send/wait message file*/ + if(UC_opts.launch == UC_READWRITE) { + HDunlink(WRITER_MESSAGE); + send_wait = 1; + } + + /* ==============================================================*/ + /* UC_READWRITE: create datafile, launch both reader and writer. */ + /* UC_WRITER: create datafile, skip reader, launch writer. */ + /* UC_READER: skip create, launch reader, exit. */ + /* ==============================================================*/ + /* ============*/ + /* Create file */ + /* ============*/ + if (UC_opts.launch != UC_READER){ + printf("Creating skeleton data file for test...\n"); + if (create_uc_file() < 0){ + fprintf(stderr, "***encounter error\n"); + Hgoto_error(1); + }else + printf("File created.\n"); + } + + if (UC_opts.launch==UC_READWRITE){ + /* fork process */ + if((childpid = fork()) < 0) { + perror("fork"); + Hgoto_error(1); + }; + }; + mypid = getpid(); + + /* ============= */ + /* launch reader */ + /* ============= */ + if (UC_opts.launch != UC_WRITER){ + /* child process launch the reader */ + if(0 == childpid) { + printf("%d: launch reader process\n", mypid); + if (read_uc_file(send_wait) < 0){ + fprintf(stderr, "read_uc_file encountered error\n"); + exit(1); + } + exit(0); + } + } + + /* ============= */ + /* launch writer */ + /* ============= */ + /* this process continues to launch the writer */ + printf("%d: continue as the writer process\n", mypid); + if (write_uc_file(send_wait) < 0){ + fprintf(stderr, "write_uc_file encountered error\n"); + Hgoto_error(1); + } + + /* ================================================ */ + /* If readwrite, collect exit code of child process */ + /* ================================================ */ + if (UC_opts.launch == UC_READWRITE){ + if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0){ + perror("waitpid"); + Hgoto_error(1); + } + if (WIFEXITED(child_status)){ + if ((child_ret_value=WEXITSTATUS(child_status)) != 0){ + printf("%d: child process exited with non-zero code (%d)\n", + mypid, child_ret_value); + Hgoto_error(2); + } + } else { + printf("%d: child process terminated abnormally\n", mypid); + Hgoto_error(2); + } + } + +done: + /* Print result and exit */ + if (ret_value != 0){ + printf("Error(s) encountered\n"); + }else{ + printf("All passed\n"); + } + + return(ret_value); +} + +#else /* H5_HAVE_FORK */ + +int +main(void) +{ + HDfprintf(stderr, "Non-POSIX platform. Skipping.\n"); + return EXIT_SUCCESS; +} /* end main() */ + +#endif /* H5_HAVE_FORK */ + |