/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 COPYING file, which can be found at the root of the source code * * distribution tree, or in https://www.hdfgroup.org/licenses. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*------------------------------------------------------------------------- * * Created: swmr_common.c * * Purpose: Utility functions for the SWMR test code. * *------------------------------------------------------------------------- */ /***********/ /* Headers */ /***********/ #include "h5test.h" #include "swmr_common.h" #include "vds_swmr.h" /*******************/ /* Local Variables */ /*******************/ /* The SWMR data arrays: * * The code uses a 2-D jagged array of datasets. The first dimension is called * the 'level' and there are five of them. * * #define NLEVELS 5 * * The second dimension is the 'count' and there are quite a few datasets per * 'level'. * * unsigned symbol_count[NLEVELS] = {100, 200, 400, 800, 1600}; * * These datasets are created when the skeleton is generated and are initially * empty. Each dataset has no upper bound on size (H5S_UNLIMITED). They * are of compound type, with two members: an integer ID and an opaque * 'data part'. The data part is not used by the SWMR testing. * * The SWMR testing will then randomly add and/or remove entries * from these datasets. The selection of the level is skewed by a mapping * table which preferentially hammers on the lower levels with their smaller * number of datasets. * * static unsigned symbol_mapping[NMAPPING] = {0, 0, 0, 0, 1, 1, 2, 3, 4}; * * The information about each dataset (name, hid_t, etc.) is stored in a * separate array. * * symbol_info_t *symbol_info[NLEVELS]; */ /* An array of dataset levels, used to select the level for a SWMR operation * Note that this preferentially selects the lower levels with their smaller * number of datasets. */ static unsigned symbol_mapping[NMAPPING] = {0, 0, 0, 0, 1, 1, 2, 3, 4}; /* The number of datasets at each level */ unsigned symbol_count[NLEVELS] = {100, 200, 400, 800, 1600}; /* Array of dataset information entries (1 per dataset) */ symbol_info_t *symbol_info[NLEVELS]; hsize_t PLANES[N_SOURCES][RANK] = {{1, SM_HEIGHT, WIDTH}, {1, LG_HEIGHT, WIDTH}, {1, SM_HEIGHT, WIDTH}, {1, LG_HEIGHT, WIDTH}, {1, SM_HEIGHT, WIDTH}, {1, LG_HEIGHT, WIDTH}}; char FILE_NAMES[N_SOURCES][NAME_LEN] = {{"vds_swmr_src_a.h5"}, {"vds_swmr_src_b.h5"}, {"vds_swmr_src_c.h5"}, {"vds_swmr_src_d.h5"}, {"vds_swmr_src_e.h5"}, {"vds_swmr_src_f.h5"}}; char VDS_FILE_NAME[NAME_LEN] = "vds_swmr.h5"; char SOURCE_DSET_PATH[NAME_LEN] = "/source_dset"; char VDS_DSET_NAME[NAME_LEN] = "vds_dset"; /*------------------------------------------------------------------------- * Function: choose_dataset * * Purpose: Selects a random dataset in the SWMR file * * Parameters: N/A * * Return: Success: A pointer to information about a dataset. * Failure: Can't fail * *------------------------------------------------------------------------- */ symbol_info_t * choose_dataset(void) { unsigned level; /* The level of the dataset */ unsigned offset; /* The "offset" of the dataset at that level */ /* Determine level of dataset */ level = symbol_mapping[HDrandom() % NMAPPING]; /* Determine the offset of the level */ offset = (unsigned)(HDrandom() % (int)symbol_count[level]); return &symbol_info[level][offset]; } /* end choose_dataset() */ /*------------------------------------------------------------------------- * Function: create_symbol_datatype * * Purpose: Create's the HDF5 datatype used for elements in the SWMR * testing datasets. * * Parameters: N/A * * Return: Success: An HDF5 type ID * Failure: -1 * *------------------------------------------------------------------------- */ hid_t create_symbol_datatype(void) { hid_t sym_type_id; /* Datatype ID for symbol */ hid_t opaq_type_id; /* Datatype ID for opaque part of record */ /* Create opaque datatype to represent other information for this record */ if ((opaq_type_id = H5Tcreate(H5T_OPAQUE, (size_t)DTYPE_SIZE)) < 0) return -1; /* Create compound datatype for symbol */ if ((sym_type_id = H5Tcreate(H5T_COMPOUND, sizeof(symbol_t))) < 0) return -1; /* Insert fields in symbol datatype */ if (H5Tinsert(sym_type_id, "rec_id", HOFFSET(symbol_t, rec_id), H5T_NATIVE_UINT64) < 0) return -1; if (H5Tinsert(sym_type_id, "info", HOFFSET(symbol_t, info), opaq_type_id) < 0) return -1; /* Close opaque datatype */ if (H5Tclose(opaq_type_id) < 0) return -1; return sym_type_id; } /* end create_symbol_datatype() */ /*------------------------------------------------------------------------- * Function: generate_name * * Purpose: Generates a SWMR testing dataset name given a level and * count. * The name is in the format - (%u-%04u). * * Parameters: char *name_buf * Buffer for the created name. Must be pre-allocated. * Since the name is formulaic, this isn't considered an issue. * * size_t name_buf_length * The length in bytes of the name_buf buffer * * unsigned level * The dataset's level * * unsigned count * The dataset's count * * Return: Success: 0 * * Failure: Can't fail * *------------------------------------------------------------------------- */ int generate_name(char *name_buf, size_t name_buf_length, unsigned level, unsigned count) { HDassert(name_buf); HDsnprintf(name_buf, name_buf_length, "%u-%04u", level, count); return 0; } /* end generate_name() */ /*------------------------------------------------------------------------- * Function: generate_symbols * * Purpose: Initializes the global dataset information arrays. * * Parameters: N/A * * Return: Success: 0 * Failure: Can't fail * *------------------------------------------------------------------------- */ int generate_symbols(void) { unsigned u, v; /* Local index variables */ for (u = 0; u < NLEVELS; u++) { symbol_info[u] = HDmalloc(symbol_count[u] * sizeof(symbol_info_t)); for (v = 0; v < symbol_count[u]; v++) { char name_buf[64]; generate_name(name_buf, sizeof(name_buf), u, v); symbol_info[u][v].name = HDstrdup(name_buf); symbol_info[u][v].dsid = -1; symbol_info[u][v].nrecords = 0; } /* end for */ } /* end for */ return 0; } /* end generate_symbols() */ /*------------------------------------------------------------------------- * Function: shutdown_symbols * * Purpose: Cleans up the global dataset information arrays. * * Parameters: N/A * * Return: Success: 0 * Failure: Can't fail * *------------------------------------------------------------------------- */ int shutdown_symbols(void) { unsigned u, v; /* Local index variables */ /* Clean up the symbols */ for (u = 0; u < NLEVELS; u++) { for (v = 0; v < symbol_count[u]; v++) HDfree(symbol_info[u][v].name); HDfree(symbol_info[u]); } /* end for */ return 0; } /* end shutdown_symbols() */ /*------------------------------------------------------------------------- * Function: print_metadata_retries_info * * Purpose: To retrieve and print the collection of metadata retries for the file. * * Parameters: fid: the currently opened file identifier * * Return: Success: 0 * Failure: negative * *------------------------------------------------------------------------- */ int print_metadata_retries_info(hid_t fid) { H5F_retry_info_t info; unsigned i; /* Retrieve the collection of retries */ if (H5Fget_metadata_read_retry_info(fid, &info) < 0) return (-1); /* Print information for each non-NULL retries[i] */ for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++) { unsigned power; unsigned j; if (NULL == info.retries[i]) continue; HDfprintf(stderr, "Metadata read retries for item %u:\n", i); power = 1; for (j = 0; j < info.nbins; j++) { if (info.retries[i][j]) HDfprintf(stderr, "\t# of retries for %u - %u retries: %u\n", power, (power * 10) - 1, info.retries[i][j]); power *= 10; } /* end for */ } /* end for */ /* Free memory for each non-NULL retries[i] */ for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++) if (info.retries[i] != NULL) H5free_memory(info.retries[i]); return 0; } /* print_metadata_retries_info() */