From ce920c6c041c88a64b0553db538842f912ebda8e Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Thu, 11 Apr 2002 17:52:48 -0500 Subject: [svn-r5170] Purpose: New feature Description: Fill-value's behaviors for contiguous dataset have been redefined. Basicly, dataset won't allocate space until it's necessary. Full details are available at http://hdf.ncsa.uiuc.edu/RFC/Fill_Value, at this moment. Platforms tested: Linux 2.2. --- release_docs/RELEASE.txt | 4 + src/H5D.c | 784 +++++++++++++++++++++++++++++++++-------------- src/H5Dprivate.h | 13 +- src/H5Dpublic.h | 33 +- src/H5O.c | 4 +- src/H5Ofill.c | 454 +++++++++++++++++++++++---- src/H5Olayout.c | 27 +- src/H5Oprivate.h | 32 +- src/H5P.c | 326 ++++++++++++++++++-- src/H5Pprivate.h | 2 + src/H5Ppublic.h | 8 + src/H5Sall.c | 2 +- src/H5Shyper.c | 6 +- src/H5Spkg.h | 6 +- src/H5Spoint.c | 2 +- src/H5Sprivate.h | 8 +- src/H5Sselect.c | 2 +- 17 files changed, 1373 insertions(+), 340 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 1cce91e..c684286 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -156,6 +156,10 @@ Documentation New Features ============ + * Fill-value's behaviors for contiguous dataset have been redefined. + Basicly, dataset won't allocate space until it's necessary. Full details + are available at http://hdf.ncsa.uiuc.edu/RFC/Fill_Value, at this moment. + SLU - 2002/04/11 * Added new routine "H5Dfill" to fill a selection with a particular value in memory. QAK - 2002/04/09 * A new query function H5Tget_member_index has been added for compound diff --git a/src/H5D.c b/src/H5D.c index c2980ae..63e6e06 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -52,12 +52,15 @@ struct H5D_t { H5O_layout_t layout; /*data layout */ }; -/* Interface initialization? */ + static int interface_initialize_g = 0; #define INTERFACE_INIT H5D_init_interface static herr_t H5D_init_interface(void); static herr_t H5D_init_storage(H5D_t *dataset, const H5S_t *space); H5D_t * H5D_new(hid_t dcpl_id); +static herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, + const H5T_t *buf_type, const H5S_t *space); +static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation); /* Declare a free list to manage the H5D_t struct */ H5FL_DEFINE_STATIC(H5D_t); @@ -173,6 +176,8 @@ H5D_init_interface(void) int chunk_ndims = H5D_CRT_CHUNK_DIM_DEF; hsize_t chunk_size[32] = H5D_CRT_CHUNK_SIZE_DEF; H5O_fill_t fill = H5D_CRT_FILL_VALUE_DEF; + H5D_space_time_t space_time = H5D_CRT_SPACE_TIME_DEF; + H5D_fill_time_t fill_time = H5D_CRT_FILL_TIME_DEF; H5O_efl_t efl = H5D_CRT_EXT_FILE_LIST_DEF; H5O_pline_t pline = H5D_CRT_DATA_PIPELINE_DEF; @@ -300,7 +305,15 @@ H5D_init_interface(void) /* Register the fill value property */ if(H5P_register(crt_pclass, H5D_CRT_FILL_VALUE_NAME, H5D_CRT_FILL_VALUE_SIZE, &fill, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); - + + /* Register the space allocation time property */ + if(H5P_register(crt_pclass, H5D_CRT_SPACE_TIME_NAME, H5D_CRT_SPACE_TIME_SIZE, &space_time, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); + + /* Register the fill value writing time property */ + if(H5P_register(crt_pclass, H5D_CRT_FILL_TIME_NAME, H5D_CRT_FILL_TIME_SIZE, &fill_time, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); + /* Register the external file list property */ if(H5P_register(crt_pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &efl, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); @@ -407,8 +420,13 @@ H5D_crt_copy(hid_t new_plist_id, hid_t old_plist_id, void UNUSED *copy_data) /* Make copies of fill value, external file list, and data pipeline */ HDmemset(&dst_fill,0,sizeof(H5O_fill_t)); - if(NULL==H5O_copy(H5O_FILL, &src_fill, &dst_fill)) + if(src_fill.buf && (NULL==H5O_copy(H5O_FILL, &src_fill, &dst_fill))) { HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy fill value"); + } + else if (!src_fill.buf) { + dst_fill.type = dst_fill.buf = NULL; + dst_fill.size = src_fill.size; + } HDmemset(&dst_efl,0,sizeof(H5O_efl_t)); if(NULL==H5O_copy(H5O_EFL, &src_efl, &dst_efl)) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy external file list"); @@ -905,6 +923,107 @@ H5D_get_space(H5D_t *dset) /*------------------------------------------------------------------------- + * Function: H5Dget_space_status + * + * Purpose: Returns the status of data space allocation. + * + * Return: + * Success: Non-negative + * + * Failture: Negative + * + * Programmer: Raymond Lu + * + * Modification: + * + *------------------------------------------------------------------------- + */ +herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation) +{ + H5D_t *dset = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER(H5Dget_space_status, FAIL); + + /* Check arguments */ + if(H5I_DATASET != H5I_get_type(dset_id) || NULL==(dset=H5I_object(dset_id))) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset"); + + /* Read data space address and return */ + if(FAIL==(ret_value=H5D_get_space_status(dset, allocation))) + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get space status"); + +done: + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5D_get_space_status + * + * Purpose: Returns the status of data space allocation. + * + * Return: + * Success: Non-negative + * + * Failture: Negative + * + * Programmer: Raymond Lu + * + * Modification: + * + *------------------------------------------------------------------------- + */ +static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation) +{ + H5S_t *space=NULL; /* Dataset's dataspace */ + hsize_t space_allocated; /* The number of bytes allocated for chunks */ + hssize_t total_elem; /* The total number of elements in dataspace */ + size_t type_size; /* The size of the datatype for the dataset */ + hsize_t full_size; /* The number of bytes in the dataset when fully populated */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER(H5D_get_space_status, FAIL); + + /* Get the dataset's dataspace */ + if((space=H5D_get_space(dset))==NULL) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get dataspace"); + + /* Get the total number of elements in dataset's dataspace */ + if((total_elem=H5S_get_simple_extent_npoints(space))<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get # of dataspace elements"); + + /* Get the size of the dataset's datatype */ + if((type_size=H5T_get_size(dset->type))==0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get size of datatype"); + + /* Compute the maximum size of the dataset in bytes */ + H5_CHECK_OVERFLOW(total_elem,hssize_t,hsize_t); + full_size=((hsize_t)total_elem)*type_size; + + /* Difficult to error check, since the error value is 0 and 0 is a valid value... :-/ */ + space_allocated=H5D_get_storage_size(dset); + + /* Decide on how much of the space is allocated */ + if(space_allocated==0) + *allocation = H5D_SPACE_STATUS_NOT_ALLOCATED; + else if(space_allocated==full_size) + *allocation = H5D_SPACE_STATUS_ALLOCATED; + else { + /* Should only happen for chunked datasets currently */ + assert(dset->layout.type==H5D_CHUNKED); + + *allocation = H5D_SPACE_STATUS_PART_ALLOCATED; + } /* end else */ + +done: + if(space) + H5S_close(space); + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5Dget_type * * Purpose: Returns a copy of the file data type for a dataset. @@ -998,8 +1117,8 @@ H5Dget_create_plist(hid_t dset_id) { H5D_t *dset = NULL; H5O_fill_t copied_fill={NULL,0,NULL}; - H5P_genplist_t *dcpl_plist; - H5P_genplist_t *new_plist; + H5P_genplist_t *dcpl_plist; + H5P_genplist_t *new_plist; hid_t ret_value = FAIL; FUNC_ENTER (H5Dget_create_plist, FAIL); @@ -1379,6 +1498,11 @@ done: * Changed the way to retrieve and set property for generic property * list. * + * Raymond Lu, 26 Feb 2002 + * A new fill value message is added. Two properties, space allocation + * time and fill value writing time, govern space allocation and fill + * value writing. + * *------------------------------------------------------------------------- */ H5D_t * @@ -1396,9 +1520,13 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, H5D_layout_t dcpl_layout; int chunk_ndims = 0; hsize_t chunk_size[32]={0}; - H5O_fill_t fill={NULL,0,NULL}; - H5P_genplist_t *plist; /* Property list */ - H5P_genplist_t *new_plist; /* New Property list */ + H5D_space_time_t space_time; + H5D_fill_time_t fill_time; + H5O_fill_t fill_prop={NULL,0,NULL}; + H5O_fill_new_t fill={NULL, 0, NULL, H5D_SPACE_ALLOC_LATE, H5D_FILL_TIME_ALLOC, TRUE}; + H5D_fill_value_t fill_status; + H5P_genplist_t *plist; /* Property list */ + H5P_genplist_t *new_plist; /* New Property list */ FUNC_ENTER(H5D_create, NULL); @@ -1528,14 +1656,49 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, if (H5O_create(f, 256, &(new_dset->ent)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset object header"); - /* Convert the fill value to the dataset type and write the message */ - if(H5P_get(new_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve fill value"); - if (H5O_fill_convert(&fill, new_dset->type) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to convert fill value to dataset type"); - if (fill.buf && H5O_modify(&(new_dset->ent), H5O_FILL, 0, H5O_FLAG_CONSTANT, &fill) < 0) + /* Retrieve properties of fill value and others. Copy them into new fill + * value struct. Convert the fill value to the dataset type and write + * the message */ + if(H5P_get(new_plist, H5D_CRT_SPACE_TIME_NAME, &space_time) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time"); + if(H5P_get(new_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve fill time"); + if(H5P_fill_value_defined(new_plist, &fill_status)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't tell if fill value defined"); + if(fill_status== H5D_FILL_VALUE_DEFAULT || fill_status==H5D_FILL_VALUE_USER_DEFINED) { + if(H5P_get(new_plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve fill value"); + if(NULL==H5O_copy(H5O_FILL, &fill_prop, &fill)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,NULL, "unable to copy fill value"); + if (fill_prop.buf && fill_prop.size>0 && H5O_fill_convert(&fill, new_dset->type) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to convert fill value to dataset type"); + fill.fill_defined = TRUE; + } else if(fill_status==H5D_FILL_VALUE_UNDEFINED) { + fill.size = -1; + fill.type = fill.buf = NULL; + fill.fill_defined = FALSE; + } else { + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to determine if fill value is defined"); + } /* end else */ + fill.space_time = space_time; + fill.fill_time = fill_time; + + if(fill.fill_defined == FALSE && fill_time != H5D_FILL_TIME_NEVER) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,NULL, "unable to create dataset"); + /* Write new fill value message */ + if (H5O_modify(&(new_dset->ent), H5O_FILL_NEW, 0, H5O_FLAG_CONSTANT, + &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update fill value header message"); - if(H5P_set(new_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) + + H5O_reset(H5O_FILL, &fill_prop); + if(fill.buf && (NULL==H5O_copy(H5O_FILL, &fill, &fill_prop))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,NULL,"unable to copy fill value"); + /* Write old fill value */ + if (fill_prop.buf && H5O_modify(&(new_dset->ent), H5O_FILL, 0, + H5O_FLAG_CONSTANT, &fill_prop) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, + "unable to update fill value header message"); + if(H5P_set(new_plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set fill value"); /* Update the type and space header messages */ @@ -1563,16 +1726,34 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, /* * Initialize storage. We assume that external storage is already * initialized by the caller, or at least will be before I/O is performed. + * For parallelization, space is always allocated now except using + * external storage. For contiguous layout, space is allocated now if + * space allocate time is early; otherwise delay allocation until H5Dwrite. */ +#ifdef H5_HAVE_PARALLEL + if (0==efl.nused && H5F_arr_create(f, &(new_dset->layout))<0) { + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, + "unable to initialize storage"); + } else if(0layout.addr = HADDR_UNDEF; + } +#else if (0==efl.nused) { - if (H5F_arr_create(f, &(new_dset->layout)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage"); + if(dcpl_layout==H5D_CHUNKED || (dcpl_layout==H5D_CONTIGUOUS && + space_time==H5D_SPACE_ALLOC_EARLY)) { + if (H5F_arr_create(f, &(new_dset->layout))<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage"); + } /* end if */ + else + new_dset->layout.addr = HADDR_UNDEF; + } else { new_dset->layout.addr = HADDR_UNDEF; } +#endif /* Update layout message */ - if (H5O_modify (&(new_dset->ent), H5O_LAYOUT, 0, H5O_FLAG_CONSTANT, &(new_dset->layout)) < 0) + if (H5O_modify (&(new_dset->ent), H5O_LAYOUT, 0, 0, &(new_dset->layout))<0) HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to update layout message"); /* Update external storage message */ @@ -1596,9 +1777,22 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to update external file list message"); } /* end if */ - /* Initialize the raw data */ + /* Initialize the raw data when it's + * 1. Parallel I/O + * 2. layout is contiguous, space allocation time is early, fill value + * writing time is upon allocation + * 3. external space is treated the same as internal except it's always + * assumed as early for space allocation time. */ +#ifdef H5_HAVE_PARALLEL if (H5D_init_storage(new_dset, space)<0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage"); + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage"); +#else + if(dcpl_layout==H5D_CHUNKED || (dcpl_layout==H5D_CONTIGUOUS && + fill_time==H5D_FILL_TIME_ALLOC && ((space_time==H5D_SPACE_ALLOC_EARLY && !efl.nused) || + (efl.nused)))) + if (H5D_init_storage(new_dset, space)<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage"); +#endif /* Success */ ret_value = new_dset; @@ -1736,6 +1930,10 @@ done: * Tuesday, October 2, 2001 * Changed the way to set property for generic property list. * + * Raymond Lu + * Feb 26, 2002 + * A new fill value message and two new properties are added. + * *------------------------------------------------------------------------- */ H5D_t * @@ -1744,10 +1942,11 @@ H5D_open_oid(H5G_entry_t *ent) H5D_t *dataset = NULL; /*new dataset struct */ H5D_t *ret_value = NULL; /*return value */ H5S_t *space = NULL; /*data space */ - H5O_fill_t fill; - H5O_pline_t pline; - H5O_efl_t efl; - H5D_layout_t layout; + H5O_fill_new_t fill = {NULL, 0, NULL, H5D_SPACE_ALLOC_LATE, H5D_FILL_TIME_ALLOC, TRUE}; + H5O_fill_t fill_prop = {NULL, 0, NULL}; + H5O_pline_t pline; /* I/O pipeline information */ + H5O_efl_t efl; /* External file information */ + H5D_layout_t layout; /* Dataset layout */ int chunk_ndims; H5P_genplist_t *plist; /* Property list */ @@ -1777,14 +1976,38 @@ H5D_open_oid(H5G_entry_t *ent) if (NULL == (plist = H5I_object(dataset->dcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list"); - /* Get the optional fill value message */ - HDmemset(&fill,0,sizeof(H5O_fill_t)); - if(NULL == H5O_read(&(dataset->ent), H5O_FILL, 0, &fill)) { + /* Retrieve & release the previous fill-value settings */ + if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't get fill value"); + H5O_reset(H5O_FILL, &fill_prop); + + /* Get the new fill value message */ + if(NULL == H5O_read(&(dataset->ent), H5O_FILL_NEW, 0, &fill)) { H5E_clear(); HDmemset(&fill, 0, sizeof(fill)); } - - if(H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) + if(fill.fill_defined) { + if(NULL==H5O_copy(H5O_FILL, &fill, &fill_prop)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't copy fill value"); + } else { + /* For compatibility with v1.4. Retrieve the old fill value message. + * If size is 0, make it -1 for undefined. */ + if(NULL == H5O_read(&(dataset->ent), H5O_FILL, 0, &fill_prop)) { + H5E_clear(); + HDmemset(&fill_prop, 0, sizeof(fill_prop)); + } + if(fill_prop.size == 0) { + fill_prop.type = fill_prop.buf = NULL; + fill_prop.size = (size_t)-1; + } + } /* end else */ + + /* Set fill value properties */ + if(H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value"); + if(H5P_set(plist, H5D_CRT_SPACE_TIME_NAME, &fill.space_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value"); + if(H5P_set(plist, H5D_CRT_FILL_TIME_NAME, &fill.fill_time) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value"); /* Get the optional filters message */ @@ -1837,13 +2060,13 @@ H5D_open_oid(H5G_entry_t *ent) HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet"); } /* end switch */ - /* Get the external file list message, which might not exist */ - if( !H5F_addr_defined(dataset->layout.addr) ) { + /* Get the external file list message, which might not exist. Space is + * also undefined when space allocate time is H5D_SPACE_ALLOC_LATE. */ + if( !H5F_addr_defined(dataset->layout.addr)) { HDmemset(&efl,0,sizeof(H5O_efl_t)); - if(NULL == H5O_read(&(dataset->ent), H5O_EFL, 0, &efl)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "storage address is undefined and no external file list"); - if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set external file list"); + if(NULL != H5O_read(&(dataset->ent), H5O_EFL, 0, &efl)) + if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set external file list"); } /* * Make sure all storage is properly initialized for chunked datasets. @@ -1967,6 +2190,11 @@ H5D_close(H5D_t *dataset) * Raymond Lu, 2001-10-2 * Changed the way to retrieve property for generic property list. * + * Raymond Lu, 2002-2-26 + * For the new fill value design, data space can either be allocated + * or not allocated at this stage. Fill value or data from space is + * returned to outgoing buffer. + * * QAK - 2002/04/02 * Removed the must_convert parameter and move preconditions to * H5S__opt_possible() routine @@ -1977,37 +2205,39 @@ herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, const H5S_t *file_space, hid_t dxpl_id, void *buf/*out*/) { - hssize_t nelmts; /*number of elements */ - hsize_t smine_start; /*strip mine start loc */ - hsize_t n, smine_nelmts; /*elements per strip */ - uint8_t *tconv_buf = NULL; /*data type conv buffer */ - uint8_t *bkg_buf = NULL; /*background buffer */ + hssize_t nelmts; /*number of elements */ + hsize_t smine_start; /*strip mine start loc */ + hsize_t n, smine_nelmts; /*elements per strip */ + uint8_t *tconv_buf = NULL; /*data type conv buffer */ + uint8_t *bkg_buf = NULL; /*background buffer */ H5T_path_t *tpath = NULL; /*type conversion info */ - hid_t src_id = -1, dst_id = -1;/*temporary type atoms */ - H5S_conv_t *sconv=NULL; /*space conversion funcs*/ - H5S_sel_iter_t mem_iter; /*mem selection iteration info*/ - H5S_sel_iter_t bkg_iter; /*background iteration info*/ - H5S_sel_iter_t file_iter; /*file selection iter info*/ - herr_t ret_value = SUCCEED; /*return value */ - herr_t status; /*function return status*/ - size_t src_type_size; /*size of source type */ - size_t dst_type_size; /*size of destination type*/ - size_t target_size; /*desired buffer size */ - hsize_t request_nelmts; /*requested strip mine */ - H5T_bkg_t need_bkg; /*type of background buf*/ - H5S_t *free_this_space=NULL; /*data space to free */ + hid_t src_id = -1, dst_id = -1;/*temporary type atoms */ + H5S_conv_t *sconv=NULL; /*space conversion funcs*/ + H5S_sel_iter_t mem_iter; /*mem selection iteration info*/ + H5S_sel_iter_t bkg_iter; /*background iteration info*/ + H5S_sel_iter_t file_iter; /*file selection iter info*/ + herr_t ret_value = SUCCEED; /*return value */ + herr_t status=SUCCEED; /*function return status*/ + size_t src_type_size; /*size of source type */ + size_t dst_type_size; /*size of destination type*/ + size_t target_size; /*desired buffer size */ + hsize_t request_nelmts; /*requested strip mine */ + H5T_bkg_t need_bkg; /*type of background buf*/ + H5S_t *free_this_space=NULL; /*data space to free */ #ifdef H5_HAVE_PARALLEL - H5FD_mpio_dxpl_t *dx = NULL; - H5FD_mpio_xfer_t xfer_mode; /*xfer_mode for this request */ - hbool_t xfer_mode_changed=0; /*xfer_mode needs restore */ - hbool_t doing_mpio=0; /*This is an MPIO access */ + H5FD_mpio_dxpl_t *dx = NULL; + H5FD_mpio_xfer_t xfer_mode; /*xfer_mode for this request */ + hbool_t xfer_mode_changed=0; /*xfer_mode needs restore */ + hbool_t doing_mpio=0; /*This is an MPIO access */ #endif #ifdef H5S_DEBUG - H5_timer_t timer; + H5_timer_t timer; #endif - H5O_pline_t pline; - H5O_efl_t efl; - H5O_fill_t fill; + H5O_pline_t pline; /* I/O pipeline struct */ + H5O_efl_t efl; /* External File List info */ + H5O_fill_t fill; /* Fill value information */ + H5D_fill_time_t fill_time; /* When to write the fill values */ + H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */ H5P_genplist_t *dx_plist=NULL; /* Property list */ H5P_genplist_t *dc_plist; /* Property list */ unsigned sconv_flags=0; /* Flags for the space conversion */ @@ -2074,6 +2304,39 @@ printf("%s: check 1.0, nelmts=%d, H5S_get_select_npoints(file_space)=%d\n",FUNC, if (nelmts!=H5S_get_select_npoints (file_space)) HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes"); + /* Retrieve dataset properties */ + if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve data pipeline"); + if(H5P_fill_value_defined(dc_plist, &fill_status)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't tell if fill value defined"); + if((fill_status==H5D_FILL_VALUE_DEFAULT || fill_status==H5D_FILL_VALUE_USER_DEFINED) && H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill value"); + if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list"); + + /* If space hasn't been allocated and not using external storage, + * return fill value to buffer if fill time is upon allocation, or + * do nothing if fill time is never. */ + if(nelmts > 0 && efl.nused==0 && dataset->layout.type==H5D_CONTIGUOUS + && dataset->layout.addr==HADDR_UNDEF) { + + /* Should be impossible, but check anyway... */ + if(fill_status == H5D_FILL_VALUE_UNDEFINED && fill_time == H5D_FILL_TIME_ALLOC) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "read failed: dataset doesn't exist, no data can be read"); + + /* If we're never going to fill this dataset, just leave the junk in the user's buffer */ + if(fill_time == H5D_FILL_TIME_NEVER) + HGOTO_DONE(SUCCEED); + + /* Go fill the user's selection with the dataset's fill value */ + if(H5D_fill(fill.buf,fill.type,buf,mem_type,mem_space)<0) { + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed"); + } else + HGOTO_DONE(SUCCEED); + } /* end if */ + /* * Locate the type conversion function and data space conversion * functions, and set up the element numbering information. If a data @@ -2115,6 +2378,7 @@ printf("%s: check 1.0, nelmts=%d, H5S_get_select_npoints(file_space)=%d\n",FUNC, #ifdef QAK printf("%s: check 1.1, \n",FUNC); #endif /* QAK */ + /* * If there is no type conversion then try reading directly into the * application's buffer. This saves at least one mem-to-mem copy. @@ -2123,36 +2387,22 @@ printf("%s: check 1.1, \n",FUNC); #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get pipeline"); - if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve fill value"); - if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get external file list"); - status = (sconv->read)(dataset->ent.file, &(dataset->layout), &pline, - &fill, &efl, H5T_get_size(dataset->type), file_space, - mem_space, dxpl_id, buf/*out*/); + /* Sanity check dataset, then read it */ + assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused>0); + status = (sconv->read)(dataset->ent.file, &(dataset->layout), + &pline, &fill, &efl, H5T_get_size(dataset->type), + file_space, mem_space, dxpl_id, buf/*out*/); +#ifdef H5S_DEBUG + H5_timer_end(&(sconv->stats[1].read_timer), &timer); + sconv->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->type); + sconv->stats[1].read_ncalls++; +#endif - /* Supports only no conversion, type or space, for now. */ + /* Check return value from optimized read */ if (status<0) { HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed"); - } else { - /* direct xfer accomplished successfully */ -#ifdef H5S_DEBUG - H5_timer_end(&(sconv->stats[1].read_timer), &timer); - sconv->stats[1].read_nbytes += nelmts * - H5T_get_size(dataset->type); - sconv->stats[1].read_ncalls++; -#endif + } else HGOTO_DONE(SUCCEED); - } /* end else */ -#ifdef H5D_DEBUG - if (H5DEBUG(D)) { - fprintf (H5DEBUG(D), "H5D: data space conversion could not be " - "optimized for this case (using general method instead)\n"); - } /* end if */ -#endif - H5E_clear (); } /* end if */ #ifdef QAK @@ -2246,14 +2496,6 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d, min_e printf("%s: check 4.0, nelmts=%d, need_bkg=%d\n", FUNC,(int)nelmts,(int)need_bkg); #endif - /* Get some necessary information for later */ - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve data pipeline"); - if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve fill value"); - if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list"); - /* Start strip mining... */ H5_CHECK_OVERFLOW(nelmts,hssize_t,hsize_t); for (smine_start=0; smine_start<(hsize_t)nelmts; smine_start+=smine_nelmts) { @@ -2272,11 +2514,11 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d, min_e #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - n = (sconv->f->gath)(dataset->ent.file, &(dataset->layout), &pline, - &fill, &efl, src_type_size, file_space, - &file_iter, smine_nelmts, dxpl_id, - tconv_buf/*out*/); - + /* Sanity check that space is allocated, then read data from it */ + assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused > 0); + n = (sconv->f->gath)(dataset->ent.file, &(dataset->layout), + &pline, &fill, &efl, src_type_size, file_space, + &file_iter, smine_nelmts, dxpl_id, tconv_buf/*out*/); #ifdef H5S_DEBUG H5_timer_end(&(sconv->stats[1].gath_timer), &timer); @@ -2439,6 +2681,11 @@ done: * Raymond Lu, 2001-10-2 * Changed the way to retrieve property for generic property list. * + * Raymond Lu, 2002-2-26 + * For the new fill value design, space may not be allocated until + * this function is called. Allocate and initialize space if it + * hasn't been. + * * QAK - 2002/04/02 * Removed the must_convert parameter and move preconditions to * H5S__opt_possible() routine @@ -2449,40 +2696,41 @@ herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, const H5S_t *file_space, hid_t dxpl_id, const void *buf) { - hssize_t nelmts; /*total number of elmts */ - hsize_t smine_start; /*strip mine start loc */ - hsize_t n, smine_nelmts; /*elements per strip */ - uint8_t *tconv_buf = NULL; /*data type conv buffer */ - uint8_t *bkg_buf = NULL; /*background buffer */ + hssize_t nelmts; /*total number of elmts */ + hsize_t smine_start; /*strip mine start loc */ + hsize_t n, smine_nelmts; /*elements per strip */ + uint8_t *tconv_buf = NULL; /*data type conv buffer */ + uint8_t *bkg_buf = NULL; /*background buffer */ H5T_path_t *tpath = NULL; /*type conversion info */ - hid_t src_id = -1, dst_id = -1;/*temporary type atoms */ + hid_t src_id = -1, dst_id = -1;/*temporary type atoms */ H5S_conv_t *sconv=NULL; /*space conversion funcs*/ - H5S_sel_iter_t mem_iter; /*memory selection iteration info*/ - H5S_sel_iter_t bkg_iter; /*background iteration info*/ - H5S_sel_iter_t file_iter; /*file selection iteration info*/ - herr_t ret_value = SUCCEED; /*return value */ - herr_t status; /*function return status*/ - size_t src_type_size; /*size of source type */ - size_t dst_type_size; /*size of destination type*/ - size_t target_size; /*desired buffer size */ - hsize_t request_nelmts; /*requested strip mine */ - H5T_bkg_t need_bkg; /*type of background buf*/ - H5S_t *free_this_space=NULL; /*data space to free */ + H5S_sel_iter_t mem_iter; /*memory selection iteration info*/ + H5S_sel_iter_t bkg_iter; /*background iteration info*/ + H5S_sel_iter_t file_iter; /*file selection iteration info*/ + herr_t ret_value = SUCCEED; /*return value */ + herr_t status; /*function return status*/ + size_t src_type_size; /*size of source type */ + size_t dst_type_size; /*size of destination type*/ + size_t target_size; /*desired buffer size */ + hsize_t request_nelmts; /*requested strip mine */ + H5T_bkg_t need_bkg; /*type of background buf*/ + H5S_t *free_this_space=NULL; /*data space to free */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_dxpl_t *dx = NULL; - H5FD_mpio_xfer_t xfer_mode; /*xfer_mode for this request */ - hbool_t xfer_mode_changed=0; /*xfer_mode needs restore */ - hbool_t doing_mpio=0; /*This is an MPIO access */ + H5FD_mpio_xfer_t xfer_mode; /*xfer_mode for this request */ + hbool_t xfer_mode_changed=0; /*xfer_mode needs restore */ + hbool_t doing_mpio=0; /*This is an MPIO access */ #endif #ifdef H5S_DEBUG - H5_timer_t timer; + H5_timer_t timer; #endif - H5O_pline_t pline; - H5O_efl_t efl; - H5O_fill_t fill; - H5P_genplist_t *dx_plist=NULL; /* Property list */ - H5P_genplist_t *dc_plist; /* Property list */ - unsigned sconv_flags=0; /* Flags for the space conversion */ + H5O_pline_t pline; /* I/O Pipeline info */ + H5O_efl_t efl; /* External file list info */ + H5O_fill_t fill; /* Fill value info */ + H5D_fill_time_t fill_time; + H5P_genplist_t *dx_plist=NULL; /* Data transfer property list */ + H5P_genplist_t *dc_plist; /* Dataset creation roperty list */ + unsigned sconv_flags=0; /* Flags for the space conversion */ FUNC_ENTER(H5D_write, FAIL); @@ -2570,6 +2818,37 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (nelmts!=H5S_get_select_npoints (file_space)) HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes"); + /* Retrieve properties. Allocate space and initialize the space with + * fill value if it has been done so. Remember, if H5D_write fails, + * need to deallocate space(?). */ + if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline"); + if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve fill time"); + if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get external file list"); + + /* Allocate data space and initialize it if it hasn't been. Also modify + * header message for layout(this is only for forward compatibility). */ + if(nelmts > 0 && efl.nused==0 && dataset->layout.type==H5D_CONTIGUOUS && + dataset->layout.addr==HADDR_UNDEF) { + /* Allocate storage */ + if(H5F_arr_create(dataset->ent.file, &(dataset->layout))<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage"); + + /* Initialize raw data */ + if(fill_time==H5D_FILL_TIME_ALLOC) + if(H5D_init_storage(dataset, file_space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value"); + + /* Update layout message */ + if (H5O_modify (&(dataset->ent), H5O_LAYOUT, 0, H5O_FLAG_CONSTANT, + &(dataset->layout)) < 0) + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message"); + } /* end if */ + /* * Locate the type conversion function and data space conversion * functions, and set up the element numbering information. If a data @@ -2618,16 +2897,12 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, #ifdef QAK printf("%s: check 0.7, H5T_IS_NOOP(path)=%d, sconv->write=%p\n", FUNC, (int)H5T_IS_NOOP(tpath), sconv->write); #endif /* QAK */ + if (H5T_IS_NOOP(tpath) && sconv->write) { + #ifdef H5S_DEBUG H5_timer_begin(&timer); #endif - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get pipeline"); - if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve fill value"); - if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get external file list"); status = (sconv->write)(dataset->ent.file, &(dataset->layout), &pline, &fill, &efl, H5T_get_size(dataset->type), file_space, mem_space, dxpl_id, buf/*out*/); @@ -2734,14 +3009,6 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d\n",FUN printf("%s: check 4.0, nelmts=%d, request_nelmts=%d, need_bkg=%d\n", FUNC,(int)nelmts,(int)request_nelmts,(int)need_bkg); #endif - /* Get some necessary information for later */ - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline"); - if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); - if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get external file list"); - /* Start strip mining... */ H5_CHECK_OVERFLOW(nelmts,hssize_t,hsize_t); for (smine_start=0; smine_start<(hsize_t)nelmts; smine_start+=smine_nelmts) { @@ -2888,6 +3155,7 @@ done: H5FL_BLK_FREE(bkgr_conv,bkg_buf); if (free_this_space) H5S_close(free_this_space); + FUNC_LEAVE(ret_value); } @@ -3106,15 +3374,14 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space) switch (dset->layout.type) { case H5D_CONTIGUOUS: /* - * If the fill value is set then write it to the specified selection - * even if it is all zero. This allows the application to force - * filling when the underlying storage isn't initialized to zero. + * If the fill value is set then write it to the entire extent + * of the dataset. */ snpoints = H5S_get_simple_extent_npoints(space); assert(snpoints>=0); H5_ASSIGN_OVERFLOW(npoints,snpoints,hssize_t,size_t); - if (fill.buf && npoints==(size_t)H5S_get_select_npoints(space)) { + if (fill.buf) { /* * Fill the entire current extent with the fill value. We can do * this quite efficiently by making sure we copy the fill value @@ -3147,12 +3414,7 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space) npoints -= MIN(ptsperbuf, npoints); addr += size; } /* end while */ - } else if(fill.buf) { - /* - * Fill the specified selection with the fill value. - */ - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to initialize dataset with fill value"); - } + } /* end if */ break; case H5D_CHUNKED: @@ -3246,21 +3508,28 @@ H5Dget_storage_size(hid_t dset_id) hsize_t H5D_get_storage_size(H5D_t *dset) { - hsize_t size; - unsigned u; + unsigned u; /* Index variable */ + hsize_t ret_value=0; FUNC_ENTER(H5D_get_storage_size, 0); if (H5D_CHUNKED==dset->layout.type) { - size = H5F_istore_allocated(dset->ent.file, dset->layout.ndims, + ret_value = H5F_istore_allocated(dset->ent.file, dset->layout.ndims, dset->layout.addr); } else { - for (u=0, size=1; ulayout.ndims; u++) { - size *= dset->layout.dim[u]; - } - } + /* Sanity Check */ + assert(dset->layout.type==H5D_CONTIGUOUS); + + /* Datasets which are not allocated yet are using no space on disk */ + if(dset->layout.addr == HADDR_UNDEF) + ret_value=0; + else { + for (u=0, ret_value=1; ulayout.ndims; u++) + ret_value *= dset->layout.dim[u]; + } /* end else */ + } /* end else */ - FUNC_LEAVE(size); + FUNC_LEAVE(ret_value); } @@ -3597,16 +3866,16 @@ done: /*-------------------------------------------------------------------------- NAME - H5Dfill + H5D_fill PURPOSE - Fill a selection in memory with a value + Fill a selection in memory with a value (internal version) USAGE - herr_t H5Dfill(fill, fill_type, space, buf, buf_type) + herr_t H5Dfill(fill, fill_type, buf, buf_type, space) const void *fill; IN: Pointer to fill value to use - hid_t fill_type_id; IN: Datatype of the fill value + H5T_t *fill_type; IN: Datatype of the fill value void *buf; IN/OUT: Memory buffer to fill selection within - hid_t buf_type_id; IN: Datatype of the elements in buffer - hid_t space_id; IN: Dataspace describing memory buffer & + H5T_t *buf_type; IN: Datatype of the elements in buffer + H5S_t *space; IN: Dataspace describing memory buffer & containing selection to use. RETURNS Non-negative on success/Negative on failure. @@ -3614,37 +3883,33 @@ done: Use the selection in the dataspace to fill elements in a memory buffer. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + If "fill" parameter is NULL, use all zeros as fill value. If "fill_type" + parameter is NULL, use "buf_type" for the fill value datatype. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id) +static herr_t +H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, const H5S_t *space) { - H5S_t *space; /* Dataspace */ - H5T_t *fill_type; /* Fill-value datatype */ - H5T_t *buf_type; /* Buffer datatype */ H5T_path_t *tpath = NULL; /* Conversion information*/ uint8_t *tconv_buf = NULL; /* Data type conv buffer */ uint8_t *bkg_buf = NULL; /* Temp conversion buffer */ + hid_t src_id = -1, dst_id = -1; /* Temporary type IDs */ size_t src_type_size; /* Size of source type */ size_t dst_type_size; /* Size of destination type*/ size_t buf_size; /* Desired buffer size */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER (H5Dfill, FAIL); - H5TRACE5("e","xixii",fill,fill_type_id,buf,buf_type_id,space_id); + FUNC_ENTER (H5D_fill, FAIL); /* Check args */ - if (fill==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fill value"); - if (buf==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer"); - if (H5I_DATASPACE != H5I_get_type(space_id) || NULL == (space=H5I_object(space_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataspace"); - if (H5I_DATATYPE != H5I_get_type(fill_type_id) || NULL == (fill_type=H5I_object(fill_type_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); - if (H5I_DATATYPE != H5I_get_type(buf_type_id) || NULL == (buf_type=H5I_object(buf_type_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + assert(buf); + assert(buf_type); + assert(space); + + /* Check for "default" fill value */ + if(fill_type==NULL) + fill_type=buf_type; /* Get the memory and file datatype sizes */ src_type_size = H5T_get_size(fill_type); @@ -3656,15 +3921,23 @@ H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); /* Copy the user's data into the buffer for conversion */ - HDmemcpy(tconv_buf,fill,src_type_size); + if(fill==NULL) + HDmemset(tconv_buf,0,src_type_size); + else + HDmemcpy(tconv_buf,fill,src_type_size); /* Convert memory buffer into disk buffer */ /* Set up type conversion function */ - if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL))) + if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL))) { HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types"); + } else if (!H5T_IS_NOOP(tpath)) { + if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL)))<0 || + (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL)))<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion"); + } /* Perform data type conversion */ - if (H5T_convert(tpath, fill_type_id, buf_type_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, H5P_DEFAULT)<0) + if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, H5P_DEFAULT)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed"); /* Fill the selection in the memory buffer */ @@ -3679,9 +3952,104 @@ done: FUNC_LEAVE (ret_value); } /* H5Dfill() */ + +/*-------------------------------------------------------------------------- + NAME + H5Dfill + PURPOSE + Fill a selection in memory with a value + USAGE + herr_t H5Dfill(fill, fill_type, space, buf, buf_type) + const void *fill; IN: Pointer to fill value to use + hid_t fill_type_id; IN: Datatype of the fill value + void *buf; IN/OUT: Memory buffer to fill selection within + hid_t buf_type_id; IN: Datatype of the elements in buffer + hid_t space_id; IN: Dataspace describing memory buffer & + containing selection to use. + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + Use the selection in the dataspace to fill elements in a memory buffer. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + If "fill" parameter is NULL, use all zeros as fill value + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id) +{ + H5S_t *space; /* Dataspace */ + H5T_t *fill_type; /* Fill-value datatype */ + H5T_t *buf_type; /* Buffer datatype */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER (H5Dfill, FAIL); + H5TRACE5("e","xixii",fill,fill_type_id,buf,buf_type_id,space_id); + /* Check args */ + if (buf==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer"); + if (H5I_DATASPACE != H5I_get_type(space_id) || NULL == (space=H5I_object(space_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataspace"); + if (H5I_DATATYPE != H5I_get_type(fill_type_id) || NULL == (fill_type=H5I_object(fill_type_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + if (H5I_DATATYPE != H5I_get_type(buf_type_id) || NULL == (buf_type=H5I_object(buf_type_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + /* Fill the selection in the memory buffer */ + if(H5D_fill(fill,fill_type,buf,buf_type,space)<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Dfill() */ + +/*------------------------------------------------------------------------- + * Function: H5Ddebug + * + * Purpose: Prints various information about a dataset. This function is + * not to be documented in the API at this time. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, April 28, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ddebug(hid_t dset_id, unsigned UNUSED flags) +{ + H5D_t *dset=NULL; + + FUNC_ENTER(H5Ddebug, FAIL); + H5TRACE2("e","iIu",dset_id,flags); + + /* Check args */ + if (H5I_DATASET!=H5I_get_type(dset_id) || + NULL==(dset=H5I_object(dset_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset"); + } + + /* Print B-tree information */ + if (H5D_CHUNKED==dset->layout.type) { + H5F_istore_dump_btree(dset->ent.file, stdout, dset->layout.ndims, + dset->layout.addr); + } else if (H5D_CONTIGUOUS==dset->layout.type) { + HDfprintf(stdout, " %-10s %a\n", "Address:", + dset->layout.addr); + } + + FUNC_LEAVE(SUCCEED); +} + + /*------------------------------------------------------------------------- * Function: H5Dset_extent * @@ -3879,49 +4247,3 @@ done: H5S_close( space ); FUNC_LEAVE( ret_value ); } - - - -/*------------------------------------------------------------------------- - * Function: H5Ddebug - * - * Purpose: Prints various information about a dataset. This function is - * not to be documented in the API at this time. - * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Wednesday, April 28, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Ddebug(hid_t dset_id, unsigned UNUSED flags) -{ - H5D_t *dset=NULL; - - FUNC_ENTER(H5Ddebug, FAIL); - H5TRACE2("e","iIu",dset_id,flags); - - /* Check args */ - if (H5I_DATASET!=H5I_get_type(dset_id) || - NULL==(dset=H5I_object(dset_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset"); - } - - /* Print B-tree information */ - if (H5D_CHUNKED==dset->layout.type) { - H5F_istore_dump_btree(dset->ent.file, stdout, dset->layout.ndims, - dset->layout.addr); - } else if (H5D_CONTIGUOUS==dset->layout.type) { - HDfprintf(stdout, " %-10s %a\n", "Address:", - dset->layout.addr); - } - - FUNC_LEAVE(SUCCEED); -} - diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 33fa930..8bbdc74 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -55,10 +55,19 @@ #define H5D_CRT_CHUNK_SIZE_SIZE sizeof(hsize_t[32]) #define H5D_CRT_CHUNK_SIZE_DEF {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} -/* Definitions for fill value */ -#define H5D_CRT_FILL_VALUE_NAME "fill" +/* Definitions for fill value. size=0 means fill value will be 0 as + * library default; size=-1 means fill value is undefined. */ +#define H5D_CRT_FILL_VALUE_NAME "fill_value" #define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t) #define H5D_CRT_FILL_VALUE_DEF {NULL, 0, NULL} +/* Definitions for space allocation time */ +#define H5D_CRT_SPACE_TIME_NAME "space_time" +#define H5D_CRT_SPACE_TIME_SIZE sizeof(H5D_space_time_t) +#define H5D_CRT_SPACE_TIME_DEF H5D_SPACE_ALLOC_LATE +/* Definitions for time of fill value writing */ +#define H5D_CRT_FILL_TIME_NAME "fill_time" +#define H5D_CRT_FILL_TIME_SIZE sizeof(H5D_fill_time_t) +#define H5D_CRT_FILL_TIME_DEF H5D_FILL_TIME_ALLOC /* Definitions for external file list */ #define H5D_CRT_EXT_FILE_LIST_NAME "efl" #define H5D_CRT_EXT_FILE_LIST_SIZE sizeof(H5O_efl_t) diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 66b6b2f..2e580eb 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -27,10 +27,39 @@ typedef enum H5D_layout_t { H5D_COMPACT = 0, /*raw data is very small */ H5D_CONTIGUOUS = 1, /*the default */ H5D_CHUNKED = 2, /*slow and fancy */ - H5D_NLAYOUTS = 3 /*this one must be last! */ } H5D_layout_t; +/* Values for the space allocation time property */ +typedef enum H5D_space_time_t { + H5D_SPACE_ALLOC_ERROR =-1, + H5D_SPACE_ALLOC_LATE =0, + H5D_SPACE_ALLOC_EARLY =1 +} H5D_space_time_t; + +/* Values for the status of space allocation */ +typedef enum H5D_space_status_t { + H5D_SPACE_STATUS_ERROR =-1, + H5D_SPACE_STATUS_NOT_ALLOCATED =0, + H5D_SPACE_STATUS_PART_ALLOCATED =1, + H5D_SPACE_STATUS_ALLOCATED =2 +} H5D_space_status_t; + +/* Values for time of writing fill value property */ +typedef enum H5D_fill_time_t { + H5D_FILL_TIME_ERROR =-1, + H5D_FILL_TIME_ALLOC =0, + H5D_FILL_TIME_NEVER =1 +} H5D_fill_time_t; + +/* Values for fill value status */ +typedef enum H5D_fill_value_t { + H5D_FILL_VALUE_ERROR =-1, + H5D_FILL_VALUE_UNDEFINED =0, + H5D_FILL_VALUE_DEFAULT =1, + H5D_FILL_VALUE_USER_DEFINED =2 +} H5D_fill_value_t; + /* Define the operator function pointer for H5Diterate() */ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *operator_data); @@ -44,6 +73,8 @@ __DLL__ hid_t H5Dcreate (hid_t file_id, const char *name, hid_t type_id, __DLL__ hid_t H5Dopen (hid_t file_id, const char *name); __DLL__ herr_t H5Dclose (hid_t dset_id); __DLL__ hid_t H5Dget_space (hid_t dset_id); +__DLL__ herr_t H5Dget_space_status(hid_t dset_id, + H5D_space_status_t *allocation); __DLL__ hid_t H5Dget_type (hid_t dset_id); __DLL__ hid_t H5Dget_create_plist (hid_t dset_id); __DLL__ hsize_t H5Dget_storage_size(hid_t dset_id); diff --git a/src/H5O.c b/src/H5O.c index 891a004..3e038bc 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -63,8 +63,8 @@ static const H5O_class_t *const message_type_g[] = { H5O_SDSPACE, /*0x0001 Simple Dimensionality */ NULL, /*0x0002 Data space (fiber bundle?) */ H5O_DTYPE, /*0x0003 Data Type */ - H5O_FILL, /*0x0004 Data storage -- fill value */ - NULL, /*0x0005 Not assigned */ + H5O_FILL, /*0x0004 Old data storage -- fill value */ + H5O_FILL_NEW, /*0x0005 New Data storage -- fill value */ NULL, /*0x0006 Data storage -- compact object */ H5O_EFL, /*0x0007 Data storage -- external data files */ H5O_LAYOUT, /*0x0008 Data Layout */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 1d8ef69..567b7ca 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -17,81 +17,130 @@ #define PABLO_MASK H5O_fill_mask -static void *H5O_fill_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh); +static void *H5O_fill_new_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh); +static herr_t H5O_fill_new_encode(H5F_t *f, uint8_t *p, const void *_mesg); +static void *H5O_fill_new_copy(const void *_mesg, void *_dest); +static size_t H5O_fill_new_size(H5F_t *f, const void *_mesg); +static herr_t H5O_fill_new_reset(void *_mesg); +static herr_t H5O_fill_new_debug(H5F_t *f, const void *_mesg, FILE *stream, + int indent, int fwidth); + +static void *H5O_fill_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh); static herr_t H5O_fill_encode(H5F_t *f, uint8_t *p, const void *_mesg); -static void *H5O_fill_copy(const void *_mesg, void *_dest); +static void *H5O_fill_copy(const void *_mesg, void *_dest); static size_t H5O_fill_size(H5F_t *f, const void *_mesg); static herr_t H5O_fill_reset(void *_mesg); static herr_t H5O_fill_debug(H5F_t *f, const void *_mesg, FILE *stream, int indent, int fwidth); -/* This message derives from H5O */ +/* This message derives from H5O, for old fill value before version 1.5 */ const H5O_class_t H5O_FILL[1] = {{ - H5O_FILL_ID, /*message id number */ - "fill", /*message name for debugging */ - sizeof(H5O_fill_t), /*native message size */ - H5O_fill_decode, /*decode message */ - H5O_fill_encode, /*encode message */ - H5O_fill_copy, /*copy the native value */ - H5O_fill_size, /*raw message size */ - H5O_fill_reset, /*free internal memory */ - NULL, /* free method */ + H5O_FILL_ID, /*message id number */ + "fill", /*message name for debugging */ + sizeof(H5O_fill_t), /*native message size */ + H5O_fill_decode, /*decode message */ + H5O_fill_encode, /*encode message */ + H5O_fill_copy, /*copy the native value */ + H5O_fill_size, /*raw message size */ + H5O_fill_reset, /*free internal memory */ + NULL, /* free method */ + NULL, /*get share method */ + NULL, /*set share method */ + H5O_fill_debug, /*debug the message */ +}}; + +/* This message derives from H5O, for new fill value after version 1.4 */ +const H5O_class_t H5O_FILL_NEW[1] = {{ + H5O_FILL_NEW_ID, /*message id number */ + "fill_new", /*message name for debugging */ + sizeof(H5O_fill_new_t), /*native message size */ + H5O_fill_new_decode, /*decode message */ + H5O_fill_new_encode, /*encode message */ + H5O_fill_new_copy, /*copy the native value */ + H5O_fill_new_size, /*raw message size */ + H5O_fill_new_reset, /*free internal memory */ + NULL, /* free method */ NULL, /*get share method */ NULL, /*set share method */ - H5O_fill_debug, /*debug the message */ + H5O_fill_new_debug, /*debug the message */ }}; +#define H5O_FILL_VERSION 1 + /* Interface initialization */ static int interface_initialize_g = 0; #define INTERFACE_INIT NULL /*------------------------------------------------------------------------- - * Function: H5O_fill_decode + * Function: H5O_fill_new_decode * - * Purpose: Decode a fill value message. + * Purpose: Decode a new fill value message. The new fill value + * message is fill value plus space allocation time and + * fill value writing time and whether fill value is defined. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * - * Programmer: Robb Matzke - * Wednesday, September 30, 1998 + * Programmer: Raymond Lu + * Feb 26, 2002 * * Modifications: * *------------------------------------------------------------------------- */ static void * -H5O_fill_decode(H5F_t UNUSED *f, const uint8_t *p, +H5O_fill_new_decode(H5F_t UNUSED *f, const uint8_t *p, H5O_shared_t UNUSED *sh) { - H5O_fill_t *mesg=NULL; - void *ret_value = NULL; + H5O_fill_new_t *mesg=NULL; + int version; + void *ret_value = NULL; - FUNC_ENTER(H5O_fill_decode, NULL); + FUNC_ENTER(H5O_fill_new_decode, NULL); assert(f); assert(p); assert(!sh); - if (NULL==(mesg=H5MM_calloc(sizeof(H5O_fill_t)))) { + if (NULL==(mesg=H5MM_calloc(sizeof(H5O_fill_new_t)))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message"); } + + /* Version */ + version = *p++; + if( version != H5O_FILL_VERSION) { + HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, + "bad version number for fill value message"); + } + + /* Space allocation time */ + mesg->space_time = *p++; + + /* Fill value write time */ + mesg->fill_time = *p++; + + /* Whether fill value is defined */ + mesg->fill_defined = *p++; + + /* Does it handle undefined fill value? */ UINT32DECODE(p, mesg->size); if (mesg->size>0) { - if (NULL==(mesg->buf=H5MM_malloc(mesg->size))) { + H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t); + if (NULL==(mesg->buf=H5MM_malloc((size_t)mesg->size))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value"); } - HDmemcpy(mesg->buf, p, mesg->size); + HDmemcpy(mesg->buf, p, (size_t)mesg->size); } ret_value = (void*)mesg; done: if (!ret_value && mesg) { - H5MM_xfree(mesg->buf); + if(mesg->buf) + H5MM_xfree(mesg->buf); H5MM_xfree(mesg); } FUNC_LEAVE(ret_value); @@ -99,13 +148,113 @@ H5O_fill_decode(H5F_t UNUSED *f, const uint8_t *p, /*------------------------------------------------------------------------- - * Function: H5O_fill_encode + * Function: H5O_fill_decode + * + * Purpose: Decode a fill value message. + * + * Return: Success: Ptr to new message in native struct. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, September 30, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5O_fill_decode(H5F_t UNUSED *f, const uint8_t *p, + H5O_shared_t UNUSED *sh) +{ + H5O_fill_t *mesg=NULL; + void *ret_value = NULL; + + FUNC_ENTER(H5O_fill_decode, NULL); + assert(f); + assert(p); + assert(!sh); + + if (NULL==(mesg=H5MM_calloc(sizeof(H5O_fill_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill value message"); + } + UINT32DECODE(p, mesg->size); + if (mesg->size>0) { + if (NULL==(mesg->buf=H5MM_malloc(mesg->size))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill value"); + } + HDmemcpy(mesg->buf, p, mesg->size); + } + + ret_value = (void*)mesg; + + done: + if (!ret_value && mesg) { + if(mesg->buf) + H5MM_xfree(mesg->buf); + H5MM_xfree(mesg); + } + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_new_encode * - * Purpose: Encode a fill value message. + * Purpose: Encode a new fill value message. The new fill value + * message is fill value plus space allocation time and + * fill value writing time and whether fill value is defined. * * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke + * Programmer: Raymond Lu + * Feb 26, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fill_new_encode(H5F_t UNUSED *f, uint8_t *p, const void *_mesg) +{ + const H5O_fill_new_t *mesg = (const H5O_fill_new_t *)_mesg; + + FUNC_ENTER(H5O_fill_new_encode, FAIL); + assert(f); + assert(p); + assert(mesg && NULL==mesg->type); + + /* Version */ + *p++ = H5O_FILL_VERSION; + /* Space allocation time */ + *p++ = mesg->space_time; + /* Fill value writing time */ + *p++ = mesg->fill_time; + /* Whether fill value is defined */ + *p++ = mesg->fill_defined; + + /* Does it handle undefined fill value? */ + UINT32ENCODE(p, mesg->size); + if(mesg->size>0) + if(mesg->buf) { + H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t); + HDmemcpy(p, mesg->buf, (size_t)mesg->size); + } /* end if */ + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_encode + * + * Purpose: Encode a fill value message. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke * Thursday, October 1, 1998 * * Modifications: @@ -115,7 +264,7 @@ H5O_fill_decode(H5F_t UNUSED *f, const uint8_t *p, static herr_t H5O_fill_encode(H5F_t UNUSED *f, uint8_t *p, const void *_mesg) { - const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; + const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; FUNC_ENTER(H5O_fill_encode, FAIL); assert(f); @@ -123,74 +272,150 @@ H5O_fill_encode(H5F_t UNUSED *f, uint8_t *p, const void *_mesg) assert(mesg && NULL==mesg->type); UINT32ENCODE(p, mesg->size); - HDmemcpy(p, mesg->buf, mesg->size); + if(mesg->buf) + HDmemcpy(p, mesg->buf, mesg->size); FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5O_fill_copy + * Function: H5O_fill_new_copy * * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if - * necessary. + * necessary. The new fill value message is fill value plus + * space allocation time and fill value writing time and + * whether fill value is defined. * * Return: Success: Ptr to _DEST * * Failure: NULL * - * Programmer: Robb Matzke - * Thursday, October 1, 1998 + * Programmer: Raymond Lu + * Feb 26, 2002 * * Modifications: * *------------------------------------------------------------------------- */ static void * -H5O_fill_copy(const void *_mesg, void *_dest) +H5O_fill_new_copy(const void *_mesg, void *_dest) { - const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; - H5O_fill_t *dest = (H5O_fill_t *)_dest; + const H5O_fill_new_t *mesg = (const H5O_fill_new_t *)_mesg; + H5O_fill_new_t *dest = (H5O_fill_new_t *)_dest; void *ret_value = NULL; - FUNC_ENTER(H5O_fill_copy, NULL); + FUNC_ENTER(H5O_fill_new_copy, NULL); assert(mesg); - if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_fill_t)))) { + if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_fill_new_t)))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill message"); } + /* Copy data type of fill value */ if (mesg->type && NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT))) { HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy fill value data type"); } + /* Copy fill value and its size */ if (mesg->buf) { - if (NULL==(dest->buf=H5MM_malloc(mesg->size))) { + H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t); + if (NULL==(dest->buf=H5MM_malloc((size_t)mesg->size))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value"); } dest->size = mesg->size; - HDmemcpy(dest->buf, mesg->buf, mesg->size); + HDmemcpy(dest->buf, mesg->buf, (size_t)mesg->size); } + + /* Copy three fill value attributes */ + dest->space_time = mesg->space_time; + dest->fill_time = mesg->fill_time; + dest->fill_defined = mesg->fill_defined; + ret_value = dest; - done: +done: if (!ret_value && dest) { - H5MM_xfree(dest->buf); - if (dest->type) H5T_close(dest->type); - if (!_dest) H5MM_xfree(dest); + if(dest->buf) + H5MM_xfree(dest->buf); + if (dest->type) + H5T_close(dest->type); + if (!_dest) + H5MM_xfree(dest); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5O_fill_size + * Function: H5O_fill_copy + * + * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if + * necessary. + * + * Return: Success: Ptr to _DEST + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5O_fill_copy(const void *_mesg, void *_dest) +{ + const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; + H5O_fill_t *dest = (H5O_fill_t *)_dest; + void *ret_value = NULL; + + FUNC_ENTER(H5O_fill_copy, NULL); + assert(mesg); + + if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_fill_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill message"); + } + if (mesg->type && + NULL==(dest->type=H5T_copy(mesg->type, H5T_COPY_TRANSIENT))) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "unable to copy fill value data type"); + } + if (mesg->buf) { + if (NULL==(dest->buf=H5MM_malloc(mesg->size))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for fill value"); + } + dest->size = mesg->size; + HDmemcpy(dest->buf, mesg->buf, mesg->size); + } + ret_value = dest; + +done: + if (!ret_value && dest) { + if(dest->buf) + H5MM_xfree(dest->buf); + if (dest->type) + H5T_close(dest->type); + if (!_dest) + H5MM_xfree(dest); + } + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_new_size * * Purpose: Returns the size of the raw message in bytes not counting the * message type or size fields, but only the data fields. This - * function doesn't take into account alignment. + * function doesn't take into account alignment. The new fill + * value message is fill value plus space allocation time and + * fill value writing time and whether fill value is defined. * * Return: Success: Message data size in bytes w/o alignment. * @@ -204,9 +429,47 @@ H5O_fill_copy(const void *_mesg, void *_dest) *------------------------------------------------------------------------- */ static size_t +H5O_fill_new_size(H5F_t UNUSED *f, const void *_mesg) +{ + const H5O_fill_new_t *mesg = (const H5O_fill_new_t *)_mesg; + size_t ret_value = 0; + + FUNC_ENTER(H5O_fill_new_size, 0); + assert(f); + assert(mesg); + + ret_value = 1 + /* Version number */ + 1 + /* Space allocation time */ + 1 + /* Fill value write time */ + 1 + /* Fill value defined */ + 4 + /* Fill value size */ + (mesg->size>0 ? mesg->size : 0); /* Size of fill value */ + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_size + * + * Purpose: Returns the size of the raw message in bytes not counting the + * message type or size fields, but only the data fields. This + * function doesn't take into account alignment. + * + * Return: Success: Message data size in bytes w/o alignment. + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static size_t H5O_fill_size(H5F_t UNUSED *f, const void *_mesg) { - const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; + const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; FUNC_ENTER(H5O_fill_size, 0); assert(f); @@ -217,9 +480,11 @@ H5O_fill_size(H5F_t UNUSED *f, const void *_mesg) /*------------------------------------------------------------------------- - * Function: H5O_fill_reset + * Function: H5O_fill_new_reset * - * Purpose: Resets a message to an initial state + * Purpose: Resets a new message to an initial state. The new fill value + * message is fill value plus space allocation time and + * fill value writing time and whether fill value is defined. * * Return: Non-negative on success/Negative on failure * @@ -231,18 +496,96 @@ H5O_fill_size(H5F_t UNUSED *f, const void *_mesg) *------------------------------------------------------------------------- */ static herr_t +H5O_fill_new_reset(void *_mesg) +{ + H5O_fill_new_t *mesg = (H5O_fill_new_t *)_mesg; + + FUNC_ENTER(H5O_fill_new_reset, FAIL); + assert(mesg); + + if(mesg->buf) + mesg->buf = H5MM_xfree(mesg->buf); + mesg->size = -1; + if (mesg->type) { + H5T_close(mesg->type); + mesg->type = NULL; + } + mesg->space_time = 0; + mesg->fill_time = 0; + mesg->fill_defined = 0; + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_reset + * + * Purpose: Resets a message to an initial state + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t H5O_fill_reset(void *_mesg) { - H5O_fill_t *mesg = (H5O_fill_t *)_mesg; + H5O_fill_t *mesg = (H5O_fill_t *)_mesg; FUNC_ENTER(H5O_fill_reset, FAIL); assert(mesg); - mesg->buf = H5MM_xfree(mesg->buf); + if(mesg->buf) + mesg->buf = H5MM_xfree(mesg->buf); mesg->size = 0; if (mesg->type) { - H5T_close(mesg->type); - mesg->type = NULL; + H5T_close(mesg->type); + mesg->type = NULL; + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_fill_new_debug + * + * Purpose: Prints debugging info for the message. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, October 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fill_new_debug(H5F_t UNUSED *f, const void *_mesg, FILE *stream, + int indent, int fwidth) +{ + const H5O_fill_new_t *mesg = (const H5O_fill_new_t *)_mesg; + + FUNC_ENTER(H5O_fill_new_debug, FAIL); + assert(f); + assert(mesg); + assert(stream); + assert(indent>=0); + assert(fwidth>=0); + + HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, + "Bytes:", mesg->size); + fprintf(stream, "%*s%-*s ", indent, "", fwidth, "Data type:"); + if (mesg->type) { + H5T_debug(mesg->type, stream); + fprintf(stream, "\n"); + } else { + fprintf(stream, "\n"); } FUNC_LEAVE(SUCCEED); @@ -308,8 +651,9 @@ H5O_fill_debug(H5F_t UNUSED *f, const void *_mesg, FILE *stream, *------------------------------------------------------------------------- */ herr_t -H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type) +H5O_fill_convert(void *_fill, H5T_t *dset_type) { + H5O_fill_new_t *fill = _fill; H5T_path_t *tpath=NULL; /*type conversion info */ void *buf=NULL, *bkg=NULL; /*conversion buffers */ hid_t src_id=-1, dst_id=-1; /*data type identifiers */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 5603258..a4d3fa0 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -39,7 +39,10 @@ const H5O_class_t H5O_LAYOUT[1] = {{ H5O_layout_debug, /*debug the message */ }}; -#define H5O_LAYOUT_VERSION 1 +/* For forward and backward compatibility. Version is 1 when space is + * allocated; 2 when space is delayed for allocation. */ +#define H5O_LAYOUT_VERSION_1 1 +#define H5O_LAYOUT_VERSION_2 2 /* Interface initialization */ #define PABLO_MASK H5O_layout_mask @@ -67,6 +70,10 @@ H5FL_DEFINE(H5O_layout_t); * Robb Matzke, 1998-07-20 * Rearranged the message to add a version number at the beginning. * + * Raymond Lu, 2002-2-26 + * Added version number 2 case depends on if space has been allocated + * at the moment when layout header message is updated. + * *------------------------------------------------------------------------- */ static void * @@ -89,9 +96,9 @@ H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh) "memory allocation failed"); } - /* Version */ + /* Version. 1 when space allocated; 2 when space allocation is delayed */ version = *p++; - if (version!=H5O_LAYOUT_VERSION) { + if (version!=H5O_LAYOUT_VERSION_1 && version!=H5O_LAYOUT_VERSION_2) { HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message"); } @@ -136,6 +143,10 @@ H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh) * Robb Matzke, 1998-07-20 * Rearranged the message to add a version number at the beginning. * + * Raymond Lu, 2002-2-26 + * Added version number 2 case depends on if space has been allocated + * at the moment when layout header message is updated. + * *------------------------------------------------------------------------- */ static herr_t @@ -152,8 +163,14 @@ H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg) assert(mesg->ndims > 0 && mesg->ndims <= H5O_LAYOUT_NDIMS); assert(p); - /* Version */ - *p++ = H5O_LAYOUT_VERSION; + /* Version: 1 when space allocated; 2 when space allocation is delayed */ + if(mesg->type==H5D_CONTIGUOUS) { + if(mesg->addr==HADDR_UNDEF) + *p++ = H5O_LAYOUT_VERSION_2; + else + *p++ = H5O_LAYOUT_VERSION_1; + } else + *p++ = H5O_LAYOUT_VERSION_1; /* number of dimensions */ *p++ = mesg->ndims; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index d727e58..786ae69 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -18,6 +18,7 @@ #define _H5Oprivate_H #include "H5Opublic.h" +#include "H5Dpublic.h" /* Private headers needed by this file */ #include "H5private.h" @@ -136,17 +137,34 @@ __DLLVAR__ const H5O_class_t H5O_DTYPE[1]; /* operates on an H5T_t struct */ /* - * Fill Value Message. + * Old Fill Value Message. */ -#define H5O_FILL_ID 0x0004 -__DLLVAR__ const H5O_class_t H5O_FILL[1]; +#define H5O_FILL_ID 0x0004 +__DLLVAR__ const H5O_class_t H5O_FILL[1]; typedef struct H5O_fill_t { - H5T_t *type; /*type. Null implies same as dataset */ - size_t size; /*number of bytes in the fill value */ - void *buf; /*the fill value */ + H5T_t *type; /*type. Null implies same as dataset */ + size_t size; /*number of bytes in the fill value */ + void *buf; /*the fill value */ } H5O_fill_t; +/* + * New Fill Value Message. The new fill value message is fill value plus + * space allocation time and fill value writing time and whether fill + * value is defined. + */ +#define H5O_FILL_NEW_ID 0x0005 +__DLLVAR__ const H5O_class_t H5O_FILL_NEW[1]; + +typedef struct H5O_fill_new_t { + H5T_t *type; /*type. Null implies same as dataset */ + ssize_t size; /*number of bytes in the fill value */ + void *buf; /*the fill value */ + H5D_space_time_t space_time; /* time to allocate space */ + H5D_fill_time_t fill_time; /* time to write fill value */ + htri_t fill_defined; /* whether fill value is defined */ +} H5O_fill_new_t; + /* * External File List Message @@ -302,6 +320,6 @@ __DLL__ herr_t H5O_efl_write(H5F_t *f, const H5O_efl_t *efl, haddr_t addr, size_t size, const uint8_t *buf); /* Fill value operators */ -__DLL__ herr_t H5O_fill_convert(H5O_fill_t *fill, H5T_t *type); +__DLL__ herr_t H5O_fill_convert(void *_fill, H5T_t *type); #endif diff --git a/src/H5P.c b/src/H5P.c index f8da556..3098419 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -3210,7 +3210,9 @@ done: * VALUE is interpretted as being of type TYPE, which need not * be the same type as the dataset but the library must be able * to convert VALUE to the dataset type when the dataset is - * created. + * created. If VALUE is NULL, it will be interpreted as + * undefining fill value. The fill value property will be + * removed from property list. * * Return: Non-negative on success/Negative on failure * @@ -3229,11 +3231,11 @@ done: herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value) { - H5O_fill_t fill; + H5O_fill_t fill; H5T_t *type = NULL; H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value=SUCCEED; /* return value */ - + FUNC_ENTER(H5Pset_fill_value, FAIL); H5TRACE3("e","iix",plist_id,type_id,value); @@ -3245,26 +3247,36 @@ H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value) if(NULL == (plist = H5I_object(plist_id))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + /* Get the "basic" fill value structure */ if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value"); - if (H5I_DATATYPE!=H5I_get_type(type_id) || NULL==(type=H5I_object(type_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (!value) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value specified"); - - /* Set the fill value */ - H5O_reset(H5O_FILL, &fill); - if (NULL==(fill.type=H5T_copy(type, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy data type"); - fill.size = H5T_get_size(type); - if (NULL==(fill.buf=H5MM_malloc(fill.size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for fill value"); - HDmemcpy(fill.buf, value, fill.size); + /* Reset the fill structure */ + if(H5O_reset(H5O_FILL, &fill)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't reset fill value"); + + if(value) { + if (H5I_DATATYPE!=H5I_get_type(type_id) || + NULL==(type=H5I_object(type_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + + /* Set the fill value */ + if (NULL==(fill.type=H5T_copy(type, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to copy data type"); + fill.size = H5T_get_size(type); + if (NULL==(fill.buf=H5MM_malloc(fill.size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, + "memory allocation failed for fill value"); + HDmemcpy(fill.buf, value, fill.size); + } else { + fill.type = fill.buf = NULL; + fill.size = (size_t)-1; + } if(H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set fill value"); - + done: FUNC_LEAVE(ret_value); } @@ -3314,8 +3326,8 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) if (H5I_DATATYPE!=H5I_get_type(type_id) || NULL==(type=H5I_object(type_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); if (!value) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value output buffer"); - + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,"no fill value output buffer"); + /* Get the plist structure */ if(NULL == (plist = H5I_object(plist_id))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); @@ -3323,14 +3335,20 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) /* * If no fill value is defined then return an error. We can't even * return zero because we don't know the data type of the dataset and - * data type conversion might not have resulted in zero. + * data type conversion might not have resulted in zero. If fill value + * is undefined, also return error. */ if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value"); - if(NULL == fill.buf) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "no fill value defined"); - - /* + if(fill.size == (size_t)-1) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, + "fill value is undefined"); + + if(fill.size == 0) { + HDmemset(value, 0, H5T_get_size(type)); + HRETURN(SUCCEED); + } + /* * Can we convert between the source and destination data types? */ if(NULL==(tpath=H5T_path_find(fill.type, type, NULL, NULL))) @@ -3376,6 +3394,266 @@ done: /*------------------------------------------------------------------------- + * Function: H5P_fill_value_defined + * + * Purpose: Check if fill value is defined. Internal version of function + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, January 16, 2002 + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_fill_value_defined(H5P_genplist_t *plist, H5D_fill_value_t *status) +{ + herr_t ret_value = SUCCEED; + H5O_fill_t fill; + + FUNC_ENTER(H5P_fill_value_defined, FAIL); + + assert(plist); + assert(status); + + /* Get the fill value struct */ + if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value"); + + /* Check if the fill value was never set */ + if(fill.size == (size_t)-1 && !fill.buf) { + *status = H5D_FILL_VALUE_UNDEFINED; + } + /* Check if the fill value was set to the default fill value by the library */ + else if(fill.size == 0 && !fill.buf) { + *status = H5D_FILL_VALUE_DEFAULT; + } + /* Check if the fill value was set by the application */ + else if(fill.size > 0 && fill.buf) { + *status = H5D_FILL_VALUE_USER_DEFINED; + } + else { + *status = H5D_FILL_VALUE_ERROR; + HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "invalid combination of fill-value info"); + } + +done: + FUNC_LEAVE(ret_value); +} /* end H5P_fill_value_defined() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pfill_value_defined + * + * Purpose: Check if fill value is defined. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, January 16, 2002 + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pfill_value_defined(hid_t plist_id, H5D_fill_value_t *status) +{ + H5P_genplist_t *plist; + herr_t ret_value = SUCCEED; + + FUNC_ENTER(H5Pfill_value_defined, FAIL); + + assert(status); + + /* Check arguments */ + if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE)) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation proprety list"); + + /* Get the plist structure */ + if(NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + + /* Call the internal function */ + if(H5P_fill_value_defined(plist, status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value info"); + +done: + FUNC_LEAVE(ret_value); +} /* end H5Pfill_value_defined() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_space_time + * + * Purpose: Set space allocation time for dataset during creation. + * Valid values are H5D_EARLY, H5D_LATE. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, January 16, 2002 + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_space_time(hid_t plist_id, H5D_space_time_t alloc_time) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER(H5Pset_space_time, FAIL); + + /* Check args */ + if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); + + /* Get the property list structure */ + if(NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + + /* Set values */ + if(H5P_set(plist, H5D_CRT_SPACE_TIME_NAME, &alloc_time) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time"); + +done: + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_space_time + * + * Purpose: Get space allocation time for dataset creation. Valid + * values are H5D_EARLY, H5D_LATE. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, January 16, 2002 + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_space_time(hid_t plist_id, H5D_space_time_t *alloc_time/*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER(H5Pget_space_time, FAIL); + H5TRACE2("e","ix",plist_id,alloc_time); + + /* Check args */ + if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); + + /* Get the property list structure */ + if(NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + + /* Get values */ + if(!alloc_time || H5P_get(plist, H5D_CRT_SPACE_TIME_NAME, alloc_time) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get space allocation time"); + +done: + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fill_time + * + * Purpose: Set fill value writing time for dataset. Valid values are + * H5D_ALLOC and H5D_NEVER. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, January 16, 2002 + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER(H5Pset_fill_time, FAIL); + + /* Check args */ + if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); + + /* Get the property list structure */ + if(NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + + /* Set values */ + if(H5P_set(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time"); + +done: + FUNC_LEAVE(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5Pget_fill_time + * + * Purpose: Get fill value writing time. Valid values are H5D_NEVER + * and H5D_ALLOC. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, January 16, 2002 + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t *fill_time/*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER(H5Pget_fill_time, FAIL); + H5TRACE2("e","ix",plist_id,fill_time); + + /* Check args */ + if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); + + /* Get the property list structure */ + if(NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + + /* Set values */ + if(!fill_time || H5P_get(plist, H5D_CRT_FILL_TIME_NAME, fill_time) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time"); + +done: + FUNC_LEAVE(ret_value); +} + + + +/*------------------------------------------------------------------------- * Function: H5Pset_gc_references * * Purpose: Sets the flag for garbage collecting references for the file. diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 28071f4..ba054e3 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -46,6 +46,8 @@ __DLL__ herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, __DLL__ herr_t H5P_set_vlen_mem_manager(H5P_genplist_t *plist, H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func, void *free_info); +__DLL__ herr_t H5P_fill_value_defined(H5P_genplist_t *plist, + H5D_fill_value_t *status); /* *SPECIAL* Don't make more of these! -QAK */ __DLL__ htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id); diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 1f5bc65..d50f268 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -230,6 +230,14 @@ __DLL__ herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value); __DLL__ herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/); +__DLL__ herr_t H5Pfill_value_defined(hid_t plist, H5D_fill_value_t *status); +__DLL__ herr_t H5Pset_space_time(hid_t plist_id, H5D_space_time_t + alloc_time); +__DLL__ herr_t H5Pget_space_time(hid_t plist_id, H5D_space_time_t + *alloc_time/*out*/); +__DLL__ herr_t H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time); +__DLL__ herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t + *fill_time/*out*/); __DLL__ herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref); __DLL__ herr_t H5Pget_gc_references(hid_t fapl_id, unsigned *gc_ref/*out*/); __DLL__ herr_t H5Pset_fclose_degree(hid_t fapl_id, H5F_close_degree_t degree); diff --git a/src/H5Sall.c b/src/H5Sall.c index 36ad983..1afba52 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -1084,7 +1084,7 @@ H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_all_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *buf) +H5S_all_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *buf) { hssize_t nelemts; /* Number of elements in dataspace */ herr_t ret_value=SUCCEED; /* return value */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 0857aeb..d5a35fa 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -6590,7 +6590,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_select_fill_gen(const void *fill, size_t fill_size, H5S_t *space, void *buf) +H5S_hyper_select_fill_gen(const void *fill, size_t fill_size, const H5S_t *space, void *buf) { H5S_hyper_span_info_t *spans=NULL; /* Pointer to copy of the span tree */ H5S_hyper_span_info_t *tmp_spans; /* Temporary pointer to a span tree */ @@ -6794,7 +6794,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_select_fill_opt(const void *fill, size_t fill_size, H5S_t *space, void *buf) +H5S_hyper_select_fill_opt(const void *fill, size_t fill_size, const H5S_t *space, void *buf) { H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ @@ -6935,7 +6935,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_hyper_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *buf) +H5S_hyper_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *buf) { herr_t ret_value=SUCCEED; /* return value */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 668e9a6..bde26d5 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -139,7 +139,7 @@ __DLL__ herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, __DLL__ herr_t H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op, void *operator_data); __DLL__ herr_t H5S_point_select_fill(const void *fill, size_t fill_size, - H5S_t *space, void *buf); + const H5S_t *space, void *buf); /* "All" select functions */ __DLL__ herr_t H5S_all_release(H5S_t *space); @@ -162,7 +162,7 @@ __DLL__ herr_t H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, __DLL__ herr_t H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op, void *operator_data); __DLL__ herr_t H5S_all_select_fill(const void *fill, size_t fill_size, - H5S_t *space, void *buf); + const H5S_t *space, void *buf); __DLL__ htri_t H5S_all_opt_possible(const H5S_t *mem_space, const H5S_t *file_space, const unsigned flags); @@ -184,7 +184,7 @@ __DLL__ htri_t H5S_hyper_select_regular(const H5S_t *space); __DLL__ herr_t H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op, void *operator_data); __DLL__ herr_t H5S_hyper_select_fill(const void *fill, size_t fill_size, - H5S_t *space, void *buf); + const H5S_t *space, void *buf); /* "None" selection functions */ __DLL__ herr_t H5S_select_none(H5S_t *space); diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 883dfae..de5d875 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -1458,7 +1458,7 @@ H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_point_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *_buf) +H5S_point_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf) { hsize_t size[H5O_LAYOUT_NDIMS]; /* Total size of memory buf */ uint8_t *buf=(uint8_t *)_buf; /* Alias for memory buffer */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 3fd1903..12faf49 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -222,11 +222,11 @@ __DLL__ htri_t H5S_select_single(const H5S_t *space); __DLL__ htri_t H5S_select_regular(const H5S_t *space); __DLL__ htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2); __DLL__ herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, - H5D_operator_t op, void *operator_data); + H5D_operator_t op, void *operator_data); __DLL__ herr_t H5S_sel_iter_release(const H5S_t *space, - H5S_sel_iter_t *sel_iter); -__DLL__ herr_t H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space, - void *buf); + H5S_sel_iter_t *sel_iter); +__DLL__ herr_t H5S_select_fill(const void *fill, size_t fill_size, + const H5S_t *space, void *buf); /* Needed for internal use of selections in H5Fistore code */ __DLL__ herr_t H5S_select_all(H5S_t *space); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 8d18e5c..b7beed1 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -1565,7 +1565,7 @@ H5S_select_regular(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *buf) +H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *buf) { herr_t ret_value=FAIL; /* return value */ -- cgit v0.12