summaryrefslogtreecommitdiffstats
path: root/src/H5D.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-01-09 17:20:03 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-01-09 17:20:03 (GMT)
commit9a433b99a56dc575f1c0b11f95b744de61859dbb (patch)
treed8c766537cb9adc364c902bd45477d97f67a4a9f /src/H5D.c
parent7fd449cb7987772a2881a5ced2ae7ad5231f1fa3 (diff)
downloadhdf5-9a433b99a56dc575f1c0b11f95b744de61859dbb.zip
hdf5-9a433b99a56dc575f1c0b11f95b744de61859dbb.tar.gz
hdf5-9a433b99a56dc575f1c0b11f95b744de61859dbb.tar.bz2
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces. Description: Performance Improvements: - Cached file offset & length sizes in shared file struct, to avoid constantly looking them up in the FCPL. - Generic property improvements: - Added "revision" number to generic property classes to speed up comparisons. - Changed method of storing properties from using a hash-table to the TBBT routines in the library. - Share the propery names between classes and the lists derived from them. - Removed redundant 'def_value' buffer from each property. - Switching code to use a "copy on write" strategy for properties in each list, where the properties in each list are shared with the properties in the class, until a property's value is changed in a list. - Fixed error in layout code which was allocating too many buffers. - Redefined public macros of the form (H5open()/H5check, <variable>) internally to only be (<variable>), avoiding innumerable useless calls to H5open() and H5check_version(). - Reuse already zeroed buffers in H5F_contig_fill instead of constantly re-zeroing them. - Don't write fill values if writing entire dataset. - Use gettimeofday() system call instead of time() system when checking the modification time of a dataset. - Added reference counted string API and use it for tracking the names of objects opening in a file (for the ID->name code). - Removed redundant H5P_get() calls in B-tree routines. - Redefine H5T datatype macros internally to the library, to avoid calling H5check redundantly. - Keep dataspace information for dataset locally instead of reading from disk each time. Added new module to track open objects in a file, to allow this (which will be useful eventually for some FPH5 metadata caching issues). - Remove H5AC_find macro which was inlining metadata cache lookups, and call function instead. - Remove redundant memset() calls from H5G_namei() routine. - Remove redundant checking of object type when locating objects in metadata cache and rely on the address only. - Create default dataset object to use when default dataset creation property list is used to create datasets, bypassing querying for all the property list values. - Use default I/O vector size when performing raw data with the default dataset transfer property list, instead of querying for I/O vector size. - Remove H5P_DEFAULT internally to the library, replacing it with more specific default property list based on the type of property list needed. - Remove redundant memset() calls in object header message (H5O*) routines. - Remove redunant memset() calls in data I/O routines. - Split free-list allocation routines into malloc() and calloc()- like routines, instead of one combined routine. - Remove lots of indirection in H5O*() routines. - Simplify metadata cache entry comparison routine (used when flushing entire cache out). - Only enable metadata cache statistics when H5AC_DEBUG is turned on, instead of always tracking them. - Simplify address comparison macro (H5F_addr_eq). - Remove redundant metadata cache entry protections during dataset creation by protecting the object header once and making all the modifications necessary for the dataset creation before unprotecting it. - Reduce # of "number of element in extent" computations performed by computing and storing the value during dataspace creation. - Simplify checking for group location's file information, when file has not been involving in file-mounting operations. - Use binary encoding for modification time, instead of ASCII. - Hoist H5HL_peek calls (to get information in a local heap) out of loops in many group routine. - Use static variable for iterators of selections, instead of dynamically allocation them each time. - Lookup & insert new entries in one step, avoiding traversing group's B-tree twice. - Fixed memory leak in H5Gget_objname_idx() routine (tangential to performance improvements, but fixed along the way). - Use free-list for reference counted strings. - Don't bother copying object names into cached group entries, since they are re-created when an object is opened. The benchmark I used to measure these results created several thousand small (2K) datasets in a file and wrote out the data for them. This is Elena's "regular.c" benchmark. These changes resulted in approximately ~4.3x speedup of the development branch when compared to the previous code in the development branch and ~1.4x speedup compared to the release branch. Additionally, these changes reduce the total memory used (code and data) by the development branch by ~800KB, bringing the development branch back into the same ballpark as the release branch. I'll send out a more detailed description of the benchmark results as a followup note. New internal API routines: Added "reference counted strings" API for tracking strings that get used by multiple owners without duplicating the strings. Added "ternary search tree" API for text->object mappings. Platforms tested: Tested h5committest {arabica (fortran), eirene (fortran, C++) modi4 (parallel, fortran)} Other platforms/configurations tested? FreeBSD 4.7 (sleipnir) serial & parallel Solaris 2.6 (baldric) serial
Diffstat (limited to 'src/H5D.c')
-rw-r--r--src/H5D.c1096
1 files changed, 547 insertions, 549 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 7485d7e..cab38cd 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -19,6 +19,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FDprivate.h" /* File drivers */
#include "H5FLprivate.h" /* Free Lists */
+#include "H5FOprivate.h" /* File objects */
#include "H5Gprivate.h" /* Group headers */
#include "H5HLprivate.h" /* Name heap */
#include "H5Iprivate.h" /* IDs */
@@ -64,12 +65,25 @@ static int interface_initialize_g = 0;
/* Local functions */
static herr_t H5D_init_interface(void);
-static herr_t H5D_alloc_storage (H5F_t *f, H5D_t *dset,H5D_time_alloc_t time_alloc);
-static herr_t H5D_init_storage(H5D_t *dataset);
-H5D_t * H5D_new(hid_t dcpl_id);
+static herr_t H5D_alloc_storage (H5F_t *f, H5D_t *dset,H5D_time_alloc_t time_alloc,
+ hbool_t update_time, hbool_t full_overwrite);
+static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite);
+static H5D_t * H5D_new(hid_t dcpl_id, hbool_t creating);
+static H5D_t * H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
+ const H5S_t *space, hid_t dcpl_id);
+static H5D_t * H5D_open_oid(H5G_entry_t *ent);
+static herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type,
+ const H5S_t *mem_space, const H5S_t *file_space,
+ hid_t dset_xfer_plist, void *buf/*out*/);
+static herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type,
+ const H5S_t *mem_space, const H5S_t *file_space,
+ hid_t dset_xfer_plist, const void *buf);
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);
+static hsize_t H5D_get_storage_size(H5D_t *dset);
+static haddr_t H5D_get_offset(H5D_t *dset);
+static herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size);
/* Declare a free list to manage the H5D_t struct */
H5FL_DEFINE_STATIC(H5D_t);
@@ -86,6 +100,9 @@ H5FL_BLK_DEFINE_STATIC(vlen_vl_buf);
/* Declare a free list to manage other blocks of VL data */
H5FL_BLK_DEFINE_STATIC(vlen_fl_buf);
+/* Define a static "default" dataset structure to use to initialize new datasets */
+static H5D_t H5D_def_dset;
+
/*-------------------------------------------------------------------------
* Function: H5D_init
@@ -188,6 +205,7 @@ H5D_init_interface(void)
H5O_efl_t efl = H5D_CRT_EXT_FILE_LIST_DEF;
H5O_pline_t pline = H5D_CRT_DATA_PIPELINE_DEF;
+ H5P_genplist_t *def_dcpl; /* Default Dataset Creation Property list */
size_t nprops; /* Number of properties */
herr_t ret_value = SUCCEED; /* Return value */
@@ -202,7 +220,7 @@ H5D_init_interface(void)
assert(H5P_CLS_DATASET_XFER_g!=(-1));
/* Get the pointer to the dataset transfer class */
- if (NULL == (xfer_pclass = H5I_object_verify(H5P_CLS_DATASET_XFER_g, H5I_GENPROP_CLS)))
+ if (NULL == (xfer_pclass = H5I_object(H5P_CLS_DATASET_XFER_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Get the number of properties in the class */
@@ -282,7 +300,7 @@ H5D_init_interface(void)
assert(H5P_CLS_DATASET_CREATE_g != -1);
/* Get the pointer to the dataset creation class */
- if(NULL == (crt_pclass = H5I_object_verify(H5P_CLS_DATASET_CREATE_g, H5I_GENPROP_CLS)))
+ if(NULL == (crt_pclass = H5I_object(H5P_CLS_DATASET_CREATE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
/* Get the number of properties in the class */
@@ -331,6 +349,37 @@ H5D_init_interface(void)
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list");
} /* end if */
+ /* Reset the "default dataset" information */
+ HDmemset(&H5D_def_dset,0,sizeof(H5D_t));
+
+ /* Get the default dataset cretion property list values and initialize the
+ * default dataset with them.
+ */
+ if (NULL == (def_dcpl = H5I_object(H5P_LST_DATASET_CREATE_g)))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, NULL, "can't get default dataset creation property list");
+
+ /* Set up the default allocation time information */
+ if(H5P_get(def_dcpl, H5D_CRT_ALLOC_TIME_NAME, &H5D_def_dset.alloc_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
+ if(H5D_def_dset.alloc_time==H5D_ALLOC_TIME_DEFAULT)
+ H5D_def_dset.alloc_time=H5D_ALLOC_TIME_LATE;
+
+ /* Get the default external file list information */
+ if(H5P_get(def_dcpl, H5D_CRT_EXT_FILE_LIST_NAME, &H5D_def_dset.efl) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list");
+
+ /* Get the default data storage method */
+ if(H5P_get(def_dcpl, H5D_CRT_LAYOUT_NAME, &H5D_def_dset.layout.type) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+
+ /* Get the default fill value time */
+ if (H5P_get(def_dcpl, H5D_CRT_FILL_TIME_NAME, &H5D_def_dset.fill_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
+
+ /* Get the default fill value */
+ if (H5P_get(def_dcpl, H5D_CRT_FILL_VALUE_NAME, &H5D_def_dset.fill) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value");
+
done:
FUNC_LEAVE(ret_value);
}
@@ -404,25 +453,21 @@ H5D_crt_copy(hid_t new_plist_id, hid_t old_plist_id, void UNUSED *copy_data)
FUNC_ENTER_NOAPI(H5D_crt_copy, FAIL);
/* Verify property list ID */
- if (NULL == (new_plist = H5P_object_verify(new_plist_id,H5P_DATASET_CREATE)))
+ if (NULL == (new_plist = H5I_object(new_plist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if (NULL == (old_plist = H5P_object_verify(old_plist_id,H5P_DATASET_CREATE)))
+ if (NULL == (old_plist = H5I_object(old_plist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the fill value, external file list, and data pipeline properties
* from the old property list */
- HDmemset(&src_fill,0,sizeof(H5O_fill_t));
if(H5P_get(old_plist, H5D_CRT_FILL_VALUE_NAME, &src_fill) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
- HDmemset(&src_efl,0,sizeof(H5O_efl_t));
if(H5P_get(old_plist, H5D_CRT_EXT_FILE_LIST_NAME, &src_efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
- HDmemset(&src_pline,0,sizeof(H5O_pline_t));
if(H5P_get(old_plist, H5D_CRT_DATA_PIPELINE_NAME, &src_pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
/* Make copies of fill value, external file list, and data pipeline */
- HDmemset(&dst_fill,0,sizeof(H5O_fill_t));
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");
}
@@ -433,7 +478,6 @@ H5D_crt_copy(hid_t new_plist_id, hid_t old_plist_id, void UNUSED *copy_data)
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");
- HDmemset(&dst_pline,0,sizeof(H5O_pline_t));
if(NULL==H5O_copy(H5O_PLINE, &src_pline, &dst_pline))
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy data pipeline");
@@ -481,18 +525,15 @@ H5D_crt_close(hid_t dcpl_id, void UNUSED *close_data)
FUNC_ENTER_NOAPI(H5D_crt_close, FAIL);
/* Check arguments */
- if (NULL == (plist = H5P_object_verify(dcpl_id,H5P_DATASET_CREATE)))
+ if (NULL == (plist = H5I_object(dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the fill value, external file list, and data pipeline properties
* from the old property list */
- HDmemset(&fill,0,sizeof(H5O_fill_t));
if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
- HDmemset(&efl,0,sizeof(H5O_efl_t));
if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
- HDmemset(&pline,0,sizeof(H5O_pline_t));
if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
@@ -540,7 +581,7 @@ H5D_xfer_create(hid_t dxpl_id, void UNUSED *create_data)
FUNC_ENTER_NOAPI(H5D_xfer_create, FAIL);
/* Check arguments */
- if (NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
/* Get the driver information */
@@ -634,7 +675,7 @@ H5D_xfer_close(hid_t dxpl_id, void UNUSED *close_data)
FUNC_ENTER_NOAPI(H5D_xfer_close, FAIL);
/* Check arguments */
- if (NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id)<0)
@@ -717,8 +758,9 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
if(H5P_DEFAULT == plist_id)
plist_id = H5P_DATASET_CREATE_DEFAULT;
- if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list");
+ else
+ if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list");
/* build and open the new dataset */
if (NULL == (new_dset = H5D_create(loc, name, type, space, plist_id)))
@@ -728,6 +770,10 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
if ((ret_value = H5I_register(H5I_DATASET, new_dset)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset");
+ /* Add the dataset to the list of opened objects in the file */
+ if(H5FO_insert(new_dset->ent.file,new_dset->ent.header,ret_value)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert dataset into list of open objects");
+
done:
if(ret_value<0) {
if(new_dset!=NULL)
@@ -762,7 +808,7 @@ hid_t
H5Dopen(hid_t loc_id, const char *name)
{
H5G_entry_t *loc = NULL; /*location holding the dataset */
- H5D_t *dataset = NULL; /*the dataset */
+ H5G_entry_t ent; /*dataset symbol table entry */
hid_t ret_value;
FUNC_ENTER_API(H5Dopen, FAIL);
@@ -774,20 +820,15 @@ H5Dopen(hid_t loc_id, const char *name)
if (!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
- /* Find the dataset */
- if (NULL == (dataset = H5D_open(loc, name)))
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "dataset not found");
-
- /* Create an atom for the dataset */
- if ((ret_value = H5I_register(H5I_DATASET, dataset)) < 0)
+ /* Find the dataset object */
+ if (H5G_find(loc, name, NULL, &ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
+
+ /* Open the dataset */
+ if ((ret_value = H5D_open(&ent)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset");
done:
- if(ret_value<0) {
- if(dataset!=NULL)
- H5D_close(dataset);
- } /* end if */
-
FUNC_LEAVE(ret_value);
}
@@ -874,7 +915,7 @@ H5Dget_space(hid_t dset_id)
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
/* Read the data space message and return a data space object */
- if (NULL==(space=H5D_get_space (dset)))
+ if (NULL==(space=H5S_copy (dset->space)))
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space");
/* Create an atom */
@@ -892,42 +933,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_get_space
- *
- * Purpose: Returns the data space associated with the dataset.
- *
- * Return: Success: Ptr to a copy of the data space.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Tuesday, August 25, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-H5S_t *
-H5D_get_space(H5D_t *dset)
-{
- H5S_t *space;
- H5S_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5D_get_space, NULL);
- assert(dset);
-
- if (NULL==(space=H5S_read(&(dset->ent))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load space info from dataset header");
-
- /* Set return value */
- ret_value=space;
-
-done:
- FUNC_LEAVE(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Dget_space_status
*
* Purpose: Returns the status of data space allocation.
@@ -981,7 +986,7 @@ done:
*/
static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation)
{
- H5S_t *space=NULL; /* Dataset's dataspace */
+ H5S_t *space; /* 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 */
@@ -990,9 +995,11 @@ static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation)
FUNC_ENTER_NOINIT(H5D_get_space_status);
+ assert(dset);
+
/* Get the dataset's dataspace */
- if((space=H5D_get_space(dset))==NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get dataspace");
+ space=dset->space;
+ assert(space);
/* Get the total number of elements in dataset's dataspace */
if((total_elem=H5S_get_simple_extent_npoints(space))<0)
@@ -1022,8 +1029,6 @@ static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation)
} /* end else */
done:
- if(space)
- H5S_close(space);
FUNC_LEAVE(ret_value);
}
@@ -1247,9 +1252,9 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
/* Get the default dataset transfer property list if the user didn't provide one */
if (H5P_DEFAULT == plist_id)
plist_id= H5P_DATASET_XFER_DEFAULT;
-
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
if (!buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
@@ -1338,9 +1343,9 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
/* Get the default dataset transfer property list if the user didn't provide one */
if (H5P_DEFAULT == plist_id)
plist_id= H5P_DATASET_XFER_DEFAULT;
-
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
if (!buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
@@ -1416,8 +1421,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5D_t *
-H5D_new(hid_t dcpl_id)
+static H5D_t *
+H5D_new(hid_t dcpl_id, hbool_t creating)
{
H5P_genplist_t *plist; /* Property list created */
H5D_t *new_dset = NULL; /* New dataset object */
@@ -1425,16 +1430,31 @@ H5D_new(hid_t dcpl_id)
FUNC_ENTER_NOAPI(H5D_new, NULL);
- if (NULL==(new_dset = H5FL_ALLOC(H5D_t,1)))
+ if (NULL==(new_dset = H5FL_MALLOC(H5D_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if(H5P_DEFAULT == dcpl_id)
- dcpl_id = H5P_DATASET_CREATE_DEFAULT;
- /* Get the property list */
- if (NULL == (plist = H5P_object_verify(dcpl_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list");
+ /* If we are using the default dataset creation property list, during creation
+ * don't bother to copy it, just increment the reference count
+ */
+ if(creating && dcpl_id == H5P_DATASET_CREATE_DEFAULT) {
+ /* Copy the default dataset information */
+ HDmemcpy(new_dset,&H5D_def_dset,sizeof(H5D_t));
+
+ if(H5I_inc_ref(dcpl_id)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINC, NULL, "Can't increment default DCPL ID");
+ new_dset->dcpl_id = dcpl_id;
+ } /* end if */
+ else {
+ /* Reset the dataset information */
+ HDmemset(new_dset,0,sizeof(H5D_t));
+
+ /* Get the property list */
+ if (NULL == (plist = H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list");
+
+ new_dset->dcpl_id = H5P_copy_plist(plist);
+ } /* end else */
- new_dset->dcpl_id = H5P_copy_plist(plist);
new_dset->ent.header = HADDR_UNDEF;
/* Set return value */
@@ -1442,8 +1462,11 @@ H5D_new(hid_t dcpl_id)
done:
if(ret_value==NULL) {
- if(new_dset!=NULL)
+ if(new_dset!=NULL) {
+ if(new_dset->dcpl_id!=0)
+ H5I_dec_ref(new_dset->dcpl_id);
H5FL_FREE(H5D_t,new_dset);
+ } /* end if */
} /* end if */
FUNC_LEAVE(ret_value);
@@ -1451,7 +1474,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_update_entry_cache
+ * Function: H5D_update_entry_info
*
* Purpose: Create and fill an H5G_entry_t object for insertion into
* the group LOC.
@@ -1471,72 +1494,86 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5D_update_entry_cache(H5F_t *file, H5G_entry_t *ent, H5G_entry_t *loc,
- const char *name, const H5S_t *space,
- H5P_genplist_t *plist, H5O_layout_t *layout, H5T_t *type,
- hbool_t allocate_header, haddr_t header)
+static herr_t
+H5D_update_entry_info(H5F_t *file, H5D_t *dset, H5P_genplist_t *plist)
{
- H5O_pline_t dcpl_pline;
- H5D_alloc_time_t alloc_time;
size_t ohdr_size = H5D_MINHDR_SIZE; /* Size of dataset's object header */
+ H5G_entry_t *ent=NULL; /* Dataset's group entry */
+ H5O_layout_t *layout; /* Dataset's layout information */
+ H5T_t *type; /* Dataset's datatype */
+ H5S_t *space; /* Dataset's dataspace */
+ H5D_alloc_time_t alloc_time;/* Dataset's allocation time */
+ H5O_efl_t *efl; /* Dataset's external file list */
/* fill value variables */
H5D_fill_time_t fill_time;
- H5O_fill_t fill_prop = { NULL, 0, NULL };
+ H5O_fill_t *fill_prop; /* Pointer to dataset's fill value information */
H5O_fill_new_t fill = { NULL, 0, NULL, H5D_ALLOC_TIME_LATE, H5D_FILL_TIME_ALLOC, TRUE };
H5D_fill_value_t fill_status;
+ H5O_t *oh=NULL; /* Pointer to dataset's object header */
+
/* return code */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(H5D_update_entry_cache, FAIL);
+ FUNC_ENTER_NOAPI(H5D_update_entry_info, FAIL);
+
+ /* Sanity checking */
+ assert(file);
+ assert(dset);
+ /* Pick up former parameters */
+ ent=&dset->ent;
+ layout=&dset->layout;
+ type=dset->type;
+ space=dset->space;
+ alloc_time=dset->alloc_time;
+ efl=&dset->efl;
+
+ /* Add the dataset's raw data size to the size of the header, if the raw data will be stored as compact */
if (layout->type == H5D_COMPACT)
ohdr_size += layout->size;
- /* If TRUE, then allocate the space in the file for the header */
- if (allocate_header) {
- /* Create (open for write access) an object header */
- if (H5O_create(file, ohdr_size, ent) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to create dataset object header");
- } else {
- /*
- * Just initialize the header to the specified address and open
- * it for us
- */
- HDmemset(ent, 0, sizeof(H5G_entry_t));
+ /* Create (open for write access) an object header */
+ if (H5O_create(file, ohdr_size, ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header");
- if (H5O_init(file, ohdr_size, ent, header) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to initialize dataset object header");
- }
+ /* Get a pointer to the object header itself */
+ if((oh=H5O_protect(ent))==NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to protect dataset object header");
- /*
- * 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(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
+ /* Point at dataset's copy, to cache it for later */
+ fill_prop=&dset->fill;
+ fill_time=dset->fill_time;
- if (H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
+ /* Check if dataset has non-default creation property list */
+ if(dset->dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ /*
+ * 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(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
+ dset->fill_time=fill_time; /* Cache this for later */
- if (H5P_fill_value_defined(plist, &fill_status) < 0)
+ if(fill_time==H5D_FILL_TIME_NEVER && H5T_detect_class(type, H5T_VLEN))
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Dataset doesn't support VL datatype when fill value is not defined");
+
+ /* Get the fill value information from the property list */
+ if (H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value");
+ } /* end if */
+
+ if (H5P_is_fill_value_defined(fill_prop, &fill_status) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
if (fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED) {
- if (H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value");
-
- if (H5O_copy(H5O_FILL, &fill_prop, &fill) == NULL)
+ if (H5O_copy(H5O_FILL, fill_prop, &fill) == NULL)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to copy fill value");
- if (fill_prop.buf && fill_prop.size > 0 && H5O_fill_convert(&fill, type) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to convert fill value to dataset type");
+ if (fill_prop->buf && fill_prop->size > 0 && H5O_fill_convert(&fill, type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert fill value to dataset type");
fill.fill_defined = TRUE;
} else if (fill_status == H5D_FILL_VALUE_UNDEFINED) {
@@ -1544,8 +1581,7 @@ H5D_update_entry_cache(H5F_t *file, H5G_entry_t *ent, H5G_entry_t *loc,
fill.type = fill.buf = NULL;
fill.fill_defined = FALSE;
} else {
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
- "unable to determine if fill value is defined");
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to determine if fill value is defined");
}
fill.alloc_time = alloc_time;
@@ -1555,79 +1591,51 @@ H5D_update_entry_cache(H5F_t *file, H5G_entry_t *ent, H5G_entry_t *loc,
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to create dataset");
/* Write new fill value message */
- if (H5O_modify(ent, H5O_FILL_NEW, 0, H5O_FLAG_CONSTANT, &fill) < 0)
+ if (H5O_append(file, oh, H5O_FILL_NEW, H5O_FLAG_CONSTANT, &fill) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update fill value header message");
- H5O_reset(H5O_FILL, &fill_prop);
- if (fill.buf && H5O_copy(H5O_FILL, &fill, &fill_prop) == NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL,"unable to copy fill value");
+ /* If there is valid information for the old fill value struct, update it */
+ if (fill.buf) {
+ /* Clear any previous values */
+ H5O_reset(H5O_FILL, fill_prop);
- H5O_reset(H5O_FILL_NEW, &fill);
+ /* Copy new fill value information to old fill value struct */
+ if(H5O_copy(H5O_FILL, &fill, fill_prop) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL,"unable to copy fill value");
- /* Write old fill value */
- if (fill_prop.buf && H5O_modify(ent, H5O_FILL, 0, H5O_FLAG_CONSTANT, &fill_prop) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update fill value header message");
+ /* Write old fill value */
+ if (fill_prop->buf && H5O_append(file, oh, H5O_FILL, H5O_FLAG_CONSTANT, fill_prop) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update fill value header message");
- if (H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value");
+ /* Update dataset creation property */
+ if (H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value");
+ } /* end if */
/* Update the type and space header messages */
- if (H5O_modify(ent, H5O_DTYPE, 0, H5O_FLAG_CONSTANT | H5O_FLAG_SHARED, type) < 0 ||
- H5S_modify(ent, space) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update type or space header messages");
+ if (H5O_append(file, oh, H5O_DTYPE, H5O_FLAG_CONSTANT | H5O_FLAG_SHARED, type) < 0 ||
+ H5S_append(file, oh, space) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update type or space header messages");
- /* Update the filters message */
- if (H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve pipeline filter");
-
- if (dcpl_pline.nfilters > 0 &&
- H5O_modify(ent, H5O_PLINE, 0, H5O_FLAG_CONSTANT, &dcpl_pline) < 0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message");
-
- /* Add a modification time message. */
- if (H5O_touch(ent, TRUE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update modification time message");
-
- /* Give the dataset a name */
- if (H5G_insert(loc, name, ent) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to name dataset");
+ /* Update the filters message, if this is a chunked dataset */
+ if(layout->type==H5D_CHUNKED) {
+ H5O_pline_t pline; /* Chunked data I/O pipeline info */
-done:
- FUNC_LEAVE(ret_value);
-}
+ if (H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve pipeline filter");
-
-/*-------------------------------------------------------------------------
- * Function: H5D_update_external_storage_cache
- *
- * Purpose: Update the external cache if the dataset uses external
- * files.
- *
- * This code was originally found at the end of H5D_create()
- * but was placed here for general use.
- *
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Errors:
- *
- * Programmer: Bill Wendling
- * Thursday, October 31, 2002
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
- H5O_efl_t *efl, H5O_layout_t *layout)
-{
- herr_t ret_value = SUCCEED;
+ if (pline.nfilters > 0 &&
+ H5O_append(file, oh, H5O_PLINE, H5O_FLAG_CONSTANT, &pline) < 0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message");
+ } /* end if */
- FUNC_ENTER_NOAPI(H5D_update_external_storage_cache, FAIL);
+ /*
+ * Allocate storage if space allocate time is early; otherwise delay
+ * allocation until later.
+ */
+ if (alloc_time == H5D_ALLOC_TIME_EARLY)
+ if (H5D_alloc_storage(file, dset, H5D_ALLOC_CREATE, FALSE, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage");
/* Update external storage message */
if (efl->nused > 0) {
@@ -1639,13 +1647,11 @@ H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
if (H5HL_create(file, heap_size, &efl->heap_addr/*out*/) < 0 ||
H5HL_insert(file, efl->heap_addr, 1, "") == (size_t)(-1))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to create external file list name heap");
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create external file list name heap");
for (i = 0; i < efl->nused; ++i) {
size_t offset = H5HL_insert(file, efl->heap_addr,
- HDstrlen(efl->slot[i].name) + 1,
- efl->slot[i].name);
+ HDstrlen(efl->slot[i].name) + 1, efl->slot[i].name);
assert(0 == efl->slot[i].name_offset);
@@ -1655,16 +1661,26 @@ H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
efl->slot[i].name_offset = offset;
}
- if (H5O_modify(ent, H5O_EFL, 0, H5O_FLAG_CONSTANT, efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to update external file list message");
+ if (H5O_append(file, oh, H5O_EFL, H5O_FLAG_CONSTANT, efl) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update external file list message");
}
/* Update layout message */
- if (H5D_COMPACT != layout->type && H5O_modify(ent, H5O_LAYOUT, 0, 0, layout) < 0)
+ /* (Don't make layout message constant yet, since space may not be allocated) */
+ /* Note: this is relying on H5D_alloc_storage not calling H5O_modify during dataset creation */
+ if (H5D_COMPACT != layout->type && H5O_append(file, oh, H5O_LAYOUT, 0, layout) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout");
+ /* Add a modification time message. */
+ if (H5O_touch_oh(file, oh, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message");
+
done:
+ /* Release pointer to object header itself */
+ if(ent!=NULL && oh!=NULL)
+ if(H5O_unprotect(ent,oh)<0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header");
+
FUNC_LEAVE(ret_value);
}
@@ -1726,7 +1742,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5D_t *
+static H5D_t *
H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
const H5S_t *space, hid_t dcpl_id)
{
@@ -1736,16 +1752,10 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
hsize_t comp_data_size;
unsigned u;
hsize_t max_dim[H5O_LAYOUT_NDIMS]={0};
- H5O_efl_t efl;
- H5F_t *f = NULL;
- H5O_pline_t dcpl_pline;
- H5D_layout_t dcpl_layout;
+ H5F_t *file;
int chunk_ndims = 0;
hsize_t chunk_size[32]={0};
- H5D_alloc_time_t alloc_time;
- H5D_fill_time_t fill_time;
- H5P_genplist_t *plist; /* Property list */
- H5P_genplist_t *new_plist; /* New Property list */
+ H5P_genplist_t *new_plist=NULL; /* New Property list */
FUNC_ENTER_NOAPI(H5D_create, NULL);
@@ -1755,97 +1765,105 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
assert (type);
assert (space);
- /* Get property list object */
- if (NULL == (plist = H5P_object_verify(dcpl_id,H5P_DATASET_CREATE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list");
-
- if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter");
- if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &dcpl_layout) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
- if(dcpl_pline.nfilters > 0 && H5D_CHUNKED != dcpl_layout)
- HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
-
- /* Check if the alloc_time is the default and set it accordingly */
- if(alloc_time==H5D_ALLOC_TIME_DEFAULT) {
- switch(dcpl_layout) {
- case H5D_COMPACT:
- alloc_time=H5D_ALLOC_TIME_EARLY;
- break;
-
- case H5D_CONTIGUOUS:
- alloc_time=H5D_ALLOC_TIME_LATE;
- break;
-
- case H5D_CHUNKED:
- alloc_time=H5D_ALLOC_TIME_INCR;
- break;
-
- default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
- } /* end switch */
- } /* end if */
-
- /* Don't allow compact datasets to allocate space later */
- if(dcpl_layout==H5D_COMPACT && alloc_time!=H5D_ALLOC_TIME_EARLY)
- HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "compact dataset doesn't support late space allocation");
-
- /* What file is the dataset being added to? */
- if (NULL==(f=H5G_insertion_file(loc, name)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to locate insertion point");
-
- /* If MPIO or MPIPOSIX is used, no filter support yet. */
- if((IS_H5FD_MPIO(f) || IS_H5FD_MPIPOSIX(f)) && dcpl_pline.nfilters > 0)
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "Parallel I/O does not support filters yet");
-
- /* Check if this dataset is going into a parallel file and set space allocation time */
- if(IS_H5FD_MPIO(f) || IS_H5FD_MPIPOSIX(f))
- alloc_time=H5D_ALLOC_TIME_EARLY;
-
- if(H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve fill time");
-
- if(fill_time==H5D_FILL_TIME_NEVER && H5T_detect_class(type, H5T_VLEN))
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "Dataset doesn't support VL datatype when fill value is not defined");
-
- /* Initialize the dataset object */
- if(NULL == (new_dset = H5D_new(dcpl_id)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
/* Check if the datatype is "sensible" for use in a dataset */
if(H5T_is_sensible(type)!=TRUE)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "datatype is not sensible");
+ /* Initialize the dataset object */
+ if(NULL == (new_dset = H5D_new(dcpl_id,TRUE)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
/* Copy datatype for dataset */
if((new_dset->type = H5T_copy(type, H5T_COPY_ALL))==NULL)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy datatype");
+ /* What file is the dataset being added to? */
+ if (NULL==(file=H5G_insertion_file(loc, name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to locate insertion point");
+
/* Mark any VL datatypes as being on disk now */
- if (H5T_vlen_mark(new_dset->type, f, H5T_VLEN_DISK)<0)
+ if (H5T_vlen_mark(new_dset->type, file, H5T_VLEN_DISK)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
- /* Get new dataset's property list object */
- if (NULL == (new_plist = H5I_object(new_dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list");
+ /* Copy dataspace for dataset */
+ if((new_dset->space = H5S_copy(space))==NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy dataspace");
+
+ /* Set the dataset's dataspace to 'all' selection */
+ if(H5S_select_all(new_dset->space,1)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection");
+
+ /* Check if the dataset has a non-default DCPL & get important values, if so */
+ if(new_dset->dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ H5D_layout_t dcpl_layout; /* Dataset's layout information */
+ H5O_pline_t dcpl_pline; /* Dataset's I/O pipeline information */
+ H5D_alloc_time_t alloc_time; /* Dataset's allocation time */
+
+ /* Get new dataset's property list object */
+ if (NULL == (new_plist = H5I_object(new_dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list");
+
+ if(H5P_get(new_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter");
+ if(H5P_get(new_plist, H5D_CRT_LAYOUT_NAME, &dcpl_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+ if(dcpl_pline.nfilters > 0 && H5D_CHUNKED != dcpl_layout)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout");
+ if(H5P_get(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
+
+ /* Check if the alloc_time is the default and set it accordingly */
+ if(alloc_time==H5D_ALLOC_TIME_DEFAULT) {
+ switch(dcpl_layout) {
+ case H5D_COMPACT:
+ alloc_time=H5D_ALLOC_TIME_EARLY;
+ break;
+
+ case H5D_CONTIGUOUS:
+ alloc_time=H5D_ALLOC_TIME_LATE;
+ break;
+
+ case H5D_CHUNKED:
+ alloc_time=H5D_ALLOC_TIME_INCR;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
+ } /* end switch */
+ } /* end if */
- /* Set the alloc_time for the dataset, in case the default was used */
- if(H5P_set(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set allocation time");
+ /* Don't allow compact datasets to allocate space later */
+ if(dcpl_layout==H5D_COMPACT && alloc_time!=H5D_ALLOC_TIME_EARLY)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "compact dataset doesn't support late space allocation");
- if(H5P_get(new_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+ /* Set the alloc_time for the dataset, in case the default was used */
+ new_dset->alloc_time=alloc_time;
+
+ /* If MPIO or MPIPOSIX is used, no filter support yet. */
+ if((IS_H5FD_MPIO(file) || IS_H5FD_MPIPOSIX(file)) && dcpl_pline.nfilters > 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "Parallel I/O does not support filters yet");
+
+ /* Chunked datasets are non-default, so retrieve their info here */
+ if(H5P_get(new_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
- if(H5P_get(new_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list");
+ /* Get the dataset's external file list information */
+ if(H5P_get(new_plist, H5D_CRT_EXT_FILE_LIST_NAME, &new_dset->efl) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list");
- /* Total raw data size */
- if(H5P_get(new_plist, H5D_CRT_LAYOUT_NAME, &(new_dset->layout.type)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
- new_dset->layout.ndims = H5S_get_simple_extent_ndims(space) + 1;
+ /* Get the dataset's data storage method */
+ if(H5P_get(new_plist, H5D_CRT_LAYOUT_NAME, &(new_dset->layout.type)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve layout");
+ } /* end if */
+
+ /* Check if this dataset is going into a parallel file and set space allocation time */
+ if(IS_H5FD_MPIO(file) || IS_H5FD_MPIPOSIX(file))
+ new_dset->alloc_time=H5D_ALLOC_TIME_EARLY;
+
+ /* Set up layout information */
+ new_dset->layout.ndims = H5S_get_simple_extent_ndims(new_dset->space) + 1;
assert((unsigned)(new_dset->layout.ndims) <= NELMTS(new_dset->layout.dim));
- new_dset->layout.dim[new_dset->layout.ndims-1] = H5T_get_size(new_dset->type);
+ new_dset->layout.dim[new_dset->layout.ndims-1] = H5T_get_size(new_dset->type);
new_dset->layout.addr = HADDR_UNDEF; /* Initialize to no address */
switch (new_dset->layout.type) {
@@ -1855,15 +1873,15 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
* Also, only the slowest varying dimension of a simple data space
* can be extendible.
*/
- if ((ndims=H5S_get_simple_extent_dims(space, new_dset->layout.dim, max_dim))<0)
+ if ((ndims=H5S_get_simple_extent_dims(new_dset->space, new_dset->layout.dim, max_dim))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize contiguous storage");
for (i=1; i<ndims; i++) {
if (max_dim[i]>new_dset->layout.dim[i])
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "only the first dimension can be extendible");
}
- if (efl.nused>0) {
- hsize_t max_points = H5S_get_npoints_max (space);
- hsize_t max_storage = H5O_efl_total_size (&efl);
+ if (new_dset->efl.nused>0) {
+ hsize_t max_points = H5S_get_npoints_max (new_dset->space);
+ hsize_t max_storage = H5O_efl_total_size (&new_dset->efl);
if (H5S_UNLIMITED==max_points) {
if (H5O_EFL_UNLIMITED!=max_storage)
@@ -1883,9 +1901,9 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
* Chunked storage allows any type of data space extension, so we
* don't even bother checking.
*/
- if(chunk_ndims != H5S_get_simple_extent_ndims(space))
+ if(chunk_ndims != H5S_get_simple_extent_ndims(new_dset->space))
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "dimensionality of chunks doesn't match the data space");
- if (efl.nused>0)
+ if (new_dset->efl.nused>0)
HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, NULL, "external storage not supported with chunked layout");
/*
@@ -1895,7 +1913,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
if(H5P_get(new_plist, H5D_CRT_CHUNK_SIZE_NAME, chunk_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve chunk size");
- if (H5S_get_simple_extent_dims(space, NULL, max_dim)<0)
+ if (H5S_get_simple_extent_dims(new_dset->space, NULL, max_dim)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to query maximum dimensions");
for (u=0; u<new_dset->layout.ndims-1; u++) {
if(max_dim[u] != H5S_UNLIMITED && max_dim[u] < chunk_size[u])
@@ -1917,7 +1935,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
/* Verify data size is smaller than maximum header message size
* (64KB) minus other layout message fields.
*/
- comp_data_size=H5O_MAX_SIZE-H5O_layout_meta_size(f, &(new_dset->layout));
+ comp_data_size=H5O_MAX_SIZE-H5O_layout_meta_size(file, &(new_dset->layout));
if(new_dset->layout.size > comp_data_size)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "compact dataset size is bigger than header message maximum size");
if ((ndims=H5S_get_simple_extent_dims(space, new_dset->layout.dim, max_dim))<0)
@@ -1931,38 +1949,32 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
} /* end switch */
/*
- * Update the entry cache. That is, create and add a new
- * "H5G_entry_t" object to the group this dataset is being initially
- * created in.
+ * Update the dataset's entry info.
*/
- if (H5D_update_entry_cache(f, &new_dset->ent, loc, name, space, new_plist,
- &new_dset->layout, new_dset->type, TRUE, (haddr_t)0) != SUCCEED)
+ if (H5D_update_entry_info(file, new_dset, new_plist) != SUCCEED)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the metadata cache");
- /*
- * Allocate storage if space allocate time is early; otherwise delay
- * allocation until later.
+ /*
+ * Give the dataset a name. That is, create and add a new
+ * "H5G_entry_t" object to the group this dataset is being initially
+ * created in.
*/
- if (H5P_get(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
-
- if (alloc_time == H5D_ALLOC_TIME_EARLY)
- if (H5D_alloc_storage(f, new_dset, H5D_ALLOC_CREATE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage");
-
- /* Update the external storage cache if this is an external object */
- if (H5D_update_external_storage_cache(f, &new_dset->ent, &efl, &new_dset->layout) != SUCCEED)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the external metadata cache");
+ if (H5G_insert(loc, name, &new_dset->ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to name dataset");
/* Success */
ret_value = new_dset;
done:
if (!ret_value && new_dset) {
+ if (new_dset->space)
+ H5S_close(new_dset->space);
if (new_dset->type)
H5T_close(new_dset->type);
if (H5F_addr_defined(new_dset->ent.header))
H5O_close(&(new_dset->ent));
+ if(new_dset->dcpl_id!=0)
+ H5I_dec_ref(new_dset->dcpl_id);
new_dset->ent.file = NULL;
H5FL_FREE(H5D_t,new_dset);
}
@@ -2024,53 +2036,59 @@ done:
*-------------------------------------------------------------------------
* Function: H5D_open
*
- * Purpose: Finds a dataset named NAME in file F and builds a descriptor
- * for it, opening it for access.
- *
- * Return: Success: Pointer to a new dataset descriptor.
+ * Purpose: Checks if dataset is already open, or opens a dataset for
+ * access.
*
- * Failure: NULL
+ * Return: Success: Dataset ID
+ * Failure: FAIL
*
* Errors:
*
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
+ * Programmer: Quincey Koziol
+ * Friday, December 20, 2002
*
* Modifications:
- * Robb Matzke, 9 Jun 1998
- * The data space message is no longer cached in the dataset struct.
- *
- * Quincey Koziol, 12 Oct 1998
- * Moved guts of function into H5D_open_oid
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
*
*-------------------------------------------------------------------------
*/
-H5D_t *
-H5D_open(H5G_entry_t *loc, const char *name)
+hid_t
+H5D_open(H5G_entry_t *ent)
{
- H5D_t *dataset = NULL; /*the dataset which was found */
- H5D_t *ret_value = NULL; /*return value */
- H5G_entry_t ent; /*dataset symbol table entry */
+ hid_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_open, NULL);
/* check args */
- assert (loc);
- assert (name && *name);
+ assert (ent);
- /* Find the dataset object */
- if (H5G_find(loc, name, NULL, &ent) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found");
+ /* Check if dataset was already open */
+ if((ret_value=H5FO_opened(ent->file,ent->header))<0) {
+ H5D_t *dataset; /*the dataset which was found */
- /* Open the dataset object */
- if ((dataset=H5D_open_oid(&ent)) ==NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found");
+ H5E_clear();
- /* Success */
- ret_value = dataset;
+ /* Open the dataset object */
+ if ((dataset=H5D_open_oid(ent)) ==NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
+
+ /* Create an atom for the dataset */
+ if ((ret_value = H5I_register(H5I_DATASET, dataset)) < 0) {
+ H5D_close(dataset);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset");
+ } /* end if */
+
+ /* Add the dataset to the list of opened objects in the file */
+ if(H5FO_insert(ent->file,ent->header,ret_value)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert dataset into list of open objects");
+ } /* end if */
+ else {
+ /* Dataset is already open, increment the reference count on the ID */
+ if(H5I_inc_ref(ret_value)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, FAIL, "Can't increment dataset ID");
+
+ /* Release the dataset entry we located earlier */
+ H5G_free_ent_name(ent);
+ } /* end else */
done:
FUNC_LEAVE(ret_value);
@@ -2104,15 +2122,14 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5D_t *
+static H5D_t *
H5D_open_oid(H5G_entry_t *ent)
{
H5D_t *dataset = NULL; /*new dataset struct */
H5D_t *ret_value = NULL; /*return value */
H5O_fill_new_t fill = {NULL, 0, NULL, H5D_ALLOC_TIME_LATE, H5D_FILL_TIME_ALLOC, TRUE};
- H5O_fill_t fill_prop = {NULL, 0, NULL};
+ H5O_fill_t *fill_prop; /* Pointer to dataset's fill value area */
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 */
@@ -2123,7 +2140,7 @@ H5D_open_oid(H5G_entry_t *ent)
assert (ent);
/* Allocate the dataset structure */
- if(NULL==(dataset = H5D_new(H5P_DEFAULT)))
+ if(NULL==(dataset = H5D_new(H5P_DATASET_CREATE_DEFAULT,FALSE)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Shallow copy (take ownership) of the group entry object */
@@ -2137,12 +2154,14 @@ H5D_open_oid(H5G_entry_t *ent)
if (NULL==(dataset->type=H5O_read(&(dataset->ent), H5O_DTYPE, 0, NULL)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load type info from dataset header");
+ if (NULL==(dataset->space=H5S_read(&(dataset->ent))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load space info from dataset header");
+
/* Get dataset creation property list object */
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 filters message */
- HDmemset(&pline,0,sizeof(H5O_pline_t));
if(NULL == H5O_read(&(dataset->ent), H5O_PLINE, 0, &pline)) {
H5E_clear();
HDmemset(&pline, 0, sizeof(pline));
@@ -2195,10 +2214,13 @@ H5D_open_oid(H5G_entry_t *ent)
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
} /* end switch */
+ /* Point at dataset's copy, to cache it for later */
+ fill_prop=&dataset->fill;
+
/* Retrieve & release the previous fill-value settings */
- if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
+ 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);
+ H5O_reset(H5O_FILL, fill_prop);
/* Get the new fill value message */
if(NULL == H5O_read(&(dataset->ent), H5O_FILL_NEW, 0, &fill)) {
@@ -2224,35 +2246,37 @@ H5D_open_oid(H5G_entry_t *ent)
} /* end switch */
} /* end if */
if(fill.fill_defined) {
- if(NULL==H5O_copy(H5O_FILL, &fill, &fill_prop))
+ 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)) {
+ if(NULL == H5O_read(&(dataset->ent), H5O_FILL, 0, fill_prop)) {
H5E_clear();
- HDmemset(&fill_prop, 0, sizeof(fill_prop));
+ HDmemset(fill_prop, 0, sizeof(H5O_fill_t));
}
- if(fill_prop.size == 0) {
- fill_prop.type = fill_prop.buf = NULL;
- fill_prop.size = (size_t)-1;
+ 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)
+ /* Set revised 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");
+ dataset->alloc_time=fill.alloc_time; /* Cache this for later */
if(H5P_set(plist, H5D_CRT_ALLOC_TIME_NAME, &fill.alloc_time) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value");
+ dataset->fill_time=fill.fill_time; /* Cache this for later */
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 external file list message, which might not exist. Space is
* also undefined when space allocate time is H5D_ALLOC_TIME_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))
- if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
+ HDmemset(&dataset->efl,0,sizeof(H5O_efl_t));
+ if(NULL != H5O_read(&(dataset->ent), H5O_EFL, 0, &dataset->efl))
+ if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &dataset->efl) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set external file list");
}
/*
@@ -2263,7 +2287,7 @@ H5D_open_oid(H5G_entry_t *ent)
if ((H5F_get_intent(dataset->ent.file) & H5F_ACC_RDWR)
&& (dataset->layout.type!=H5D_COMPACT && dataset->layout.addr==HADDR_UNDEF)
&& (IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file))) {
- if (H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_OPEN)<0)
+ if (H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_OPEN, TRUE, FALSE)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize file storage");
}
@@ -2274,6 +2298,8 @@ done:
if (ret_value==NULL && dataset) {
if (H5F_addr_defined(dataset->ent.header))
H5O_close(&(dataset->ent));
+ if (dataset->space)
+ H5S_close(dataset->space);
if (dataset->type)
H5T_close(dataset->type);
dataset->ent.file = NULL;
@@ -2317,19 +2343,23 @@ H5D_close(H5D_t *dataset)
assert(dataset && dataset->ent.file);
/*
- * Release data type and creation property list -- there isn't much we
- * can do if one of these fails, so we just continue.
+ * Release datatype, dataspace and creation property list -- there isn't
+ * much we can do if one of these fails, so we just continue.
*/
- free_failed = (H5T_close(dataset->type) < 0 ||
+ free_failed=(H5T_close(dataset->type)<0 || H5S_close(dataset->space)<0 ||
H5I_dec_ref(dataset->dcpl_id) < 0);
/* Update header message of layout for compact dataset. */
if(dataset->layout.type==H5D_COMPACT && dataset->layout.dirty) {
- if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, &(dataset->layout))<0)
+ if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, 1, &(dataset->layout))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
dataset->layout.dirty = FALSE;
} /* end if */
+ /* Remove the dataset from the list of opened objects in the file */
+ if(H5FO_delete(dataset->ent.file,dataset->ent.header)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't remove dataset from list of open objects");
+
/* Close the dataset object */
H5O_close(&(dataset->ent));
@@ -2400,7 +2430,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static 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*/)
{
@@ -2413,8 +2443,11 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
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*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
herr_t ret_value = SUCCEED; /*return value */
herr_t status; /*function return status*/
size_t src_type_size; /*size of source type */
@@ -2422,7 +2455,6 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
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=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
@@ -2432,10 +2464,6 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#ifdef H5S_DEBUG
H5_timer_t timer;
#endif
- H5O_efl_t efl; /* External File List info */
- H5O_fill_t fill; /* Fill value info */
- 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; /* Data transfer property list */
H5P_genplist_t *dc_plist; /* Dataset creation roperty list */
unsigned sconv_flags=0; /* Flags for the space conversion */
@@ -2447,24 +2475,16 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
assert(mem_type);
assert(buf);
- /* Initialize these before any errors can occur */
- HDmemset(&mem_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&bkg_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&file_iter,0,sizeof(H5S_sel_iter_t));
-
/* Get the dataset's creation property list */
if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (dx_plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if (!file_space) {
- if (NULL==(free_this_space=H5S_read (&(dataset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
- file_space = free_this_space;
- } /* end if */
+ if (!file_space)
+ file_space = dataset->space;
if (!mem_space)
mem_space = file_space;
nelmts = (*mem_space->select.get_npoints)(mem_space);
@@ -2500,15 +2520,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes");
/* Retrieve dataset properties */
- if(H5P_fill_value_defined(dc_plist, &fill_status)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "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 time");
- 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");
+ /* <none needed in the general case> */
/* If space hasn't been allocated and not using external storage,
* return fill value to buffer if fill time is upon allocation, or
@@ -2516,8 +2528,20 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* fill time is NEVER, there is no way to tell whether part of data
* has been overwritten. So just proceed in reading.
*/
- if(nelmts > 0 && efl.nused==0 && dataset->layout.type!=H5D_COMPACT
+ if(nelmts > 0 && dataset->efl.nused==0 && dataset->layout.type!=H5D_COMPACT
&& dataset->layout.addr==HADDR_UNDEF) {
+ H5O_fill_t fill; /* Fill value info */
+ 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 */
+
+ /* Retrieve dataset's fill-value properties */
+ if(H5P_fill_value_defined(dc_plist, &fill_status)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "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 time");
/* Should be impossible, but check anyway... */
if(fill_status == H5D_FILL_VALUE_UNDEFINED && fill_time == H5D_FILL_TIME_ALLOC)
@@ -2581,10 +2605,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
/* Sanity check dataset, then read it */
- assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused>0 || dataset->layout.type==H5D_COMPACT);
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 || dataset->layout.type==H5D_COMPACT);
status = (sconv->read)(dataset->ent.file, &(dataset->layout),
- dc_plist, H5T_get_size(dataset->type),
- file_space, mem_space, dxpl_id, buf/*out*/);
+ dc_plist, &(dataset->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);
@@ -2636,10 +2660,13 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
/* Figure out the strip mine size. */
if ((*file_space->select.iter_init)(file_space, src_type_size, &file_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
if ((*mem_space->select.iter_init)(mem_space, dst_type_size, &mem_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
if ((*mem_space->select.iter_init)(mem_space, dst_type_size, &bkg_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
/* Sanity check elements in temporary buffer */
if (request_nelmts<=0)
@@ -2662,13 +2689,13 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
} /* end else */
if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_ALLOC(type_conv,target_size,0))==NULL)
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
} /* end if */
if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
/* Allocate background buffer */
H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
- if((bkg_buf=H5FL_BLK_ALLOC(type_conv,(size_t)(request_nelmts*dst_type_size),0))==NULL)
+ if((bkg_buf=H5FL_BLK_MALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
} /* end if */
@@ -2687,9 +2714,9 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
/* Sanity check that space is allocated, then read data from it */
- assert(dataset->layout.addr!=HADDR_UNDEF || efl.nused > 0);
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused > 0);
n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
- dc_plist, src_type_size, file_space,
+ dc_plist, &(dataset->efl), src_type_size, file_space,
&file_iter, smine_nelmts, dxpl_id, tconv_buf/*out*/);
#ifdef H5S_DEBUG
@@ -2753,9 +2780,12 @@ done:
} /* end if */
#endif /*H5_HAVE_PARALLEL*/
/* Release selection iterators */
- (*file_space->select.iter_release)(&file_iter);
- (*mem_space->select.iter_release)(&mem_iter);
- (*mem_space->select.iter_release)(&bkg_iter);
+ if(file_iter_init)
+ (*file_space->select.iter_release)(&file_iter);
+ if(mem_iter_init)
+ (*mem_space->select.iter_release)(&mem_iter);
+ if(bkg_iter_init)
+ (*mem_space->select.iter_release)(&bkg_iter);
if (src_id >= 0)
H5I_dec_ref(src_id);
@@ -2766,8 +2796,6 @@ done:
H5FL_BLK_FREE(type_conv,tconv_buf);
if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
H5FL_BLK_FREE(type_conv,bkg_buf);
- if (free_this_space)
- H5S_close(free_this_space);
FUNC_LEAVE(ret_value);
} /* end H5D_read() */
@@ -2816,7 +2844,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static 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)
{
@@ -2829,8 +2857,11 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
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*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
herr_t ret_value = SUCCEED; /*return value */
herr_t status; /*function return status*/
size_t src_type_size; /*size of source type */
@@ -2838,7 +2869,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
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=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
@@ -2848,10 +2878,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#ifdef H5S_DEBUG
H5_timer_t timer;
#endif
- H5O_efl_t efl; /* External File List info */
- H5O_fill_t fill; /* Fill value info */
- H5D_fill_time_t fill_time; /* When to write the fill values */
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
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 */
@@ -2863,24 +2889,16 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
assert(mem_type);
assert(buf);
- /* Initialize these before any errors can occur */
- HDmemset(&mem_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&bkg_iter,0,sizeof(H5S_sel_iter_t));
- HDmemset(&file_iter,0,sizeof(H5S_sel_iter_t));
-
/* Get the dataset's creation property list */
if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
/* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if (NULL == (dx_plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if (!file_space) {
- if (NULL==(free_this_space=H5S_read (&(dataset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
- file_space = free_this_space;
- } /* end if */
+ if (!file_space)
+ file_space = dataset->space;
if (!mem_space)
mem_space = file_space;
nelmts = (*mem_space->select.get_npoints)(mem_space);
@@ -2941,20 +2959,19 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_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_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 time");
- 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(H5P_get(dc_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
+ /* <none needed currently> */
/* Allocate data space and initialize it if it hasn't been. */
if(nelmts > 0 && dataset->layout.type!=H5D_COMPACT &&
dataset->layout.addr==HADDR_UNDEF) {
+ hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
+
+ /* Get the number of elements in file dataset's dataspace */
+ if((file_nelmts=H5S_get_simple_extent_npoints(file_space))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset");
+
/* Allocate storage */
- if(H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_WRITE)<0)
+ if(H5D_alloc_storage(dataset->ent.file, dataset,H5D_ALLOC_WRITE, TRUE, (hbool_t)((hsize_t)file_nelmts==nelmts ? TRUE : FALSE))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage");
} /* end if */
@@ -3005,8 +3022,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
status = (sconv->write)(dataset->ent.file, &(dataset->layout),
- dc_plist, H5T_get_size(dataset->type),
- file_space, mem_space, dxpl_id, buf);
+ dc_plist, &(dataset->efl), H5T_get_size(dataset->type),
+ file_space, mem_space, dxpl_id, buf);
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[0].write_timer), &timer);
sconv->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type);
@@ -3061,10 +3078,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
/* Figure out the strip mine size. */
if ((*file_space->select.iter_init)(file_space, dst_type_size, &file_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
if ((*mem_space->select.iter_init)(mem_space, src_type_size, &mem_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
if ((*file_space->select.iter_init)(file_space, dst_type_size, &bkg_iter)<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
/*
* Get a temporary buffer for type conversion unless the app has already
@@ -3087,13 +3107,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
} /* end else */
if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_ALLOC(type_conv,target_size,0))==NULL)
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
} /* end if */
if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
/* Allocate background buffer */
H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
- if((bkg_buf=H5FL_BLK_ALLOC(type_conv,(size_t)(request_nelmts*dst_type_size),1))==NULL)
+ if((bkg_buf=H5FL_BLK_CALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
} /* end if */
@@ -3126,9 +3146,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
- dc_plist, dst_type_size, file_space,
- &bkg_iter, smine_nelmts, dxpl_id,
- bkg_buf/*out*/);
+ dc_plist, &(dataset->efl), dst_type_size, file_space,
+ &bkg_iter, smine_nelmts, dxpl_id, bkg_buf/*out*/);
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[0].bkg_timer), &timer);
@@ -3152,9 +3171,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5_timer_begin(&timer);
#endif
status = H5S_select_fscat(dataset->ent.file, &(dataset->layout),
- dc_plist, dst_type_size,
- file_space, &file_iter, smine_nelmts,
- dxpl_id, tconv_buf);
+ dc_plist, &(dataset->efl), dst_type_size, file_space, &file_iter,
+ smine_nelmts, dxpl_id, tconv_buf);
#ifdef H5S_DEBUG
H5_timer_end(&(sconv->stats[0].scat_timer), &timer);
@@ -3186,9 +3204,12 @@ done:
} /* end if */
#endif /*H5_HAVE_PARALLEL*/
/* Release selection iterators */
- (*file_space->select.iter_release)(&file_iter);
- (*mem_space->select.iter_release)(&mem_iter);
- (*file_space->select.iter_release)(&bkg_iter);
+ if(file_iter_init)
+ (*file_space->select.iter_release)(&file_iter);
+ if(mem_iter_init)
+ (*mem_space->select.iter_release)(&mem_iter);
+ if(bkg_iter_init)
+ (*file_space->select.iter_release)(&bkg_iter);
if (src_id >= 0)
H5I_dec_ref(src_id);
@@ -3199,8 +3220,6 @@ done:
H5FL_BLK_FREE(type_conv,tconv_buf);
if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
H5FL_BLK_FREE(type_conv,bkg_buf);
- if (free_this_space)
- H5S_close(free_this_space);
FUNC_LEAVE(ret_value);
} /* end H5D_write() */
@@ -3230,8 +3249,6 @@ H5D_extend (H5D_t *dataset, const hsize_t *size)
{
int changed; /* Flag to indicate that the dataspace was successfully extended */
H5S_t *space = NULL; /* Dataset's dataspace */
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
- H5P_genplist_t *plist; /* Property list */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_extend, FAIL);
@@ -3240,12 +3257,6 @@ H5D_extend (H5D_t *dataset, const hsize_t *size)
assert (dataset);
assert (size);
- /* Get the dataset creation property list */
- if (NULL == (plist = H5I_object(dataset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
-
/*
* NOTE: Restrictions on extensions were checked when the dataset was
* created. All extensions are allowed here since none should be
@@ -3253,24 +3264,22 @@ H5D_extend (H5D_t *dataset, const hsize_t *size)
*/
/* Increase the size of the data space */
- if (NULL==(space=H5S_read (&(dataset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space info from dataset header");
+ space=dataset->space;
if ((changed=H5S_extend (space, size))<0)
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to increase size of data space");
if (changed>0){
/* Save the new dataspace in the file if necessary */
- if (H5S_modify (&(dataset->ent), space)<0)
+ if (H5S_modify (&(dataset->ent), space, TRUE)<0)
HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace");
/* Allocate space for the new parts of the dataset, if appropriate */
- if(alloc_time==H5D_ALLOC_TIME_EARLY)
- if (H5D_alloc_storage(dataset->ent.file, dataset, H5D_ALLOC_EXTEND)<0)
+ if(dataset->alloc_time==H5D_ALLOC_TIME_EARLY)
+ if (H5D_alloc_storage(dataset->ent.file, dataset, H5D_ALLOC_EXTEND, TRUE, FALSE)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value");
} /* end if */
done:
- H5S_close(space);
FUNC_LEAVE (ret_value);
}
@@ -3347,7 +3356,7 @@ H5D_typeof (H5D_t *dset)
*
*-------------------------------------------------------------------------
*/
-H5F_t *
+static H5F_t *
H5D_get_file (const H5D_t *dset)
{
/* Use FUNC_ENTER_NOINIT here to avoid performance issues */
@@ -3379,12 +3388,9 @@ H5D_get_file (const H5D_t *dset)
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
+H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc,
+ hbool_t update_time, hbool_t full_overwrite)
{
- H5P_genplist_t *plist; /* Dataset's creation property list */
- H5O_efl_t efl; /* External File List info */
- H5D_fill_time_t fill_time; /* When to write fill values */
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
struct H5O_layout_t *layout; /* The dataset's layout information */
hsize_t nbytes; /* The number of bytes in the dataset */
unsigned space_allocated=0; /* Flag to indicate that space was allocated */
@@ -3397,23 +3403,11 @@ H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
assert (f);
assert (dset);
- /* Get external file list properties */
- if (NULL == (plist = H5I_object(dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
-
/* If the data is stored in external files, don't set an address for the layout
* We assume that external storage is already
* allocated by the caller, or at least will be before I/O is performed.
*/
- if(efl.nused==0) {
- /* Get properties needed */
- if(H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
-
+ if(dset->efl.nused==0) {
/* Get a pointer to the dataset's layout information */
layout=&(dset->layout);
@@ -3441,6 +3435,11 @@ H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
/* Indicate that we allocated space */
space_allocated=1;
} /* end if */
+
+ /* If MPIO or MPIPOSIX is used, indicate that space was allocated, so the B-tree gets expanded */
+ if(IS_H5FD_MPIO(f) || IS_H5FD_MPIPOSIX(f))
+ space_allocated=1;
+
break;
case H5D_COMPACT:
@@ -3462,19 +3461,22 @@ H5D_alloc_storage (H5F_t *f, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc)
HGOTO_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
} /* end switch */
- /* If we are filling the dataset on allocation, do that now */
- if(fill_time==H5D_FILL_TIME_ALLOC
- && !(alloc_time==H5D_ALLOC_TIME_INCR && time_alloc==H5D_ALLOC_WRITE)) {
- if(H5D_init_storage(dset) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value");
- } /* end if */
+ /* Check if we actually allocated space before performing other actions */
+ if(space_allocated) {
+ /* If we are filling the dataset on allocation, do that now */
+ if(dset->fill_time==H5D_FILL_TIME_ALLOC
+ && !(dset->alloc_time==H5D_ALLOC_TIME_INCR && time_alloc==H5D_ALLOC_WRITE)) {
+ if(H5D_init_storage(dset, full_overwrite) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value");
+ } /* end if */
- /* Also update header message for layout with new address
- * (this is only for forward compatibility).
- */
- if(space_allocated && time_alloc!=H5D_ALLOC_CREATE)
- if (H5O_modify (&(dset->ent), H5O_LAYOUT, 0, H5O_FLAG_CONSTANT, &(dset->layout)) < 0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
+ /* Also update header message for layout with new address
+ * (this is only for forward compatibility).
+ */
+ if(time_alloc!=H5D_ALLOC_CREATE)
+ if (H5O_modify (&(dset->ent), H5O_LAYOUT, 0, H5O_FLAG_CONSTANT, update_time, &(dset->layout)) < 0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
+ } /* end if */
} /* end if */
done:
@@ -3504,13 +3506,11 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_init_storage(H5D_t *dset)
+H5D_init_storage(H5D_t *dset, hbool_t full_overwrite)
{
hssize_t snpoints; /* Number of points in space (for error checking) */
size_t npoints; /* Number of points in space */
- H5S_t *space = NULL; /* Dataset's dataspace */
- H5O_fill_t fill; /* Fill value information */
- H5O_efl_t efl; /* External File List info */
+ H5S_t *space; /* Dataset's dataspace */
H5P_genplist_t *plist; /* Property list */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3518,17 +3518,8 @@ H5D_init_storage(H5D_t *dset)
assert(dset);
- /* Get fill value, external file list, and data pipeline properties */
- if (NULL == (plist = H5I_object(dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
- if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
- if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve external file list");
-
/* Get the dataset's dataspace */
- if (NULL==(space=H5S_read (&(dset->ent))))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space from dataset header");
+ space=dset->space;
/* Get the number of elements in the dataset's dataspace */
snpoints = H5S_get_simple_extent_npoints(space);
@@ -3537,19 +3528,31 @@ H5D_init_storage(H5D_t *dset)
switch (dset->layout.type) {
case H5D_COMPACT:
- /* If the fill value is defined, initialize the data buffer with it */
- if(fill.buf)
- /* Initialize the cached data buffer with the fill value */
- H5V_array_fill(dset->layout.buf, fill.buf, fill.size, npoints);
- else /* If the fill value is default, zero set data buf. */
- HDmemset(dset->layout.buf, 0, dset->layout.size);
+ /* If we will be immediately overwriting the values, don't bother to clear them */
+ if(!full_overwrite) {
+ /* If the fill value is defined, initialize the data buffer with it */
+ if(dset->fill.buf)
+ /* Initialize the cached data buffer with the fill value */
+ H5V_array_fill(dset->layout.buf, dset->fill.buf, dset->fill.size, npoints);
+ else /* If the fill value is default, zero set data buf. */
+ HDmemset(dset->layout.buf, 0, dset->layout.size);
+ } /* end if */
break;
case H5D_CONTIGUOUS:
- if (H5F_contig_fill(dset->ent.file, H5P_DATASET_XFER_DEFAULT,
- &(dset->layout), plist, space, H5T_get_size(dset->type))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset");
- break;
+ /* Don't write default fill values to external files */
+ /* If we will be immediately overwriting the values, don't bother to clear them */
+ if((dset->efl.nused==0 || dset->fill.buf) && !full_overwrite) {
+ /* Get dataset's creation property list */
+ if (NULL == (plist = H5I_object(dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
+ if (H5F_contig_fill(dset->ent.file, H5P_DATASET_XFER_DEFAULT,
+ &(dset->layout), plist, &(dset->efl), space,
+ &dset->fill, H5T_get_size(dset->type))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset");
+ } /* end if */
+ break;
case H5D_CHUNKED:
/*
@@ -3561,21 +3564,22 @@ H5D_init_storage(H5D_t *dset)
int ndims;
hsize_t dim[H5O_LAYOUT_NDIMS];
+ /* Get dataset's creation property list */
+ if (NULL == (plist = H5I_object(dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
if ((ndims=H5S_get_simple_extent_dims(space, dim, NULL))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple data space info");
dim[ndims] = dset->layout.dim[ndims];
if (H5F_istore_allocate(dset->ent.file, H5P_DATASET_XFER_DEFAULT,
- &(dset->layout), dim, plist)<0)
+ &(dset->layout), dim, plist, full_overwrite)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset");
} /* end if */
break;
} /* end switch */
done:
- if (space)
- H5S_close(space);
-
FUNC_LEAVE(ret_value);
}
@@ -3638,7 +3642,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-hsize_t
+static hsize_t
H5D_get_storage_size(H5D_t *dset)
{
unsigned u; /* Index variable */
@@ -3732,7 +3736,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-haddr_t
+static haddr_t
H5D_get_offset(H5D_t *dset)
{
haddr_t ret_value;
@@ -3894,9 +3898,9 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
/* Get the default dataset transfer property list if the user didn't provide one */
if (H5P_DEFAULT == plist_id)
plist_id= H5P_DATASET_XFER_DEFAULT;
-
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
/* Call H5Diterate with args, etc. */
ret_value=H5Diterate(buf,type_id,space_id,H5T_vlen_reclaim,&plist_id);
@@ -3923,7 +3927,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-void *
+static void *
H5D_vlen_get_buf_size_alloc(size_t size, void *info)
{
H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)info;
@@ -3970,7 +3974,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, hsize_t UNUSED ndim, hssize_t *point, void *op_data)
{
H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)op_data;
@@ -4060,9 +4064,9 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't create dataspace");
/* Grab the temporary buffers required */
- if((vlen_bufsize.fl_tbuf=H5FL_BLK_ALLOC(vlen_fl_buf,1,0))==NULL)
+ if((vlen_bufsize.fl_tbuf=H5FL_BLK_MALLOC(vlen_fl_buf,1))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
- if((vlen_bufsize.vl_tbuf=H5FL_BLK_ALLOC(vlen_vl_buf,1,0))==NULL)
+ if((vlen_bufsize.vl_tbuf=H5FL_BLK_MALLOC(vlen_vl_buf,1))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
/* Get the pointer to the dataset transfer class */
@@ -4160,7 +4164,7 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t
/* Get the maximum buffer size needed and allocate it */
buf_size=MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5FL_BLK_ALLOC(type_elem,buf_size,0)) || NULL==(bkg_buf = H5FL_BLK_ALLOC(type_elem,buf_size,1)))
+ if (NULL==(tconv_buf = H5FL_BLK_MALLOC(type_elem,buf_size)) || NULL==(bkg_buf = H5FL_BLK_CALLOC(type_elem,buf_size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Copy the user's data into the buffer for conversion */
@@ -4180,7 +4184,7 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t
}
/* Perform data type conversion */
- if (H5T_convert(tpath, src_id, dst_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_DATASET_XFER_DEFAULT)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed");
/* Fill the selection in the memory buffer */
@@ -4311,7 +4315,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5D_set_extent(H5D_t *dset, const hsize_t *size)
{
hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Current dimension sizes */
@@ -4319,7 +4323,6 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
herr_t ret_value = SUCCEED; /* Return value */
H5S_t *space = NULL;
H5P_genplist_t *plist;
- H5D_alloc_time_t alloc_time; /* When to allocate raw data space */
int u;
unsigned shrink = 0; /* Flag to indicate a dimension has shrank */
unsigned expand = 0; /* Flag to indicate a dimension has grown */
@@ -4335,8 +4338,7 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
* Get the data space
*-------------------------------------------------------------------------
*/
- if(NULL == (space = H5S_read(&(dset->ent))))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data space info from dset header");
+ space = dset->space;
/*-------------------------------------------------------------------------
* Check if we are shrinking or expanding any of the dimensions
@@ -4361,23 +4363,17 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
/* Don't bother updating things, unless they've changed */
if(changed) {
- /* Get the dataset creation property list */
- if(NULL == (plist = H5I_object(dset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dset creation property list");
- if(H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
-
/*-------------------------------------------------------------------------
* Modify the dataset storage
*-------------------------------------------------------------------------
*/
/* Save the new dataspace in the file if necessary */
- if(H5S_modify(&(dset->ent), space) < 0)
+ if(H5S_modify(&(dset->ent), space, TRUE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace");
/* Allocate space for the new parts of the dataset, if appropriate */
- if(expand && alloc_time==H5D_ALLOC_TIME_EARLY)
- if(H5D_alloc_storage(dset->ent.file, dset, H5D_ALLOC_EXTEND) < 0)
+ if(expand && dset->alloc_time==H5D_ALLOC_TIME_EARLY)
+ if(H5D_alloc_storage(dset->ent.file, dset, H5D_ALLOC_EXTEND, TRUE, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset storage");
@@ -4387,6 +4383,10 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
*-------------------------------------------------------------------------
*/
if(shrink && H5D_CHUNKED == dset->layout.type) {
+ /* Get the dataset creation property list */
+ if(NULL == (plist = H5I_object(dset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dset creation property list");
+
/* Remove excess chunks */
if(H5F_istore_prune_by_extent(dset->ent.file, &dset->layout, space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to remove chunks ");
@@ -4398,8 +4398,6 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size)
} /* end if */
done:
- if(space)
- H5S_close(space);
FUNC_LEAVE(ret_value);
}
@@ -4449,7 +4447,7 @@ H5D_flush(H5F_t *f)
if(NULL==(dataset=H5I_object_verify(id_list[j], H5I_DATASET)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset object");
if(dataset->layout.type==H5D_COMPACT && dataset->layout.dirty)
- if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, &(dataset->layout))<0)
+ if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, 1, &(dataset->layout))<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message");
dataset->layout.dirty = FALSE;
}
@@ -4459,7 +4457,7 @@ done:
if(id_list!=NULL)
H5MM_xfree(id_list);
FUNC_LEAVE(ret_value);
-}
+} /* end H5D_flush() */
/*-------------------------------------------------------------------------