summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Distore.c484
-rw-r--r--test/tvltypes.c756
2 files changed, 675 insertions, 565 deletions
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 8d1d2c7..8f967bf 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -279,6 +279,9 @@ H5FL_SEQ_DEFINE_STATIC(size_t);
/* Declare a free list to manage the raw page information */
H5FL_BLK_DEFINE_STATIC(chunk_page);
+/* Declare a free list to manage blocks of type conversion data */
+H5FL_BLK_EXTERN(type_conv);
+
/*-------------------------------------------------------------------------
* Function: H5D_istore_get_shared
@@ -1470,7 +1473,7 @@ H5D_istore_lock(const H5D_io_info_t *io_info,
unsigned idx=0; /*hash index number */
hbool_t found = FALSE; /*already in cache? */
unsigned u; /*counters */
- size_t chunk_size=0; /*size of a chunk */
+ size_t chunk_size; /*size of a chunk */
void *chunk=NULL; /*the file chunk */
void *ret_value; /*return value */
@@ -1581,14 +1584,103 @@ H5D_istore_lock(const H5D_io_info_t *io_info,
if(fill_time==H5D_FILL_TIME_ALLOC ||
(fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED)) {
- if (fill && fill->buf) {
- /*
- * The chunk doesn't exist in the file. Replicate the fill
- * value throughout the chunk.
- */
- assert(0==chunk_size % fill->size);
- H5V_array_fill(chunk, fill->buf, fill->size, chunk_size/fill->size);
- } else {
+ /*
+ * The chunk doesn't exist in the file. Replicate the fill
+ * value throughout the chunk, if the fill value is defined.
+ */
+ if(fill->buf) {
+ size_t elmts_per_chunk; /* # of elements per chunk */
+
+ /* Sanity check */
+ HDassert(0 == (chunk_size % fill->size));
+ elmts_per_chunk = chunk_size / fill->size;
+
+ /* If necessary, convert fill value datatypes (which copies VL components, etc.) */
+ if(H5T_detect_class(dset->shared->type, H5T_VLEN) > 0) {
+ H5T_path_t *tpath; /* Datatype conversion path */
+ uint8_t *bkg_buf = NULL; /* Background conversion buffer */
+ H5T_t *mem_type; /* Pointer to memory datatype */
+ size_t mem_type_size, file_type_size; /* Size of datatype in memory and on disk */
+ hid_t mem_tid; /* Memory version of disk datatype */
+
+ /* Create temporary datatype for conversion operation */
+ if(NULL == (mem_type = H5T_copy(dset->shared->type, H5T_COPY_REOPEN)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy file datatype")
+ if((mem_tid = H5I_register(H5I_DATATYPE, mem_type)) < 0) {
+ H5T_close(mem_type);
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype")
+ } /* end if */
+
+ /* Retrieve sizes of memory & file datatypes */
+ mem_type_size = H5T_get_size(mem_type);
+ HDassert(mem_type_size > 0);
+ file_type_size = H5T_get_size(dset->shared->type);
+ HDassert(file_type_size == fill->size);
+
+ /* Get the datatype conversion path for this operation */
+ if(NULL == (tpath = H5T_path_find(dset->shared->type, mem_type, NULL, NULL, io_info->dxpl_id))) {
+ H5I_dec_ref(mem_tid);
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between src and dst datatypes")
+ } /* end if */
+
+ /* Allocate a background buffer, if necessary */
+ if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, (elmts_per_chunk * MAX(mem_type_size, file_type_size))))) {
+ H5I_dec_ref(mem_tid);
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ } /* end if */
+
+ /* Make a copy of the (disk-based) fill value into the chunk buffer */
+ HDmemcpy(chunk, fill->buf, file_type_size);
+
+ /* Type convert the chunk buffer, to copy any VL components */
+ if(H5T_convert(tpath, dset->shared->type_id, mem_tid, (size_t)1, (size_t)0, (size_t)0, chunk, bkg_buf, io_info->dxpl_id) < 0) {
+ if(bkg_buf)
+ H5FL_BLK_FREE(type_conv, bkg_buf);
+ H5I_dec_ref(mem_tid);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, NULL, "data type conversion failed")
+ } /* end if */
+
+ /* Replicate the fill value into the cached buffer */
+ H5V_array_fill(chunk, chunk, mem_type_size, elmts_per_chunk);
+
+ /* Get the inverse datatype conversion path for this operation */
+ if(NULL == (tpath = H5T_path_find(mem_type, dset->shared->type, NULL, NULL, io_info->dxpl_id))) {
+ if(bkg_buf)
+ H5FL_BLK_FREE(type_conv, bkg_buf);
+ H5I_dec_ref(mem_tid);
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to convert between src and dst datatypes")
+ } /* end if */
+
+ /* Allocate or reset the background buffer, if necessary */
+ if(H5T_path_bkg(tpath)) {
+ if(bkg_buf)
+ HDmemset(bkg_buf, 0, MAX(mem_type_size, file_type_size));
+ else {
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, (elmts_per_chunk * MAX(mem_type_size, file_type_size))))) {
+ H5I_dec_ref(mem_tid);
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ } /* end if */
+ } /* end else */
+ } /* end if */
+
+ /* Type convert the chunk buffer, to copy any VL components */
+ if(H5T_convert(tpath, mem_tid, dset->shared->type_id, elmts_per_chunk, (size_t)0, (size_t)0, chunk, bkg_buf, io_info->dxpl_id) < 0) {
+ if(bkg_buf)
+ H5FL_BLK_FREE(type_conv, bkg_buf);
+ H5I_dec_ref(mem_tid);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, NULL, "data type conversion failed")
+ } /* end if */
+
+ /* Release resources used */
+ if(bkg_buf)
+ H5FL_BLK_FREE(type_conv, bkg_buf);
+ H5I_dec_ref(mem_tid);
+ } /* end if */
+ else
+ /* Replicate the [non-VL] fill value into chunk */
+ H5V_array_fill(chunk, fill->buf, fill->size, elmts_per_chunk);
+ } /* end if */
+ else {
/*
* The chunk doesn't exist in the file and no fill value was
* specified. Assume all zeros.
@@ -2394,89 +2486,74 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
H5D_io_info_t io_info; /* Dataset I/O info */
H5D_storage_t store; /* Dataset storage information */
hsize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
- hsize_t chunk_size; /* Size of chunk in bytes */
- unsigned filter_mask=0; /* Filter mask for chunks that have them */
- H5O_pline_t pline; /* I/O pipeline information */
- hbool_t pline_initialized=FALSE; /* Flag to indicate that pline has valid info */
- H5O_fill_t fill; /* Fill value information */
- H5D_fill_time_t fill_time; /* When to write fill values */
+ size_t elmts_per_chunk; /* # of elements which fit in a chunk */
+ size_t orig_chunk_size; /* Original size of chunk in bytes */
+ unsigned filter_mask = 0; /* Filter mask for chunks that have them */
H5D_fill_value_t fill_status; /* The fill value status */
- unsigned should_fill=0; /* Whether fill values should be written */
- void *chunk=NULL; /* Chunk buffer for writing fill values */
+ hbool_t should_fill = FALSE; /* Whether fill values should be written */
+ void *chunk = NULL; /* Chunk buffer for writing fill values */
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
- H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */
+ H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
#ifdef H5_HAVE_PARALLEL
- MPI_Comm mpi_comm=MPI_COMM_NULL; /* MPI communicator for file */
- int mpi_rank=(-1); /* This process's rank */
+ MPI_Comm mpi_comm = MPI_COMM_NULL; /* MPI communicator for file */
+ int mpi_rank = (-1); /* This process's rank */
int mpi_code; /* MPI return code */
- unsigned blocks_written=0; /* Flag to indicate that chunk was actually written */
- unsigned using_mpi=0; /* Flag to indicate that the file is being accessed with an MPI-capable file driver */
+ hbool_t blocks_written = FALSE; /* Flag to indicate that chunk was actually written */
+ hbool_t using_mpi = FALSE; /* Flag to indicate that the file is being accessed with an MPI-capable file driver */
#endif /* H5_HAVE_PARALLEL */
- int carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
- unsigned chunk_exists; /* Flag to indicate whether a chunk exists already */
- int i; /* Local index variable */
- unsigned u; /* Local index variable */
- H5P_genplist_t *dc_plist; /* Property list */
+ hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
int space_ndims; /* Dataset's space rank */
hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Dataset's dataspace dimensions */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5T_path_t *fill_to_mem_tpath; /* Datatype conversion path for converting the fill value to the memory buffer */
+ H5T_path_t *mem_to_dset_tpath; /* Datatype conversion path for converting the memory buffer to the dataset elements */
+ uint8_t *bkg_buf = NULL; /* Background conversion buffer */
+ H5T_t *mem_type = NULL; /* Pointer to memory datatype */
+ size_t mem_type_size, file_type_size; /* Size of datatype in memory and on disk */
+ size_t elmt_size; /* Size of each element */
+ hid_t mem_tid = (-1); /* Memory version of disk datatype */
+ size_t bkg_buf_size; /* Size of background buffer */
+ hbool_t has_vlen_fill_type = FALSE; /* Whether the datatype for the fill value has a variable-length component */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_allocate, FAIL)
/* Check args */
- assert(dset && H5D_CHUNKED==dset->shared->layout.type);
- assert(dset->shared->layout.u.chunk.ndims>0 && dset->shared->layout.u.chunk.ndims<=H5O_LAYOUT_NDIMS);
- assert(H5F_addr_defined(dset->shared->layout.u.chunk.addr));
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
-
- /* Get dataset's creation property list */
- if (NULL == (dc_plist = H5I_object(dset->shared->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
-
- /* We only handle simple data spaces so far */
- if ((space_ndims=H5S_get_simple_extent_dims(dset->shared->space, space_dim, NULL))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple data space info")
+ HDassert(dset && H5D_CHUNKED == dset->shared->layout.type);
+ HDassert(dset->shared->layout.u.chunk.ndims > 0 && dset->shared->layout.u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(H5F_addr_defined(dset->shared->layout.u.chunk.addr));
+ HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
+
+ /* Retrieve the dataset dimensions */
+ if((space_ndims = H5S_get_simple_extent_dims(dset->shared->space, space_dim, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info")
space_dim[space_ndims] = dset->shared->layout.u.chunk.dim[space_ndims];
- /* Get necessary properties from dataset creation property list */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "can't get fill value")
- if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "can't get data pipeline")
- pline_initialized=TRUE;
- if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time")
-
/* Fill the DXPL cache values for later use */
- if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache)<0)
+ if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
#ifdef H5_HAVE_PARALLEL
/* Retrieve MPI parameters */
if(IS_H5FD_MPI(dset->ent.file)) {
/* Get the MPI communicator */
- if (MPI_COMM_NULL == (mpi_comm=H5F_mpi_get_comm(dset->ent.file)))
+ if(MPI_COMM_NULL == (mpi_comm = H5F_mpi_get_comm(dset->ent.file)))
HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI communicator")
/* Get the MPI rank */
- if ((mpi_rank=H5F_mpi_get_rank(dset->ent.file))<0)
+ if((mpi_rank = H5F_mpi_get_rank(dset->ent.file)) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI rank")
/* Set the MPI-capable file driver flag */
- using_mpi=1;
+ using_mpi = TRUE;
} /* end if */
#endif /* H5_HAVE_PARALLEL */
- /*
- * Setup indice to go through all chunks. (Future improvement
- * should allocate only chunks that have no file space assigned yet.
- */
- for (u=0; u<dset->shared->layout.u.chunk.ndims; u++)
- chunk_offset[u] = 0;
- chunk_size = dset->shared->layout.u.chunk.size;
+ /* Get original chunk size */
+ H5_CHECK_OVERFLOW(dset->shared->layout.u.chunk.size, hsize_t, size_t);
+ orig_chunk_size = (size_t)dset->shared->layout.u.chunk.size;
/* Check the dataset's fill-value status */
- if (H5P_is_fill_value_defined(&fill, &fill_status) < 0)
+ if(H5P_is_fill_value_defined(&dset->shared->dcpl_cache.fill, &fill_status) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined")
/* If we are filling the dataset on allocation or "if set" and
@@ -2484,141 +2561,266 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
* or if there are any pipeline filters defined,
* set the "should fill" flag
*/
- if((!full_overwrite && (fill_time==H5D_FILL_TIME_ALLOC ||
- (fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED)))
- || pline.nused>0)
- should_fill=1;
+ if((!full_overwrite && (dset->shared->dcpl_cache.fill_time == H5D_FILL_TIME_ALLOC ||
+ (dset->shared->dcpl_cache.fill_time == H5D_FILL_TIME_IFSET && fill_status == H5D_FILL_VALUE_USER_DEFINED)))
+ || dset->shared->dcpl_cache.pline.nused > 0)
+ should_fill = TRUE;
- /* Check if fill values should be written to blocks */
+ /* Check if fill values should be written to chunks */
if(should_fill) {
- /* Allocate chunk buffer for processes to use when writing fill values */
- H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t);
- if (NULL==(chunk = H5D_istore_chunk_alloc((size_t)chunk_size,&pline)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for chunk")
-
/* Fill the chunk with the proper values */
- if(fill.buf) {
- /*
- * Replicate the fill value throughout the chunk.
- */
- assert(0==chunk_size % fill.size);
- H5V_array_fill(chunk, fill.buf, fill.size, (size_t)chunk_size/fill.size);
- } else {
+ if(dset->shared->dcpl_cache.fill.buf) {
+ /* Detect whether the datatype has a VL component */
+ has_vlen_fill_type = H5T_detect_class(dset->shared->type, H5T_VLEN);
+
+ /* If necessary, convert fill value datatypes (which copies VL components, etc.) */
+ if(has_vlen_fill_type) {
+ /* Create temporary datatype for conversion operation */
+ if(NULL == (mem_type = H5T_copy(dset->shared->type, H5T_COPY_REOPEN)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype")
+ if((mem_tid = H5I_register(H5I_DATATYPE, mem_type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
+
+ /* Retrieve sizes of memory & file datatypes */
+ mem_type_size = H5T_get_size(mem_type);
+ HDassert(mem_type_size > 0);
+ file_type_size = H5T_get_size(dset->shared->type);
+ HDassert(file_type_size == dset->shared->dcpl_cache.fill.size);
+
+ /* Compute the base size for a chunk to operate on */
+ elmt_size = MAX(mem_type_size, file_type_size);
+ elmts_per_chunk = dset->shared->layout.u.chunk.size / file_type_size;
+ orig_chunk_size = elmts_per_chunk * elmt_size;
+
+ /* Allocate a chunk buffer now, if _no_ filters are used */
+ if(dset->shared->dcpl_cache.pline.nused == 0)
+ if(NULL == (chunk = H5D_istore_chunk_alloc(orig_chunk_size, &dset->shared->dcpl_cache.pline)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for chunk")
+
+ /* Get the datatype conversion path for this operation */
+ if(NULL == (fill_to_mem_tpath = H5T_path_find(dset->shared->type, mem_type, NULL, NULL, dxpl_id)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst datatypes")
+
+ /* Get the inverse datatype conversion path for this operation */
+ if(NULL == (mem_to_dset_tpath = H5T_path_find(mem_type, dset->shared->type, NULL, NULL, dxpl_id)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst datatypes")
+
+ /* Check if we need to allocate a background buffer */
+ if(H5T_path_bkg(fill_to_mem_tpath) || H5T_path_bkg(mem_to_dset_tpath)) {
+ /* Check for inverse datatype conversion needing a background buffer */
+ /* (do this first, since it needs a larger buffer) */
+ if(H5T_path_bkg(mem_to_dset_tpath))
+ bkg_buf_size = elmts_per_chunk * elmt_size;
+ else
+ bkg_buf_size = elmt_size;
+
+ /* Allocate the background buffer */
+ if(NULL == (bkg_buf = H5FL_BLK_MALLOC(type_conv, bkg_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ } /* end if */
+ } /* end if */
+ else {
+ /* Allocate chunk buffer for processes to use when writing fill values */
+ if(NULL == (chunk = H5D_istore_chunk_alloc(orig_chunk_size, &dset->shared->dcpl_cache.pline)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for chunk")
+
+ /*
+ * Replicate the fill value throughout the chunk.
+ */
+ HDassert(0 == (orig_chunk_size % dset->shared->dcpl_cache.fill.size));
+ H5V_array_fill(chunk, dset->shared->dcpl_cache.fill.buf, dset->shared->dcpl_cache.fill.size, (size_t)(orig_chunk_size / dset->shared->dcpl_cache.fill.size));
+ } /* end else */
+ } /* end if */
+ else {
+ /* Allocate chunk buffer for processes to use when writing fill values */
+ if(NULL == (chunk = H5D_istore_chunk_alloc(orig_chunk_size, &dset->shared->dcpl_cache.pline)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for chunk")
+
/*
* No fill value was specified, assume all zeros.
*/
- HDmemset (chunk, 0, (size_t)chunk_size);
+ HDmemset(chunk, 0, orig_chunk_size);
} /* end else */
/* Check if there are filters which need to be applied to the chunk */
- if (pline.nused>0) {
- size_t buf_size=(size_t)chunk_size;
- size_t nbytes=(size_t)chunk_size;
+ /* (only do this in advance when the chunk info can be re-used (i.e.
+ * it doesn't contain any non-default VL datatype fill values)
+ */
+ if(!has_vlen_fill_type && dset->shared->dcpl_cache.pline.nused > 0) {
+ size_t buf_size = orig_chunk_size;
/* Push the chunk through the filters */
- if (H5Z_pipeline(&pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &nbytes, &buf_size, &chunk)<0)
+ if(H5Z_pipeline(&dset->shared->dcpl_cache.pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &orig_chunk_size, &buf_size, &chunk) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed")
-
- /* Keep the number of bytes the chunk turned in to */
- chunk_size=nbytes;
} /* end if */
} /* end if */
/* Set up dataset I/O info */
- store.chunk.offset=chunk_offset;
- H5D_BUILD_IO_INFO(&io_info,dset,dxpl_cache,dxpl_id,&store);
+ store.chunk.offset = chunk_offset;
+ H5D_BUILD_IO_INFO(&io_info, dset, dxpl_cache, dxpl_id, &store);
+
+ /* Reset the chunk offset indices */
+ HDmemset(chunk_offset, 0, (dset->shared->layout.u.chunk.ndims * sizeof(chunk_offset[0])));
/* Loop over all chunks */
- carry=0;
- while (carry==0) {
+ carry = FALSE;
+ while(!carry) {
+ int i; /* Local index variable */
+
/* Check if the chunk exists yet on disk */
- chunk_exists=1;
- if(H5D_istore_get_addr(&io_info,NULL)==HADDR_UNDEF) {
- const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
- H5D_rdcc_ent_t *ent = NULL; /*cache entry */
+ if(!H5F_addr_defined(H5D_istore_get_addr(&io_info, NULL))) {
+ const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Raw data chunk cache */
+ H5D_rdcc_ent_t *ent; /* Cache entry */
+ hbool_t chunk_exists; /* Flag to indicate whether a chunk exists already */
+ unsigned u; /* Local index variable */
/* Didn't find the chunk on disk */
- chunk_exists = 0;
+ chunk_exists = FALSE;
/* Look for chunk in cache */
for(ent = rdcc->head; ent && !chunk_exists; ent = ent->next) {
/* Assume a match */
- chunk_exists = 1;
- for(u = 0; u < dset->shared->layout.u.chunk.ndims && chunk_exists; u++) {
- if(ent->offset[u] != chunk_offset[u])
- chunk_exists = 0; /* Reset if no match */
- } /* end for */
+ chunk_exists = TRUE;
+ for(u = 0; u < dset->shared->layout.u.chunk.ndims; u++)
+ if(ent->offset[u] != chunk_offset[u]) {
+ chunk_exists = FALSE; /* Reset if no match */
+ break;
+ } /* end if */
} /* end for */
- } /* end if */
- if(!chunk_exists) {
- H5D_istore_ud1_t udata; /* B-tree pass-through for creating chunk */
+ /* Chunk wasn't in cache either, create it now */
+ if(!chunk_exists) {
+ H5D_istore_ud1_t udata; /* B-tree pass-through for creating chunk */
+ size_t chunk_size; /* Size of chunk in bytes, possibly filtered */
- /* Initialize the chunk information */
- udata.common.mesg = &dset->shared->layout;
- udata.common.key.filter_mask = filter_mask;
- udata.addr = HADDR_UNDEF;
- H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t);
- udata.common.key.nbytes = (size_t)chunk_size;
- for(u = 0; u < dset->shared->layout.u.chunk.ndims; u++)
- udata.common.key.offset[u] = chunk_offset[u];
+ /* Check for VL datatype & non-default fill value */
+ if(has_vlen_fill_type) {
+ /* Allocate a new chunk buffer each time, if filters are used */
+ if(dset->shared->dcpl_cache.pline.nused > 0)
+ if(NULL == (chunk = H5D_istore_chunk_alloc(orig_chunk_size, &dset->shared->dcpl_cache.pline)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for chunk")
- /* Allocate the chunk with all processes */
- if (H5B_insert(dset->ent.file, dxpl_id, H5B_ISTORE, dset->shared->layout.u.chunk.addr, &udata)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
+ /* Make a copy of the (disk-based) fill value into the buffer */
+ HDmemcpy(chunk, dset->shared->dcpl_cache.fill.buf, file_type_size);
- /* Check if fill values should be written to blocks */
- if(should_fill) {
-#ifdef H5_HAVE_PARALLEL
- /* Check if this file is accessed with an MPI-capable file driver */
- if(using_mpi) {
- /* Write the chunks out from only one process */
- /* !! Use the internal "independent" DXPL!! -QAK */
- if(H5_PAR_META_WRITE==mpi_rank) {
- if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, H5AC_ind_dxpl_id, chunk)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
- } /* end if */
+ /* Reset first element of background buffer, if necessary */
+ if(H5T_path_bkg(fill_to_mem_tpath))
+ HDmemset(bkg_buf, 0, elmt_size);
+
+ /* Type convert the dataset buffer, to copy any VL components */
+ if(H5T_convert(fill_to_mem_tpath, dset->shared->type_id, mem_tid, (size_t)1, (size_t)0, (size_t)0, chunk, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed")
+
+ /* Replicate the fill value into the cached buffer */
+ H5V_array_fill(chunk, chunk, mem_type_size, elmts_per_chunk);
+
+ /* Reset the entire background buffer, if necessary */
+ if(H5T_path_bkg(mem_to_dset_tpath))
+ HDmemset(bkg_buf, 0, bkg_buf_size);
- /* Indicate that blocks are being written */
- blocks_written=1;
+ /* Type convert the dataset buffer, to copy any VL components */
+ if(H5T_convert(mem_to_dset_tpath, mem_tid, dset->shared->type_id, elmts_per_chunk, (size_t)0, (size_t)0, chunk, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed")
+
+ /* Check if there are filters which need to be applied to the chunk */
+ if(dset->shared->dcpl_cache.pline.nused > 0) {
+ size_t buf_size = orig_chunk_size;
+ size_t nbytes = (size_t)dset->shared->layout.u.chunk.size;
+
+ /* Push the chunk through the filters */
+ if(H5Z_pipeline(&dset->shared->dcpl_cache.pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &nbytes, &buf_size, &chunk) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed")
+
+ /* Keep the number of bytes the chunk turned in to */
+ chunk_size = nbytes;
+ } /* end if */
+ else
+ chunk_size = (size_t)dset->shared->layout.u.chunk.size;
} /* end if */
- else {
+ else
+ chunk_size = orig_chunk_size;
+
+ /* Initialize the chunk information */
+ udata.common.mesg = &dset->shared->layout;
+ udata.common.key.filter_mask = filter_mask;
+ udata.addr = HADDR_UNDEF;
+ udata.common.key.nbytes = chunk_size;
+ for(u = 0; u < dset->shared->layout.u.chunk.ndims; u++)
+ udata.common.key.offset[u] = chunk_offset[u];
+
+ /* Allocate the chunk with all processes */
+ if(H5B_insert(dset->ent.file, dxpl_id, H5B_ISTORE, dset->shared->layout.u.chunk.addr, &udata) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
+
+ /* Check if fill values should be written to chunks */
+ if(should_fill) {
+#ifdef H5_HAVE_PARALLEL
+ /* Check if this file is accessed with an MPI-capable file driver */
+ if(using_mpi) {
+ /* Write the chunks out from only one process */
+ /* !! Use the internal "independent" DXPL!! -QAK */
+ if(H5_PAR_META_WRITE == mpi_rank)
+ if(H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, H5AC_ind_dxpl_id, chunk) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
+
+ /* Indicate that blocks are being written */
+ blocks_written = TRUE;
+ } /* end if */
+ else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, dxpl_id, chunk)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
+ if(H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, dxpl_id, chunk) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
#ifdef H5_HAVE_PARALLEL
- } /* end else */
+ } /* end else */
#endif /* H5_HAVE_PARALLEL */
+ } /* end if */
+
+ /* Release the chunk if we need to re-allocate it each time */
+ if(has_vlen_fill_type && dset->shared->dcpl_cache.pline.nused > 0)
+ chunk = H5D_istore_chunk_xfree(chunk, &dset->shared->dcpl_cache.pline);
} /* end if */
} /* end if */
- /* Increment indices */
- for (i=(int)dset->shared->layout.u.chunk.ndims-1, carry=1; i>=0 && carry; --i) {
+ /* Increment chunk offset indices */
+ carry = TRUE;
+ for(i = (int)dset->shared->layout.u.chunk.ndims - 1; i >= 0; --i) {
chunk_offset[i] += dset->shared->layout.u.chunk.dim[i];
- if (chunk_offset[i] >= space_dim[i])
+ if(chunk_offset[i] >= space_dim[i])
chunk_offset[i] = 0;
- else
- carry = 0;
+ else {
+ carry = FALSE;
+ break;
+ } /* end else */
} /* end for */
} /* end while */
#ifdef H5_HAVE_PARALLEL
- /* Only need to block at the barrier if we actually allocated a chunk */
- /* And if we are using an MPI-capable file driver */
+ /* Only need to block at the barrier if we actually initialized a chunk */
+ /* using an MPI-capable file driver */
if(using_mpi && blocks_written) {
/* Wait at barrier to avoid race conditions where some processes are
* still writing out chunks and other processes race ahead to read
* them in, getting bogus data.
*/
- if (MPI_SUCCESS != (mpi_code=MPI_Barrier(mpi_comm)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Barrier(mpi_comm)))
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code);
} /* end if */
#endif /* H5_HAVE_PARALLEL */
done:
/* Free the chunk for fill values */
- if(chunk!=NULL && pline_initialized)
- chunk=H5D_istore_chunk_xfree(chunk,&pline);
+ if(chunk)
+ chunk = H5D_istore_chunk_xfree(chunk, &dset->shared->dcpl_cache.pline);
+
+ /* Free other resources for vlen fill values */
+ if(has_vlen_fill_type) {
+ if(mem_tid > 0)
+ H5I_dec_ref(mem_tid);
+ else if(mem_type)
+ H5T_close(mem_type);
+ if(bkg_buf)
+ H5FL_BLK_FREE(type_conv, bkg_buf);
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_istore_allocate() */
diff --git a/test/tvltypes.c b/test/tvltypes.c
index 48ed402..15af456 100644
--- a/test/tvltypes.c
+++ b/test/tvltypes.c
@@ -2538,99 +2538,91 @@ test_vltypes_fill_value(void)
CHECK(file_id, FAIL, "H5Fcreate");
/* Create datasets with different storage layouts */
-#ifdef QAK
-HDfprintf(stderr, "Before creating datasets\n");
-#endif /* QAK */
-HDfprintf(stderr, "Uncomment loop!\n");
-/* for(layout = H5D_COMPACT; layout <= H5D_CHUNKED; layout++) { */
- for(layout = H5D_COMPACT; layout <= H5D_CONTIGUOUS; layout++) {
- hid_t tmp_dcpl_id; /* Temporary copy of the dataset creation property list */
-
- /* Make a copy of the dataset creation property list */
- tmp_dcpl_id = H5Pcopy(dcpl_id);
- CHECK(tmp_dcpl_id, FAIL, "H5Pcopy");
-
- /* Layout specific actions */
- switch(layout) {
- case H5D_COMPACT:
- HDstrcpy(dset_name1, "dataset1-compact");
- HDstrcpy(dset_name2, "dataset2-compact");
- dset_dspace_id = small_dspace_id;
- ret = H5Pset_layout(tmp_dcpl_id, H5D_COMPACT);
- CHECK(ret, FAIL, "H5Pset_layout");
- break;
-
- case H5D_CONTIGUOUS:
- HDstrcpy(dset_name1, "dataset1-contig");
- HDstrcpy(dset_name2, "dataset2-contig");
- dset_dspace_id = large_dspace_id;
- break;
-
- case H5D_CHUNKED:
- {
- hsize_t chunk_dims[1] = {SPACE4_DIM_LARGE / 4};
-
- HDstrcpy(dset_name1, "dataset1-chunked");
- HDstrcpy(dset_name2, "dataset2-chunked");
+ for(layout = H5D_COMPACT; layout <= H5D_CHUNKED; layout++) {
+ unsigned compress_loop; /* # of times to run loop, for testing compressed chunked dataset */
+ unsigned test_loop; /* Loop over datasets */
+
+#ifdef H5_HAVE_FILTER_DEFLATE
+ if(layout == H5D_CHUNKED)
+ compress_loop = 2;
+ else
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ compress_loop = 1;
+
+ /* Loop over dataset operations */
+ for(test_loop = 0; test_loop < compress_loop; test_loop++) {
+ hid_t tmp_dcpl_id; /* Temporary copy of the dataset creation property list */
+
+ /* Make a copy of the dataset creation property list */
+ tmp_dcpl_id = H5Pcopy(dcpl_id);
+ CHECK(tmp_dcpl_id, FAIL, "H5Pcopy");
+
+ /* Layout specific actions */
+ switch(layout) {
+ case H5D_COMPACT:
+ HDstrcpy(dset_name1, "dataset1-compact");
+ HDstrcpy(dset_name2, "dataset2-compact");
+ dset_dspace_id = small_dspace_id;
+ ret = H5Pset_layout(tmp_dcpl_id, H5D_COMPACT);
+ CHECK(ret, FAIL, "H5Pset_layout");
+ break;
+
+ case H5D_CONTIGUOUS:
+ HDstrcpy(dset_name1, "dataset1-contig");
+ HDstrcpy(dset_name2, "dataset2-contig");
dset_dspace_id = large_dspace_id;
- ret = H5Pset_chunk(tmp_dcpl_id, 1, chunk_dims);
- CHECK(ret, FAIL, "H5Pset_chunk");
- }
- break;
- } /* end switch */
-
- /* Create first data set with default setting - no space is allocated */
-#ifdef QAK
-HDfprintf(stderr, "Before creating first dataset: '%s'\n", dset_name1);
-#endif /* QAK */
- dset_id = H5Dcreate(file_id, dset_name1, dtype1_id, dset_dspace_id, tmp_dcpl_id);
-#ifdef QAK
-HDfprintf(stderr, "After creating first dataset\n");
-#endif /* QAK */
- CHECK(dset_id, FAIL, "H5Dcreate");
-
-#ifdef QAK
-HDfprintf(stderr, "Before closing first dataset\n");
-#endif /* QAK */
- ret = H5Dclose(dset_id);
-#ifdef QAK
-HDfprintf(stderr, "After closing first dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dclose");
-
-
-#ifndef QAK2
- /* Create a second data set with space allocated and fill value written */
- ret = H5Pset_fill_time(tmp_dcpl_id, H5D_FILL_TIME_IFSET);
- CHECK(ret, FAIL, "H5Pset_fill_time");
-
- ret = H5Pset_alloc_time(tmp_dcpl_id, H5D_ALLOC_TIME_EARLY);
- CHECK(ret, FAIL, "H5Pset_alloc_time");
-
-#ifdef QAK
-HDfprintf(stderr, "Before creating second dataset: '%s'\n", dset_name2);
-#endif /* QAK */
- dset_id = H5Dcreate(file_id, dset_name2, dtype1_id, dset_dspace_id, tmp_dcpl_id);
-#ifdef QAK
-HDfprintf(stderr, "After creating second dataset\n");
-#endif /* QAK */
- CHECK(dset_id, FAIL, "H5Dcreate");
-
-#ifdef QAK
-HDfprintf(stderr, "Before closing second dataset\n");
-#endif /* QAK */
- ret = H5Dclose(dset_id);
-#ifdef QAK
-HDfprintf(stderr, "After closing second dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dclose");
-#else /* QAK2 */
-HDfprintf(stderr, "Uncomment test for second dataset!\n");
-#endif /* QAK2 */
-
- /* Close temporary DCPL */
- ret = H5Pclose(tmp_dcpl_id);
- CHECK(ret, FAIL, "H5Pclose");
+ break;
+
+ case H5D_CHUNKED:
+ {
+ hsize_t chunk_dims[1] = {SPACE4_DIM_LARGE / 4};
+
+ dset_dspace_id = large_dspace_id;
+ ret = H5Pset_chunk(tmp_dcpl_id, 1, chunk_dims);
+ CHECK(ret, FAIL, "H5Pset_chunk");
+#ifdef H5_HAVE_FILTER_DEFLATE
+ if(test_loop == 1) {
+ HDstrcpy(dset_name1, "dataset1-chunked-compressed");
+ HDstrcpy(dset_name2, "dataset2-chunked-compressed");
+ ret = H5Pset_deflate(tmp_dcpl_id, 3);
+ CHECK(ret, FAIL, "H5Pset_deflate");
+ } /* end if */
+ else {
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ HDstrcpy(dset_name1, "dataset1-chunked");
+ HDstrcpy(dset_name2, "dataset2-chunked");
+#ifdef H5_HAVE_FILTER_DEFLATE
+ } /* end else */
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ }
+ break;
+ } /* end switch */
+
+ /* Create first data set with default setting - no space is allocated */
+ dset_id = H5Dcreate(file_id, dset_name1, dtype1_id, dset_dspace_id, tmp_dcpl_id);
+ CHECK(dset_id, FAIL, "H5Dcreate");
+
+ ret = H5Dclose(dset_id);
+ CHECK(ret, FAIL, "H5Dclose");
+
+
+ /* Create a second data set with space allocated and fill value written */
+ ret = H5Pset_fill_time(tmp_dcpl_id, H5D_FILL_TIME_IFSET);
+ CHECK(ret, FAIL, "H5Pset_fill_time");
+
+ ret = H5Pset_alloc_time(tmp_dcpl_id, H5D_ALLOC_TIME_EARLY);
+ CHECK(ret, FAIL, "H5Pset_alloc_time");
+
+ dset_id = H5Dcreate(file_id, dset_name2, dtype1_id, dset_dspace_id, tmp_dcpl_id);
+ CHECK(dset_id, FAIL, "H5Dcreate");
+
+ ret = H5Dclose(dset_id);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Close temporary DCPL */
+ ret = H5Pclose(tmp_dcpl_id);
+ CHECK(ret, FAIL, "H5Pclose");
+ } /* end for */
} /* end for */
ret = H5Fclose(file_id);
@@ -2652,358 +2644,278 @@ HDfprintf(stderr, "Uncomment test for second dataset!\n");
CHECK(file_id, FAIL, "H5Fopen");
/* Read datasets with different storage layouts */
-#ifdef QAK
-HDfprintf(stderr, "Before testing empty reads\n");
-#endif /* QAK */
-HDfprintf(stderr, "Uncomment loop!\n");
-/* for(layout = H5D_COMPACT; layout <= H5D_CHUNKED; layout++) { */
- for(layout = H5D_COMPACT; layout <= H5D_CONTIGUOUS; layout++) {
-
- /* Layout specific actions */
- switch(layout) {
- case H5D_COMPACT:
- HDstrcpy(dset_name1, "dataset1-compact");
- HDstrcpy(dset_name2, "dataset2-compact");
- dset_dspace_id = small_dspace_id;
- dset_elmts = SPACE4_DIM_SMALL;
- break;
-
- case H5D_CONTIGUOUS:
- HDstrcpy(dset_name1, "dataset1-contig");
- HDstrcpy(dset_name2, "dataset2-contig");
- dset_dspace_id = large_dspace_id;
- dset_elmts = SPACE4_DIM_LARGE;
- break;
-
- case H5D_CHUNKED:
- HDstrcpy(dset_name1, "dataset1-chunked");
- HDstrcpy(dset_name2, "dataset2-chunked");
- dset_dspace_id = large_dspace_id;
- dset_elmts = SPACE4_DIM_LARGE;
- break;
- } /* end switch */
-
- /* Open first data set */
-#ifdef QAK
-HDfprintf(stderr, "Before opening first dataset: '%s'\n", dset_name1);
-#endif /* QAK */
- dset_id = H5Dopen(file_id, dset_name1);
-#ifdef QAK
-HDfprintf(stderr, "After opening first dataset\n");
-#endif /* QAK */
- CHECK(dset_id, FAIL, "H5Dopen");
-
- /* Read in the data of fill value */
-#ifdef QAK
-HDfprintf(stderr, "Before reading from first dataset\n");
-#endif /* QAK */
- ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reading from first dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dread");
-
- /* Compare data read in */
- for(i = 0; i < dset_elmts; i++) {
- if(HDstrcmp(rbuf[i].str_id, "foobar")
- || HDstrcmp(rbuf[i].str_name, "")
- || rbuf[i].str_desc
- || HDstrcmp(rbuf[i].str_orig, "\0")
- || HDstrcmp(rbuf[i].str_stat, "dead")
- || HDstrcmp(rbuf[i].str_form, "liquid")
- || HDstrcmp(rbuf[i].str_unit, "meter")) {
- TestErrPrintf("%d: VL data doesn't match!, index(i) = %d\n", __LINE__, (int)i);
- continue;
- } /* end if */
- } /* end for */
-
-#ifdef QAK
-HDfprintf(stderr, "Before closing first dataset\n");
-#endif /* QAK */
- ret = H5Dclose(dset_id);
-#ifdef QAK
-HDfprintf(stderr, "After closing first dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dclose");
-
- /* Release the space */
-#ifdef QAK
-HDfprintf(stderr, "Before reclaiming space\n");
-#endif /* QAK */
- ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reclaiming space\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dvlen_reclaim");
-
-
-#ifndef QAK2
- /* Open the second data set to check the value of data */
-#ifdef QAK
-HDfprintf(stderr, "Before opening second dataset: '%s'\n", dset_name2);
-#endif /* QAK */
- dset_id = H5Dopen(file_id, dset_name2);
-#ifdef QAK
-HDfprintf(stderr, "After opening second dataset\n");
-#endif /* QAK */
- CHECK(dset_id, FAIL, "H5Dopen");
-
-#ifdef QAK
-HDfprintf(stderr, "Before reading from second dataset\n");
-#endif /* QAK */
- ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reading from second dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dread");
-
- /* Compare data read in */
- for(i = 0; i < dset_elmts; i++) {
- if(HDstrcmp(rbuf[i].str_id, "foobar")
- || HDstrcmp(rbuf[i].str_name, "")
- || rbuf[i].str_desc
- || HDstrcmp(rbuf[i].str_orig, "\0")
- || HDstrcmp(rbuf[i].str_stat, "dead")
- || HDstrcmp(rbuf[i].str_form, "liquid")
- || HDstrcmp(rbuf[i].str_unit, "meter")) {
- TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
- continue;
- } /* end if */
- } /* end for */
-
-#ifdef QAK
-HDfprintf(stderr, "Before closing second dataset\n");
-#endif /* QAK */
- ret = H5Dclose(dset_id);
-#ifdef QAK
-HDfprintf(stderr, "After closing second dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dclose");
-
- /* Release the space */
-#ifdef QAK
-HDfprintf(stderr, "Before reclaiming space\n");
-#endif /* QAK */
- ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reclaiming space\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dvlen_reclaim");
-#else /* QAK2 */
-HDfprintf(stderr, "Uncomment test for second dataset!\n");
-#endif /* QAK2 */
- } /* end for */
-
- ret = H5Fclose(file_id);
- CHECK(ret, FAIL, "H5Fclose");
+ for(layout = H5D_COMPACT; layout <= H5D_CHUNKED; layout++) {
+ unsigned compress_loop; /* # of times to run loop, for testing compressed chunked dataset */
+ unsigned test_loop; /* Loop over datasets */
+
+#ifdef H5_HAVE_FILTER_DEFLATE
+ if(layout == H5D_CHUNKED)
+ compress_loop = 2;
+ else
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ compress_loop = 1;
+
+ /* Loop over dataset operations */
+ for(test_loop = 0; test_loop < compress_loop; test_loop++) {
+
+ /* Layout specific actions */
+ switch(layout) {
+ case H5D_COMPACT:
+ HDstrcpy(dset_name1, "dataset1-compact");
+ HDstrcpy(dset_name2, "dataset2-compact");
+ dset_dspace_id = small_dspace_id;
+ dset_elmts = SPACE4_DIM_SMALL;
+ break;
+
+ case H5D_CONTIGUOUS:
+ HDstrcpy(dset_name1, "dataset1-contig");
+ HDstrcpy(dset_name2, "dataset2-contig");
+ dset_dspace_id = large_dspace_id;
+ dset_elmts = SPACE4_DIM_LARGE;
+ break;
+
+ case H5D_CHUNKED:
+#ifdef H5_HAVE_FILTER_DEFLATE
+ if(test_loop == 1) {
+ HDstrcpy(dset_name1, "dataset1-chunked-compressed");
+ HDstrcpy(dset_name2, "dataset2-chunked-compressed");
+ } /* end if */
+ else {
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ HDstrcpy(dset_name1, "dataset1-chunked");
+ HDstrcpy(dset_name2, "dataset2-chunked");
+#ifdef H5_HAVE_FILTER_DEFLATE
+ } /* end else */
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ dset_dspace_id = large_dspace_id;
+ dset_elmts = SPACE4_DIM_LARGE;
+ break;
+ } /* end switch */
+ /* Open first data set */
+ dset_id = H5Dopen(file_id, dset_name1);
+ CHECK(dset_id, FAIL, "H5Dopen");
- /* Open the file to check data set value */
- file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
- CHECK(file_id, FAIL, "H5Fopen");
+ /* Read in the data of fill value */
+ ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dread");
- /* Write one element & fill values to datasets with different storage layouts */
-#ifdef QAK
-HDfprintf(stderr, "Before testing single element writes\n");
-#endif /* QAK */
-HDfprintf(stderr, "Uncomment loop!\n");
-/* for(layout = H5D_COMPACT; layout <= H5D_CHUNKED; layout++) { */
- for(layout = H5D_COMPACT; layout <= H5D_CONTIGUOUS; layout++) {
-
- /* Layout specific actions */
- switch(layout) {
- case H5D_COMPACT:
- HDstrcpy(dset_name1, "dataset1-compact");
- HDstrcpy(dset_name2, "dataset2-compact");
- dset_dspace_id = small_dspace_id;
- dset_elmts = SPACE4_DIM_SMALL;
- break;
-
- case H5D_CONTIGUOUS:
- HDstrcpy(dset_name1, "dataset1-contig");
- HDstrcpy(dset_name2, "dataset2-contig");
- dset_dspace_id = large_dspace_id;
- dset_elmts = SPACE4_DIM_LARGE;
- break;
-
- case H5D_CHUNKED:
- HDstrcpy(dset_name1, "dataset1-chunked");
- HDstrcpy(dset_name2, "dataset2-chunked");
- dset_dspace_id = large_dspace_id;
- dset_elmts = SPACE4_DIM_LARGE;
- break;
- } /* end switch */
-
- /* Copy the dataset's dataspace */
- single_dspace_id = H5Scopy(dset_dspace_id);
- CHECK(single_dspace_id, FAIL, "H5Scopy");
-
- /* Set a single element in the dataspace */
- ret = H5Sselect_hyperslab(single_dspace_id, H5S_SELECT_SET, single_offset,
- NULL, single_block, NULL);
- CHECK(ret, FAIL, "H5Sselect_hyperslab");
-
- /* Open first data set */
-#ifdef QAK
-HDfprintf(stderr, "Before opening first dataset: '%s'\n", dset_name1);
-#endif /* QAK */
- dset_id = H5Dopen(file_id, dset_name1);
-#ifdef QAK
-HDfprintf(stderr, "After opening first dataset\n");
-#endif /* QAK */
- CHECK(dset_id, FAIL, "H5Dopen");
-
- /* Write one element in the dataset */
-#ifdef QAK
-HDfprintf(stderr, "Before writing to first dataset\n");
-#endif /* QAK */
- ret = H5Dwrite(dset_id, dtype1_id, scalar_dspace_id, single_dspace_id, xfer_pid, &wdata);
-#ifdef QAK
-HDfprintf(stderr, "After writing to first dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dwrite");
-
-#ifdef QAK
-HDfprintf(stderr, "Before reading from first dataset\n");
-#endif /* QAK */
- ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reading from first dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dread");
-
- /* Compare data read in */
- for(i = 0; i < dset_elmts; i++) {
- if(i == single_offset[0]) {
- if(HDstrcmp(rbuf[i].str_id, wdata.str_id)
- || rbuf[i].str_name
- || HDstrcmp(rbuf[i].str_desc, wdata.str_desc)
- || HDstrcmp(rbuf[i].str_orig, wdata.str_orig)
- || HDstrcmp(rbuf[i].str_stat, wdata.str_stat)
- || HDstrcmp(rbuf[i].str_form, wdata.str_form)
- || HDstrcmp(rbuf[i].str_unit, wdata.str_unit)) {
- TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
- continue;
- } /* end if */
- } /* end if */
- else {
+ /* Compare data read in */
+ for(i = 0; i < dset_elmts; i++) {
if(HDstrcmp(rbuf[i].str_id, "foobar")
|| HDstrcmp(rbuf[i].str_name, "")
|| rbuf[i].str_desc
- || HDstrcmp(rbuf[i].str_orig,"\0")
+ || HDstrcmp(rbuf[i].str_orig, "\0")
|| HDstrcmp(rbuf[i].str_stat, "dead")
|| HDstrcmp(rbuf[i].str_form, "liquid")
|| HDstrcmp(rbuf[i].str_unit, "meter")) {
- TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
+ TestErrPrintf("%d: VL data doesn't match!, index(i) = %d\n", __LINE__, (int)i);
continue;
} /* end if */
- } /* end if */
- } /* end for */
+ } /* end for */
+ ret = H5Dclose(dset_id);
+ CHECK(ret, FAIL, "H5Dclose");
-#ifdef QAK
-HDfprintf(stderr, "Before closing first dataset\n");
-#endif /* QAK */
- ret = H5Dclose(dset_id);
-#ifdef QAK
-HDfprintf(stderr, "After closing first dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dclose");
-
- /* Release the space */
-#ifdef QAK
-HDfprintf(stderr, "Before reclaiming space\n");
-#endif /* QAK */
- ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reclaiming space\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dvlen_reclaim");
-
-
-#ifndef QAK2
- /* Open the second data set to check the value of data */
-#ifdef QAK
-HDfprintf(stderr, "Before opening second dataset: '%s'\n", dset_name2);
-#endif /* QAK */
- dset_id = H5Dopen(file_id, dset_name2);
-#ifdef QAK
-HDfprintf(stderr, "After opening second dataset\n");
-#endif /* QAK */
- CHECK(dset_id, FAIL, "H5Dopen");
-
- /* Write one element in the dataset */
-#ifdef QAK
-HDfprintf(stderr, "Before writing to second dataset\n");
-#endif /* QAK */
- ret = H5Dwrite(dset_id, dtype1_id, scalar_dspace_id, single_dspace_id, xfer_pid, &wdata);
-#ifdef QAK
-HDfprintf(stderr, "After writing to second dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dwrite");
-
-#ifdef QAK
-HDfprintf(stderr, "Before reading from second dataset\n");
-#endif /* QAK */
- ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reading from second dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dread");
-
- /* Compare data read in */
- for(i = 0; i < dset_elmts; i++) {
- if(i == single_offset[0]) {
- if(HDstrcmp(rbuf[i].str_id, wdata.str_id)
- || rbuf[i].str_name
- || HDstrcmp(rbuf[i].str_desc, wdata.str_desc)
- || HDstrcmp(rbuf[i].str_orig, wdata.str_orig)
- || HDstrcmp(rbuf[i].str_stat, wdata.str_stat)
- || HDstrcmp(rbuf[i].str_form, wdata.str_form)
- || HDstrcmp(rbuf[i].str_unit, wdata.str_unit)) {
- TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
- continue;
- } /* end if */
- } /* end if */
- else {
+ /* Release the space */
+ ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
+
+
+ /* Open the second data set to check the value of data */
+ dset_id = H5Dopen(file_id, dset_name2);
+ CHECK(dset_id, FAIL, "H5Dopen");
+
+ ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Compare data read in */
+ for(i = 0; i < dset_elmts; i++) {
if(HDstrcmp(rbuf[i].str_id, "foobar")
|| HDstrcmp(rbuf[i].str_name, "")
|| rbuf[i].str_desc
- || HDstrcmp(rbuf[i].str_orig,"\0")
+ || HDstrcmp(rbuf[i].str_orig, "\0")
|| HDstrcmp(rbuf[i].str_stat, "dead")
|| HDstrcmp(rbuf[i].str_form, "liquid")
|| HDstrcmp(rbuf[i].str_unit, "meter")) {
TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
continue;
} /* end if */
- } /* end if */
+ } /* end for */
+
+ ret = H5Dclose(dset_id);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Release the space */
+ ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
} /* end for */
+ } /* end for */
+
+ ret = H5Fclose(file_id);
+ CHECK(ret, FAIL, "H5Fclose");
+
+
+ /* Open the file to check data set value */
+ file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(file_id, FAIL, "H5Fopen");
+
+ /* Write one element & fill values to datasets with different storage layouts */
+ for(layout = H5D_COMPACT; layout <= H5D_CHUNKED; layout++) {
+ unsigned compress_loop; /* # of times to run loop, for testing compressed chunked dataset */
+ unsigned test_loop; /* Loop over datasets */
+
+#ifdef H5_HAVE_FILTER_DEFLATE
+ if(layout == H5D_CHUNKED)
+ compress_loop = 2;
+ else
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ compress_loop = 1;
+
+ /* Loop over dataset operations */
+ for(test_loop = 0; test_loop < compress_loop; test_loop++) {
+
+ /* Layout specific actions */
+ switch(layout) {
+ case H5D_COMPACT:
+ HDstrcpy(dset_name1, "dataset1-compact");
+ HDstrcpy(dset_name2, "dataset2-compact");
+ dset_dspace_id = small_dspace_id;
+ dset_elmts = SPACE4_DIM_SMALL;
+ break;
+
+ case H5D_CONTIGUOUS:
+ HDstrcpy(dset_name1, "dataset1-contig");
+ HDstrcpy(dset_name2, "dataset2-contig");
+ dset_dspace_id = large_dspace_id;
+ dset_elmts = SPACE4_DIM_LARGE;
+ break;
+
+ case H5D_CHUNKED:
+#ifdef H5_HAVE_FILTER_DEFLATE
+ if(test_loop == 1) {
+ HDstrcpy(dset_name1, "dataset1-chunked-compressed");
+ HDstrcpy(dset_name2, "dataset2-chunked-compressed");
+ } /* end if */
+ else {
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ HDstrcpy(dset_name1, "dataset1-chunked");
+ HDstrcpy(dset_name2, "dataset2-chunked");
+#ifdef H5_HAVE_FILTER_DEFLATE
+ } /* end else */
+#endif /* H5_HAVE_FILTER_DEFLATE */
+ dset_dspace_id = large_dspace_id;
+ dset_elmts = SPACE4_DIM_LARGE;
+ break;
+ } /* end switch */
+
+ /* Copy the dataset's dataspace */
+ single_dspace_id = H5Scopy(dset_dspace_id);
+ CHECK(single_dspace_id, FAIL, "H5Scopy");
+
+ /* Set a single element in the dataspace */
+ ret = H5Sselect_hyperslab(single_dspace_id, H5S_SELECT_SET, single_offset,
+ NULL, single_block, NULL);
+ CHECK(ret, FAIL, "H5Sselect_hyperslab");
+
+ /* Open first data set */
+ dset_id = H5Dopen(file_id, dset_name1);
+ CHECK(dset_id, FAIL, "H5Dopen");
+
+ /* Write one element in the dataset */
+ ret = H5Dwrite(dset_id, dtype1_id, scalar_dspace_id, single_dspace_id, xfer_pid, &wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Compare data read in */
+ for(i = 0; i < dset_elmts; i++) {
+ if(i == single_offset[0]) {
+ if(HDstrcmp(rbuf[i].str_id, wdata.str_id)
+ || rbuf[i].str_name
+ || HDstrcmp(rbuf[i].str_desc, wdata.str_desc)
+ || HDstrcmp(rbuf[i].str_orig, wdata.str_orig)
+ || HDstrcmp(rbuf[i].str_stat, wdata.str_stat)
+ || HDstrcmp(rbuf[i].str_form, wdata.str_form)
+ || HDstrcmp(rbuf[i].str_unit, wdata.str_unit)) {
+ TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
+ continue;
+ } /* end if */
+ } /* end if */
+ else {
+ if(HDstrcmp(rbuf[i].str_id, "foobar")
+ || HDstrcmp(rbuf[i].str_name, "")
+ || rbuf[i].str_desc
+ || HDstrcmp(rbuf[i].str_orig,"\0")
+ || HDstrcmp(rbuf[i].str_stat, "dead")
+ || HDstrcmp(rbuf[i].str_form, "liquid")
+ || HDstrcmp(rbuf[i].str_unit, "meter")) {
+ TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
+ continue;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+
+
+ ret = H5Dclose(dset_id);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Release the space */
+ ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
+
+
+ /* Open the second data set to check the value of data */
+ dset_id = H5Dopen(file_id, dset_name2);
+ CHECK(dset_id, FAIL, "H5Dopen");
+
+ /* Write one element in the dataset */
+ ret = H5Dwrite(dset_id, dtype1_id, scalar_dspace_id, single_dspace_id, xfer_pid, &wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
-#ifdef QAK
-HDfprintf(stderr, "Before closing second dataset\n");
-#endif /* QAK */
- ret = H5Dclose(dset_id);
-#ifdef QAK
-HDfprintf(stderr, "After closing second dataset\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dclose");
-
- /* Release the space */
-#ifdef QAK
-HDfprintf(stderr, "Before reclaiming space\n");
-#endif /* QAK */
- ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
-#ifdef QAK
-HDfprintf(stderr, "After reclaiming space\n");
-#endif /* QAK */
- CHECK(ret, FAIL, "H5Dvlen_reclaim");
-#else /* QAK2 */
-HDfprintf(stderr, "Uncomment test for second dataset!\n");
-#endif /* QAK2 */
-
- /* Close the dataspace for the writes */
- ret = H5Sclose(single_dspace_id);
- CHECK(ret, FAIL, "H5Sclose");
+ ret = H5Dread(dset_id, dtype1_id, dset_dspace_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Compare data read in */
+ for(i = 0; i < dset_elmts; i++) {
+ if(i == single_offset[0]) {
+ if(HDstrcmp(rbuf[i].str_id, wdata.str_id)
+ || rbuf[i].str_name
+ || HDstrcmp(rbuf[i].str_desc, wdata.str_desc)
+ || HDstrcmp(rbuf[i].str_orig, wdata.str_orig)
+ || HDstrcmp(rbuf[i].str_stat, wdata.str_stat)
+ || HDstrcmp(rbuf[i].str_form, wdata.str_form)
+ || HDstrcmp(rbuf[i].str_unit, wdata.str_unit)) {
+ TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
+ continue;
+ } /* end if */
+ } /* end if */
+ else {
+ if(HDstrcmp(rbuf[i].str_id, "foobar")
+ || HDstrcmp(rbuf[i].str_name, "")
+ || rbuf[i].str_desc
+ || HDstrcmp(rbuf[i].str_orig,"\0")
+ || HDstrcmp(rbuf[i].str_stat, "dead")
+ || HDstrcmp(rbuf[i].str_form, "liquid")
+ || HDstrcmp(rbuf[i].str_unit, "meter")) {
+ TestErrPrintf("%d: VL data doesn't match!, index(i)=%d\n",__LINE__,(int)i);
+ continue;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+
+ ret = H5Dclose(dset_id);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Release the space */
+ ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
+
+ /* Close the dataspace for the writes */
+ ret = H5Sclose(single_dspace_id);
+ CHECK(ret, FAIL, "H5Sclose");
+ } /* end for */
} /* end for */
ret = H5Fclose(file_id);
@@ -3043,7 +2955,6 @@ test_vltypes(void)
MESSAGE(5, ("Testing Variable-Length Datatypes\n"));
/* These next tests use the same file */
-#ifndef QAK
test_vltypes_dataset_create(); /* Check dataset of VL when fill value
* won't be rewritten to it.*/
test_vltypes_vlen_atomic(); /* Test VL atomic datatypes */
@@ -3057,9 +2968,6 @@ test_vltypes(void)
rewrite_shorter_vltypes_vlen_vlen_atomic(); /*overwrite with VL data of shorted sequence*/
test_vltypes_compound_vlen_vlen(); /* Test compound datatypes with VL atomic components */
test_vltypes_compound_vlstr(); /* Test data rewritten of nested VL data */
-#else /* QAK */
-HDfprintf(stderr, "Uncomment tests!\n");
-#endif /* QAK */
test_vltypes_fill_value(); /* Test fill value for VL data */
} /* test_vltypes() */