summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2002-04-11 22:52:48 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2002-04-11 22:52:48 (GMT)
commitce920c6c041c88a64b0553db538842f912ebda8e (patch)
tree3f3ebbafc532eb23a2ed43a7d4c5cfc07a609d58
parent19c8cfa8617156fa99caa4349fecb40ab652753c (diff)
downloadhdf5-ce920c6c041c88a64b0553db538842f912ebda8e.zip
hdf5-ce920c6c041c88a64b0553db538842f912ebda8e.tar.gz
hdf5-ce920c6c041c88a64b0553db538842f912ebda8e.tar.bz2
[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.
-rw-r--r--release_docs/RELEASE.txt4
-rw-r--r--src/H5D.c784
-rw-r--r--src/H5Dprivate.h13
-rw-r--r--src/H5Dpublic.h33
-rw-r--r--src/H5O.c4
-rw-r--r--src/H5Ofill.c454
-rw-r--r--src/H5Olayout.c27
-rw-r--r--src/H5Oprivate.h32
-rw-r--r--src/H5P.c326
-rw-r--r--src/H5Pprivate.h2
-rw-r--r--src/H5Ppublic.h8
-rw-r--r--src/H5Sall.c2
-rw-r--r--src/H5Shyper.c6
-rw-r--r--src/H5Spkg.h6
-rw-r--r--src/H5Spoint.c2
-rw-r--r--src/H5Sprivate.h8
-rw-r--r--src/H5Sselect.c2
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(0<efl.nused) {
+ new_dset->layout.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_<foo>_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_<foo>_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; u<dset->layout.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; u<dset->layout.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, "<dataset type>\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 */