diff options
Diffstat (limited to 'src/H5C.c')
-rw-r--r-- | src/H5C.c | 1392 |
1 files changed, 1392 insertions, 0 deletions
diff --git a/src/H5C.c b/src/H5C.c new file mode 100644 index 0000000..e62bc0a --- /dev/null +++ b/src/H5C.c @@ -0,0 +1,1392 @@ +/**************************************************************************** +* NCSA HDF * +* Software Development Group * +* National Center for Supercomputing Applications * +* University of Illinois at Urbana-Champaign * +* 605 E. Springfield, Champaign IL 61820 * +* * +* For conditions of distribution and use, see the accompanying * +* hdf/COPYING file. * +* * +****************************************************************************/ + +#ifdef RCSID +static char RcsId[] = "@(#)$Revision$"; +#endif + +/* $Id$ */ + +#include <stdarg.h> + +/* Private header files */ +#include <H5private.h> /* Generic Functions */ +#include <H5Aprivate.h> /* Atoms */ +#include <H5Bprivate.h> /* B-tree subclass names */ +#include <H5Cprivate.h> /* Template information */ +#include <H5Dprivate.h> /* Datasets */ +#include <H5Eprivate.h> /* Error handling */ +#include <H5MMprivate.h> /* Memory management */ + +#define PABLO_MASK H5C_mask + +/* Is the interface initialized? */ +static hbool_t interface_initialize_g = FALSE; +#define INTERFACE_INIT H5C_init_interface +static herr_t H5C_init_interface(void); + +/* PRIVATE PROTOTYPES */ +static void H5C_term_interface(void); + +/*-------------------------------------------------------------------------- +NAME + H5C_init_interface -- Initialize interface-specific information +USAGE + herr_t H5C_init_interface() + +RETURNS + SUCCEED/FAIL +DESCRIPTION + Initializes any interface-specific data or routines. + +--------------------------------------------------------------------------*/ +static herr_t +H5C_init_interface(void) +{ + herr_t ret_value = SUCCEED; + intn i; + herr_t status; + + FUNC_ENTER(H5C_init_interface, FAIL); + + /* + * Make sure the file creation and file access default templates are + * initialized since this might be done at run-time instead of compile + * time. + */ + if (H5F_init_interface ()<0) { + HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL, + "unable to initialize H5F and H5C interfaces"); + } + + assert(H5C_NCLASSES <= H5_TEMPLATE_MAX - H5_TEMPLATE_0); + + /* + * Initialize the mappings between template classes and atom groups. We + * keep the two separate because template classes are publicly visible but + * atom groups aren't. + */ + for (i = 0; i < H5C_NCLASSES; i++) { + status = H5A_init_group((group_t)(H5_TEMPLATE_0 +i), + H5A_TEMPID_HASHSIZE, 0, NULL); + if (status < 0) ret_value = FAIL; + } + if (ret_value < 0) { + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + "unable to initialize atom group"); + } + + /* + * Register cleanup function. + */ + if (H5_add_exit(H5C_term_interface) < 0) { + HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, + "unable to install atexit function"); + } + + FUNC_LEAVE(ret_value); +} + +/*-------------------------------------------------------------------------- + NAME + H5C_term_interface + PURPOSE + Terminate various H5C objects + USAGE + void H5C_term_interface() + RETURNS + SUCCEED/FAIL + DESCRIPTION + Release the atom group and any other resources allocated. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Can't report errors... + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static void +H5C_term_interface(void) +{ + intn i; + + for (i = 0; i < H5C_NCLASSES; i++) { + H5A_destroy_group((group_t)(H5_TEMPLATE_0 + i)); + } +} + +/*-------------------------------------------------------------------------- + NAME + H5Ccreate + PURPOSE + Returns a copy of the default template for some class of templates. + USAGE + herr_t H5Ccreate (type) + H5C_class_t type; IN: Template class whose default is desired. + RETURNS + Template ID or FAIL + + ERRORS + ARGS BADVALUE Unknown template class. + ATOM CANTINIT Can't register template. + INTERNAL UNSUPPORTED Not implemented yet. + + DESCRIPTION + Returns a copy of the default template for some class of templates. +--------------------------------------------------------------------------*/ +hid_t +H5Ccreate(H5C_class_t type) +{ + hid_t ret_value = FAIL; + void *tmpl = NULL; + + FUNC_ENTER(H5Ccreate, FAIL); + + /* Allocate a new template and initialize it with default values */ + switch (type) { + case H5C_FILE_CREATE: + tmpl = H5MM_xmalloc(sizeof(H5F_create_t)); + memcpy(tmpl, &H5F_create_dflt, sizeof(H5F_create_t)); + break; + + case H5C_FILE_ACCESS: + tmpl = H5MM_xmalloc(sizeof(H5F_access_t)); + memcpy(tmpl, &H5F_access_dflt, sizeof(H5F_access_t)); + break; + + case H5C_DATASET_CREATE: + tmpl = H5MM_xmalloc(sizeof(H5D_create_t)); + memcpy(tmpl, &H5D_create_dflt, sizeof(H5D_create_t)); + break; + + case H5C_DATASET_XFER: + tmpl = H5MM_xmalloc(sizeof(H5D_xfer_t)); + memcpy(tmpl, &H5D_xfer_dflt, sizeof(H5D_xfer_t)); + break; + + default: + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "unknown template class"); + } + + /* Atomize the new template */ + if ((ret_value = H5C_create(type, tmpl)) < 0) { + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + "can't register template"); + } + FUNC_LEAVE(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5C_create + * + * Purpose: Given a pointer to some template struct, atomize the template + * and return its ID. The template memory is not copied, so the + * caller should not free it; it will be freed by H5C_release(). + * + * Return: Success: A new template ID. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, December 3, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5C_create(H5C_class_t type, void *tmpl) +{ + hid_t ret_value = FAIL; + + FUNC_ENTER(H5C_create, FAIL); + + /* check args */ + assert(type >= 0 && type < H5C_NCLASSES); + assert(tmpl); + + /* Atomize the new template */ + if ((ret_value=H5A_register((group_t)(H5_TEMPLATE_0+type), tmpl)) < 0) { + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + "can't register template"); + } + + FUNC_LEAVE(ret_value); +} + +/*-------------------------------------------------------------------------- + NAME + H5Cclose + PURPOSE + Release access to a template object. + USAGE + herr_t H5Cclose(oid) + hid_t oid; IN: Template object to release access to + RETURNS + SUCCEED/FAIL + DESCRIPTION + This function releases access to a template object +--------------------------------------------------------------------------*/ +herr_t +H5Cclose(hid_t tid) +{ + H5C_class_t type; + void *tmpl = NULL; + + FUNC_ENTER(H5Cclose, FAIL); + + /* Check arguments */ + if ((type=H5Cget_class (tid))<0 || + NULL==(tmpl=H5A_object (tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + } + + /* + * Chuck the object! When the reference count reaches zero then + * H5A_dec_ref() removes it from the group and we should free it. The + * free function is not registered as part of the group because it takes + * an extra argument. + */ + if (0==H5A_dec_ref(tid)) H5C_close (type, tmpl); + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5C_close + * + * Purpose: Closes a template and frees the memory associated with the + * template. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, February 18, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_close (H5C_class_t type, void *tmpl) +{ + FUNC_ENTER (H5C_close, FAIL); + + /* Check args */ + assert (tmpl); + + /* Some templates may need to do special things */ + switch (type) { + case H5C_FILE_ACCESS: +#ifdef LATER + /* Need to free the COMM and INFO objects too. */ +#endif + break; + + case H5C_FILE_CREATE: + case H5C_DATASET_CREATE: + case H5C_DATASET_XFER: + /*nothing to do*/ + break; + + default: + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "unknown property list class"); + } + + /* Free the template struct and return */ + H5MM_xfree(tmpl); + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Cget_class + * + * Purpose: Returns the class identifier for a template. + * + * Return: Success: A template class + * + * Failure: H5C_NO_CLASS (-1) + * + * Programmer: Robb Matzke + * Wednesday, December 3, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5C_class_t +H5Cget_class(hid_t tid) +{ + group_t group; + H5C_class_t ret_value = H5C_NO_CLASS; + + FUNC_ENTER(H5Cget_class, H5C_NO_CLASS); + + if ((group = H5A_group(tid)) < 0 || +#ifndef NDEBUG + group >= H5_TEMPLATE_MAX || +#endif + group < H5_TEMPLATE_0) { + HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, H5C_NO_CLASS, "not a template"); + } + ret_value = (H5C_class_t)(group - H5_TEMPLATE_0); + FUNC_LEAVE(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5Cget_version + * + * Purpose: Retrieves version information for various parts of a file. + * + * BOOT: The file boot block. + * HEAP: The global heap. + * FREELIST: The global free list. + * STAB: The root symbol table entry. + * SHHDR: Shared object headers. + * + * Any (or even all) of the output arguments can be null + * pointers. + * + * Return: Success: SUCCEED, version information is returned + * through the arguments. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cget_version(hid_t tid, int *boot /*out */ , int *heap /*out */ , + int *freelist /*out */ , int *stab /*out */ , int *shhdr /*out */ ) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cget_version, FAIL); + + /* Check arguments */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + /* Get values */ + if (boot) + *boot = tmpl->bootblock_ver; + if (heap) + *heap = tmpl->smallobject_ver; + if (freelist) + *freelist = tmpl->freespace_ver; + if (stab) + *stab = tmpl->objectdir_ver; + if (shhdr) + *shhdr = tmpl->sharedheader_ver; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cset_userblock + * + * Purpose: Sets the userblock size field of a file creation template. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 6, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_userblock(hid_t tid, size_t size) +{ + intn i; + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cset_userblock, FAIL); + + /* Check arguments */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + for (i = 8; i < 8 * sizeof(int); i++) { + uintn p2 = 8 == i ? 0 : 1 << i; + if (size == p2) + break; + } + if (i >= 8 * sizeof(int)) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "userblock size is not valid"); + } + /* Set value */ + tmpl->userblock_size = size; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cget_userblock + * + * Purpose: Queries the size of a user block in a file creation template. + * + * Return: Success: SUCCEED, size returned through SIZE argument. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cget_userblock(hid_t tid, size_t *size) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cget_userblock, FAIL); + + /* Check args */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + /* Get value */ + if (size) + *size = tmpl->userblock_size; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cset_sizes + * + * Purpose: Sets file size-of addresses and sizes. TEMPLATE + * should be a file creation template. A value of zero causes + * the property to not change. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 6, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_sizes(hid_t tid, size_t sizeof_addr, size_t sizeof_size) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cset_sizeof_addr, FAIL); + + /* Check arguments */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + if (sizeof_addr) { + if (sizeof_addr != 2 && sizeof_addr != 4 && + sizeof_addr != 8 && sizeof_addr != 16) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "file haddr_t size is not valid"); + } + } + if (sizeof_size) { + if (sizeof_size != 2 && sizeof_size != 4 && + sizeof_size != 8 && sizeof_size != 16) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "file size_t size is not valid"); + } + } + /* Set value */ + if (sizeof_addr) + tmpl->sizeof_addr = sizeof_addr; + if (sizeof_size) + tmpl->sizeof_size = sizeof_size; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cget_sizes + * + * Purpose: Returns the size of address and size quantities stored in a + * file according to a file creation template. Either (or even + * both) SIZEOF_ADDR and SIZEOF_SIZE may be null pointers. + * + * Return: Success: SUCCEED, sizes returned through arguments. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cget_sizes(hid_t tid, + size_t *sizeof_addr /*out */ , size_t *sizeof_size /*out */ ) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cget_sizes, FAIL); + + /* Check args */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + /* Get values */ + if (sizeof_addr) + *sizeof_addr = tmpl->sizeof_addr; + if (sizeof_size) + *sizeof_size = tmpl->sizeof_size; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cset_sym_k + * + * Purpose: IK is one half the rank of a tree that stores a symbol + * table for a group. Internal nodes of the symbol table are on + * average 75% full. That is, the average rank of the tree is + * 1.5 times the value of IK. + * + * LK is one half of the number of symbols that can be stored in + * a symbol table node. A symbol table node is the leaf of a + * symbol table tree which is used to store a group. When + * symbols are inserted randomly into a group, the group's + * symbol table nodes are 75% full on average. That is, they + * contain 1.5 times the number of symbols specified by LK. + * + * Either (or even both) of IK and LK can be zero in which case + * that value is left unchanged. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 6, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_sym_k(hid_t tid, int ik, int lk) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cset_sym_k, FAIL); + + /* Check arguments */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + /* Set values */ + if (ik > 0) { + tmpl->btree_k[H5B_SNODE_ID] = ik; + } + if (lk > 0) { + tmpl->sym_leaf_k = lk; + } + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cget_sym_k + * + * Purpose: Retrieves the symbol table B-tree 1/2 rank (IK) and the + * symbol table leaf node 1/2 size (LK). See H5Cset_sym_k() for + * details. Either (or even both) IK and LK may be null + * pointers. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cget_sym_k(hid_t tid, int *ik /*out */ , int *lk /*out */ ) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cget_sym_k, FAIL); + + /* Check arguments */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + /* Get values */ + if (ik) + *ik = tmpl->btree_k[H5B_SNODE_ID]; + if (lk) + *lk = tmpl->sym_leaf_k; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cset_istore_k + * + * Purpose: IK is one half the rank of a tree that stores chunked raw + * data. On average, such a tree will be 75% full, or have an + * average rank of 1.5 times the value of IK. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 6, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_istore_k(hid_t tid, int ik) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cset_istore_k, FAIL); + + /* Check arguments */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + if (ik <= 0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "istore IK value must be positive"); + } + /* Set value */ + tmpl->btree_k[H5B_ISTORE_ID] = ik; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cget_istore_k + * + * Purpose: Queries the 1/2 rank of an indexed storage B-tree. See + * H5Cset_istore_k() for details. The argument IK may be the + * null pointer. + * + * Return: Success: SUCCEED, size returned through IK + * + * Failure: + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cget_istore_k(hid_t tid, int *ik /*out */ ) +{ + H5F_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cget_istore_k, FAIL); + + /* Check arguments */ + if (H5C_FILE_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation template"); + } + /* Get value */ + if (ik) + *ik = tmpl->btree_k[H5B_ISTORE_ID]; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cset_layout + * + * Purpose: Sets the layout of raw data in the file. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 6, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_layout(hid_t tid, H5D_layout_t layout) +{ + H5D_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cset_layout, FAIL); + + /* Check arguments */ + if (H5C_DATASET_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation template"); + } + if (layout < 0 || layout >= H5D_NLAYOUTS) { + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + "raw data layout method is not valid"); + } + /* Set value */ + tmpl->layout = layout; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cget_layout + * + * Purpose: Retrieves layout type of a dataset creation template. + * + * Return: Success: The layout type + * + * Failure: H5D_LAYOUT_ERROR (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5D_layout_t +H5Cget_layout(hid_t tid) +{ + H5D_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cget_layout, H5D_LAYOUT_ERROR); + + /* Check arguments */ + if (H5C_DATASET_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, H5D_LAYOUT_ERROR, + "not a dataset creation template"); + } + FUNC_LEAVE(tmpl->layout); +} + +/*------------------------------------------------------------------------- + * Function: H5Cset_chunk + * + * Purpose: Sets the number of dimensions and the size of each chunk to + * the values specified. The dimensionality of the chunk should + * match the dimensionality of the data space. + * + * As a side effect, the layout method is changed to + * H5D_CHUNKED. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 6, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_chunk(hid_t tid, int ndims, const size_t dim[]) +{ + int i; + H5D_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cset_chunk, FAIL); + + /* Check arguments */ + if (H5C_DATASET_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation template"); + } + if (ndims <= 0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + "chunk dimensionality must be positive"); + } + if (ndims > NELMTS(tmpl->chunk_size)) { + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + "chunk dimensionality is too large"); + } + if (!dim) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "no chunk dimensions specified"); + } + for (i = 0; i < ndims; i++) { + if (dim[i] <= 0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + "all chunk dimensions must be positive"); + } + } + + /* Set value */ + tmpl->layout = H5D_CHUNKED; + tmpl->chunk_ndims = ndims; + for (i = 0; i < ndims; i++) + tmpl->chunk_size[i] = dim[i]; + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5Cget_chunk + * + * Purpose: Retrieves the chunk size of chunked layout. The chunk + * dimensionality is returned and the chunk size in each + * dimension is returned through the DIM argument. At most + * MAX_NDIMS elements of DIM will be initialized. + * + * Return: Success: Positive Chunk dimensionality. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Cget_chunk(hid_t tid, int max_ndims, size_t dim[] /*out */ ) +{ + int i; + H5D_create_t *tmpl = NULL; + + FUNC_ENTER(H5Cget_chunk, FAIL); + + /* Check arguments */ + if (H5C_DATASET_CREATE != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation template"); + } + if (H5D_CHUNKED != tmpl->layout) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "not a chunked storage layout"); + } + for (i = 0; i < tmpl->chunk_ndims && i < max_ndims && dim; i++) { + dim[i] = tmpl->chunk_size[i]; + } + + FUNC_LEAVE(tmpl->chunk_ndims); +} + + +/*------------------------------------------------------------------------- + * Function: H5Cset_stdio + * + * Purpose: Set the low level file driver to use the functions declared + * in the stdio.h file: fopen(), fseek() or fseek64(), fread(), + * fwrite(), and fclose(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 19, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_stdio (hid_t tid) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Cset_stdio, FAIL); + + /* Check arguments */ + if (H5C_FILE_ACCESS != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + + /* Set driver */ + tmpl->driver = H5F_LOW_STDIO; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Cset_sec2 + * + * Purpose: Set the low-level file driver to use the functions declared + * in the unistd.h file: open(), lseek() or lseek64(), read(), + * write(), and close(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 19, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_sec2 (hid_t tid) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Cset_sec2, FAIL); + + /* Check arguments */ + if (H5C_FILE_ACCESS != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + + /* Set driver */ + tmpl->driver = H5F_LOW_SEC2; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Cset_core + * + * Purpose: Set the low-level file driver to use malloc() and free(). + * This driver is restricted to temporary files which are not + * larger than the amount of virtual memory available. The + * INCREMENT argument determines the file block size and memory + * will be allocated in multiples of INCREMENT bytes. A liberal + * INCREMENT results in fewer calls to realloc() and probably + * less memory fragmentation. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 19, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_core (hid_t tid, size_t increment) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Cset_core, FAIL); + + /* Check arguments */ + if (H5C_FILE_ACCESS != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + if (increment<1) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "increment must be positive"); + } + + /* Set driver */ + tmpl->driver = H5F_LOW_CORE; + tmpl->u.core.increment = increment; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Cset_split + * + * Purpose: Set the low-level driver to split meta data from raw data, + * storing meta data in one file and raw data in another file. + * The META_EXT and RAW_EXT are the extension (including the + * `.') which will be appended to the base name to form the name + * for the meta data file and the raw data file. The defaults + * are `.meta' for the meta file and `.raw' for the raw file. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 19, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_split (hid_t tid, const char *meta_ext, hid_t meta_tid, + const char *raw_ext, hid_t raw_tid) +{ + H5F_access_t *tmpl = NULL; + H5F_access_t *meta_tmpl = NULL; + H5F_access_t *raw_tmpl = NULL; + + FUNC_ENTER (H5Cset_split, FAIL); + + /* Check arguments */ + if (H5C_FILE_ACCESS != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + if (H5C_DEFAULT!=meta_tid && + (H5C_FILE_ACCESS != H5Cget_class(meta_tid) || + NULL == (meta_tmpl = H5A_object(meta_tid)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + if (H5C_DEFAULT!=raw_tid && + (H5C_FILE_ACCESS != H5Cget_class(raw_tid) || + NULL == (raw_tmpl = H5A_object(raw_tid)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + + /* Set driver */ + tmpl->driver = H5F_LOW_SPLIT; + tmpl->u.split.meta_ext = H5MM_xstrdup (meta_ext); + tmpl->u.split.meta_access = H5C_copy (H5C_FILE_ACCESS, meta_tmpl); + tmpl->u.split.raw_ext = H5MM_xstrdup (raw_ext); + tmpl->u.split.raw_access = H5C_copy (H5C_FILE_ACCESS, raw_tmpl); + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Cset_family + * + * Purpose: Sets the low-level driver to stripe the hdf5 address space + * across a family of files. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 19, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_family (hid_t tid, hid_t memb_tid) +{ + + H5F_access_t *tmpl = NULL; + H5F_access_t *memb_tmpl = NULL; + + FUNC_ENTER (H5Cset_family, FAIL); + + /* Check arguments */ + if (H5C_FILE_ACCESS != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + if (H5C_DEFAULT!=memb_tid && + (H5C_FILE_ACCESS != H5Cget_class(memb_tid) || + NULL == (memb_tmpl = H5A_object(memb_tid)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + + /* Set driver */ + tmpl->driver = H5F_LOW_FAMILY; + tmpl->u.fam.memb_access = H5C_copy (H5C_FILE_ACCESS, memb_tmpl); + + FUNC_LEAVE (SUCCEED); +} + + + +#ifdef HAVE_PARALLEL +/*------------------------------------------------------------------------- + * Function: H5Cset_mpi + * + * Signature: herr_t H5Cset_mpi(hid_t tid, MPI_Comm comm, MPI_Info info, + * uintn access_mode) + * + * Purpose: Store the access mode for MPIO call and the user supplied + * communicator and info in the access template which can then + * be used to open file. This function is available only in the + * parallel HDF5 library and is not a collective function. + * + * Parameters: + * hid_t tid + * ID of template to modify + * MPI_Comm comm + * MPI communicator to be used for file open as defined in + * MPI_FILE_OPEN of MPI-2. This function does not make a + * duplicated communicator. Any modification to comm after + * this function call returns may have undetermined effect + * to the access template. Users should call this function + * again to setup the template. + * MPI_Info info + * MPI info object to be used for file open as defined in + * MPI_FILE_OPEN of MPI-2. This function does not make a + * duplicated info. Any modification to info after + * this function call returns may have undetermined effect + * to the access template. Users should call this function + * again to setup the template. + * uintn access_mode + * File data access modes: + * H5ACC_INDEPENDENT + * Allow independent datasets access. + * H5ACC_COLLECTIVE + * Allow only collective datasets access. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Albert Cheng + * Feb 3, 1998 + * + * Modifications: + * + * Robb Matzke, 18 Feb 1998 + * Check all arguments before the template is updated so we don't leave + * the template in a bad state if something goes wrong. Also, the + * template data type changed to allow more generality so all the + * mpi-related stuff is in the `u.mpi' member. The `access_mode' will + * contain only mpi-related flags defined in H5Fpublic.h. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Cset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info, uintn access_mode) +{ + H5F_access_t *tmpl = NULL; + MPI_Comm lcomm; + int mrc; /* MPI return code */ + + FUNC_ENTER(H5Cset_mpi, FAIL); + + /* Check arguments */ + if (H5C_FILE_ACCESS != H5Cget_class(tid) || + NULL == (tmpl = H5A_object(tid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access template"); + } + + switch (access_mode){ + case H5ACC_INDEPENDENT: + case H5ACC_COLLECTIVE: + /* okay */ + break; + + default: + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "invalid mpio access mode"); + } + +#ifdef LATER + /* + * Need to verify comm and info contain sensible information. + */ +#endif + + + /* + * Everything looks good. Now go ahead and modify the access template. + */ + tmpl->driver = H5F_LOW_MPIO; + tmpl->u.mpio.access_mode = access_mode; + + /* + * Store a duplicate copy of comm so that user may freely modify comm + * after this call. + */ + if ((mrc = MPI_Comm_dup(comm, &lcomm)) != MPI_SUCCESS) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "failure to duplicate communicator"); + } + tmpl->u.mpio.comm = comm; + +#ifdef LATER + /* Need to duplicate info too but don't know a quick way to do it now */ +#endif + tmpl->u.mpio.info = info; + + FUNC_LEAVE(SUCCEED); +} + +#endif /*HAVE_PARALLEL*/ + +/*-------------------------------------------------------------------------- + NAME + H5Ccopy + PURPOSE + Copy a template + USAGE + hid_t H5C_copy(tid) + hid_t tid; IN: Template object to copy + RETURNS + Returns template ID (atom) on success, FAIL on failure + + ERRORS + ARGS BADRANGE Unknown template class. + ATOM BADATOM Can't unatomize template. + ATOM CANTREGISTER Register the atom for the new template. + INTERNAL UNSUPPORTED Dataset transfer properties are not implemented + yet. + INTERNAL UNSUPPORTED File access properties are not implemented yet. + + DESCRIPTION + This function creates a new copy of a template with all the same parameter + settings. +--------------------------------------------------------------------------*/ +hid_t +H5Ccopy(hid_t tid) +{ + const void *tmpl = NULL; + void *new_tmpl = NULL; + H5C_class_t type; + hid_t ret_value = FAIL; + group_t group; + + FUNC_ENTER(H5Ccopy, FAIL); + + /* Check args */ + if (NULL == (tmpl = H5A_object(tid)) || + (type = H5Cget_class(tid)) < 0 || + (group = H5A_group(tid)) < 0) { + HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, + "can't unatomize template"); + } + + /* Copy it */ + if (NULL==(new_tmpl=H5C_copy (type, tmpl))) { + HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL, + "unable to copy template"); + } + + /* Register the atom for the new template */ + if ((ret_value = H5A_register(group, new_tmpl)) < 0) { + HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to atomize template pointer"); + } + FUNC_LEAVE(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5C_copy + * + * Purpose: Creates a new template and initializes it with some other + * template. Copying a null pointer results in a null pointer. + * + * Return: Success: Ptr to new template + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, February 3, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void * +H5C_copy (H5C_class_t type, const void *src) +{ + size_t size; + void *dst = NULL; + + FUNC_ENTER (H5C_copy, NULL); + + /* How big is the template */ + switch (type) { + case H5C_FILE_CREATE: + size = sizeof(H5F_create_t); + break; + + case H5C_FILE_ACCESS: + size = sizeof(H5F_access_t); + break; + + case H5C_DATASET_CREATE: + size = sizeof(H5D_create_t); + break; + + case H5C_DATASET_XFER: + size = sizeof(H5D_xfer_t); + break; + + default: + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, + "unknown template class"); + } + + /* Create the new template */ + if (src) { + dst = H5MM_xmalloc(size); + HDmemcpy(dst, src, size); + } + + FUNC_LEAVE (dst); +} |