/*------------------------------------------------------------------------- * Function: monitor_dataset * * Purpose: To poll a dataset periodically for changes in dimension sizes. * For dataset with unchanged and/or decreased dimension sizes: * it just prints the dimension size changes * For dataset with increase in at least one of its dimension sizes: * it will print the new appended data to the dataset * * Return: Non-negative on success: dataset can be monitored * Negative on failure: dataset cannot be monitored * * Programmer: Vailin Choi; August 2010 * *------------------------------------------------------------------------- */ static herr_t monitor_dataset(hid_t fid, char *dsetname) { hid_t did; /* dataset id */ hid_t sid; /* dataspace id */ int ndims; /* # of dimensions in the dataspace */ int i, u; /* local index variable */ hsize_t prev_dims[H5S_MAX_RANK]; /* current dataspace dimensions */ hsize_t cur_dims[H5S_MAX_RANK]; /* previous dataspace dimensions */ herr_t ret_value = SUCCEED; /* return value */ HDfprintf(stdout, "Monitoring dataset %s...\n", dsetname); /* Open the dataset for minitoring */ if((did = H5Dopen2(fid, dsetname, H5P_DEFAULT)) < 0) { error_msg("error in opening dataset \"%s\"\n", dsetname); ret_value = FAIL; goto done; } if((sid = H5Dget_space(did)) < 0) { error_msg("error in getting dataspace id for dataset \"%s\"\n", dsetname); ret_value = FAIL; goto done; } /* Get the dataset's dimension sizes */ if((ndims = H5Sget_simple_extent_dims(sid, prev_dims, NULL)) < 0) { error_msg("unable to get dimensions sizes for \"%s\"\n", dsetname); ret_value = FAIL; goto done; } while(1) { /* Refreshes the dataset */ if(H5Drefresh(did) < 0) { ret_value = FAIL; goto done; } /* Get the dataset's current dimension sizes */ if(H5LDget_dset_dims(did, cur_dims) < 0) { error_msg("unable to get dimension sizes for \"%s\"\n", dsetname); ret_value = FAIL; goto done; } /* Check the dimension sizes */ for(i = 0; i < ndims; i++) if(cur_dims[i] != prev_dims[i]) break; /* at least one dimension has changed */ if(i != ndims) { /* Printing changes in dimension sizes */ for(u = 0; u < ndims; u++) { HDfprintf(stdout, "dimension %u: %Hu->%Hu", (unsigned)u, prev_dims[u], cur_dims[u]); if(cur_dims[u] > prev_dims[u]) HDfprintf(stdout, " (increases)\n"); else if(cur_dims[u] < prev_dims[u]) HDfprintf(stdout, " (decreases)\n"); else HDfprintf(stdout, " (unchanged)\n"); } /* Printing elements appended to the dataset if there is */ if(!g_monitor_size_only) { /* See if at least one dimension size has increased */ for(u = 0; u < ndims; u++) { int j; hsize_t start[H5S_MAX_RANK]; hsize_t block[H5S_MAX_RANK]; /* Print the new appended data to the dataset */ if(cur_dims[u] > prev_dims[u]) { HDfprintf(stdout, " Data:\n"); for(j = 0; j < ndims; j++) { start[j] = 0; block[j] = 1; } if((ret_value = slicendump(did, prev_dims, cur_dims, start, block, ndims, ndims)) < 0) goto done; break; } } /* end for */ } HDfflush(stdout); } /* Save the current dimension sizes */ HDmemcpy(prev_dims, cur_dims, (size_t)ndims * sizeof(hsize_t)); /* Sleep before next monitor */ HDsleep(g_polling_interval); } /* end while */ done: /* Closing */ H5E_BEGIN_TRY H5Dclose(did); H5E_END_TRY return(ret_value); } /* monitor_dataset() */
/*------------------------------------------------------------------------- * Function: read_records * * Purpose: For a given dataset, checks to make sure that the stated * and actual sizes are the same. If they are not, then * we have an inconsistent dataset due to a SWMR error. * * Parameters: const char *filename * The SWMR test file's name. * * unsigned verbose * Whether verbose console output is desired. * * unsigned long nrecords * The total number of records to read. * * unsigned poll_time * The amount of time to sleep (s). * * unsigned reopen_count * * * Return: Success: 0 * Failure: -1 * *------------------------------------------------------------------------- */ static int read_records(const char *filename, unsigned verbose, unsigned long nrecords, unsigned poll_time, unsigned reopen_count) { hid_t fid; /* File ID */ hid_t aid; /* Attribute ID */ time_t start_time; /* Starting time */ hid_t mem_sid; /* Memory dataspace ID */ symbol_t record; /* The record to add to the dataset */ unsigned seed; /* Seed for random number generator */ unsigned iter_to_reopen = reopen_count; /* # of iterations until reopen */ unsigned long u; /* Local index variable */ hid_t fapl; HDassert(filename); HDassert(poll_time != 0); /* Create file access property list */ if((fapl = h5_fileaccess()) < 0) return -1; H5Pset_fclose_degree(fapl, H5F_CLOSE_SEMI); /* Emit informational message */ if(verbose) HDfprintf(stderr, "Opening file: %s\n", filename); /* Open the file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0) return -1; /* Seed the random number generator with the attribute in the file */ if((aid = H5Aopen(fid, "seed", H5P_DEFAULT)) < 0) return -1; if(H5Aread(aid, H5T_NATIVE_UINT, &seed) < 0) return -1; if(H5Aclose(aid) < 0) return -1; HDsrandom(seed); /* Reset the record */ /* (record's 'info' field might need to change for each record written, also) */ HDmemset(&record, 0, sizeof(record)); /* Create a dataspace for the record to read */ if((mem_sid = H5Screate(H5S_SCALAR)) < 0) return -1; /* Emit informational message */ if(verbose) HDfprintf(stderr, "Reading records\n"); /* Get the starting time */ start_time = HDtime(NULL); /* Read records */ for(u = 0; u < nrecords; u++) { symbol_info_t *symbol = NULL; /* Symbol (dataset) */ htri_t attr_exists; /* Whether the sequence number attribute exists */ unsigned long file_u; /* Attribute sequence number (writer's "u") */ /* Get a random dataset, according to the symbol distribution */ symbol = choose_dataset(); /* Fill in "nrecords" field. Note that this depends on the writer * using the same algorithm and "nrecords" */ symbol->nrecords = nrecords / 5; /* Wait until we can read the dataset */ do { /* Check if sequence attribute exists */ if((attr_exists = H5Aexists_by_name(fid, symbol->name, "seq", H5P_DEFAULT)) < 0) return -1; if(attr_exists) { /* Read sequence number attribute */ if((aid = H5Aopen_by_name(fid, symbol->name, "seq", H5P_DEFAULT, H5P_DEFAULT)) < 0) return -1; if(H5Aread(aid, H5T_NATIVE_ULONG, &file_u) < 0) return -1; if(H5Aclose(aid) < 0) return -1; /* Check if sequence number is at least u - if so, this should * guarantee that this record has been written */ if(file_u >= u) break; } /* end if */ /* Check for timeout */ if(HDtime(NULL) >= (time_t)(start_time + (time_t)TIMEOUT)) { HDfprintf(stderr, "Reader timed out\n"); return -1; } /* end if */ /* Pause */ HDsleep(poll_time); /* Retrieve and print the collection of metadata read retries */ if(print_metadata_retries_info(fid) < 0) HDfprintf(stderr, "Warning: could not obtain metadata retries info\n"); /* Reopen the file */ if(H5Fclose(fid) < 0) return -1; if((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0) return -1; iter_to_reopen = reopen_count; } while(1); /* Emit informational message */ if(verbose) HDfprintf(stderr, "Checking dataset %lu\n", u); /* Check dataset */ if(check_dataset(fid, verbose, symbol, &record, mem_sid) < 0) return -1; HDmemset(&record, 0, sizeof(record)); /* Check for reopen */ iter_to_reopen--; if(iter_to_reopen == 0) { /* Emit informational message */ if(verbose) HDfprintf(stderr, "Reopening file: %s\n", filename); /* Retrieve and print the collection of metadata read retries */ if(print_metadata_retries_info(fid) < 0) HDfprintf(stderr, "Warning: could not obtain metadata retries info\n"); /* Reopen the file */ if(H5Fclose(fid) < 0) return -1; if((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0) return -1; iter_to_reopen = reopen_count; } /* end if */ } /* end while */ /* Retrieve and print the collection of metadata read retries */ if(print_metadata_retries_info(fid) < 0) HDfprintf(stderr, "Warning: could not obtain metadata retries info\n"); /* Close file */ if(H5Fclose(fid) < 0) return -1; /* Close the memory dataspace */ if(H5Sclose(mem_sid) < 0) return -1; return 0; } /* end read_records() */