From 471917c6384587c5de7ff4473faaae5d3fa248a6 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Sun, 4 Nov 2018 19:54:41 -0600 Subject: Updated new API functions Description: - Per Vailin's review, revised H5Dget_chunk_info_by_coord to handle non-existing chunk and H5Dget_num_chunks and H5Dget_chunk_info to handle dataset with no data. - Addressed other review comments - Note that additional tests will be added as we need to send users these functions asap for feedback. Platforms tested: Linux/64 (jelly) Linux/64 (platypus) Darwin (osx1011test) --- src/H5D.c | 4 +- src/H5Dchunk.c | 226 ++++++++++++++++++++++++++++++++++++++++----------------- src/H5Dpkg.h | 2 +- test/dsets.c | 94 +++++++++++++++++++----- 4 files changed, 239 insertions(+), 87 deletions(-) diff --git a/src/H5D.c b/src/H5D.c index 286ab4e..32b2453 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -1230,7 +1230,7 @@ H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t index, hsize_t *offset /* Call private function to get the chunk info given the chunk's index */ if(H5D__get_chunk_info(dset, space, index, offset, filter_mask, addr, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get chunk info") + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info") done: FUNC_LEAVE_API(ret_value); @@ -1279,7 +1279,7 @@ H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, unsigned *filte /* Internal function to get the chunk info */ if (H5D__get_chunk_info_by_coord(dset, offset, filter_mask, addr, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't get chunk info") done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_chunk_info_by_coord() */ diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 6bc89d1..7e7a94c 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -217,14 +217,15 @@ typedef struct H5D_chunk_readvv_ud_t { } H5D_chunk_readvv_ud_t; /* Typedef for chunk info iterator callback */ -typedef struct { +typedef struct H5D_chunk_info_iter_ud_t { hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Logical offset of the chunk */ - hsize_t ndims; /* Number of dimension in the dataset */ + hsize_t ndims; /* Number of dimensions in the dataset */ uint32_t nbytes; /* Size of stored data in the chunk */ unsigned filter_mask; /* Excluded filters */ haddr_t chunk_addr; /* Address of the chunk in file */ hsize_t chunk_idx; /* Chunk index, where the iteration needs to stop */ hsize_t curr_idx; /* Current index, where the iteration is */ + hbool_t found; /* Whether the chunk was found */ } H5D_chunk_info_iter_ud_t; /* Callback info for file selection iteration */ @@ -263,6 +264,12 @@ static herr_t H5D__chunk_flush(H5D_t *dset); static herr_t H5D__chunk_io_term(const H5D_chunk_map_t *fm); static herr_t H5D__chunk_dest(H5D_t *dset); +/* Chunk query operation callbacks */ +static int H5D__get_num_chunks_cb(const H5D_chunk_rec_t H5_ATTR_UNUSED *chunk_rec, void *_udata); +static int H5D__get_chunk_info_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata); +static int H5D__get_chunk_info_by_coord_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata); + + /* "Nonexistent" layout operation callback */ static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, @@ -6744,6 +6751,9 @@ done: * Purpose: Callback function that increments the number of written * chunks in the dataset. * + * Note: Currently, this function only gets the number of all written + * chunks, regardless the dataspace. + * * Return: Success: H5_ITER_CONT or H5_ITER_STOP * Failure: Negative (H5_ITER_ERROR) * @@ -6753,14 +6763,15 @@ done: *------------------------------------------------------------------------- */ static int -H5D__get_num_chunks_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) +H5D__get_num_chunks_cb(const H5D_chunk_rec_t H5_ATTR_UNUSED *chunk_rec, void *_udata) { - int ret_value = H5_ITER_CONT; /* Callback return value */ - hsize_t *num_chunks = (hsize_t *)_udata; + int ret_value = H5_ITER_CONT; /* Callback return value */ FUNC_ENTER_STATIC_NOERR + HDassert(num_chunks); + (*num_chunks)++; FUNC_LEAVE_NOAPI(ret_value) @@ -6772,6 +6783,9 @@ H5D__get_num_chunks_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) * * Purpose: Gets the number of written chunks in a dataset. * + * Note: Currently, this function only gets the number of all written + * chunks, regardless the dataspace. + * * Return: Success: Non-negative * Failure: Negative * @@ -6781,18 +6795,24 @@ H5D__get_num_chunks_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) *------------------------------------------------------------------------- */ herr_t -H5D__get_num_chunks(const H5D_t *dset, const H5S_t *space, hsize_t *nchunks) +H5D__get_num_chunks(const H5D_t *dset, const H5S_t H5_ATTR_UNUSED *space, hsize_t *nchunks) { - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - hsize_t num_chunks = 0; /* Number of written chunks */ - H5D_rdcc_ent_t *ent; /* Cache entry */ - const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);/* Raw data chunk cache */ - herr_t ret_value = SUCCEED; /* Return value */ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + hsize_t num_chunks = 0; /* Number of written chunks */ + H5D_rdcc_ent_t *ent; /* Cache entry */ + const H5D_rdcc_t *rdcc = NULL; /* Raw data chunk cache */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) HDassert(dset); HDassert(dset->shared); + HDassert(space); + HDassert(nchunks); + + /* Get the raw data chunk cache */ + rdcc = &(dset->shared->cache.chunk); + HDassert(rdcc); /* Search for cached chunks that haven't been written out */ for(ent = rdcc->head; ent; ent = ent->next) @@ -6806,10 +6826,17 @@ H5D__get_num_chunks(const H5D_t *dset, const H5S_t *space, hsize_t *nchunks) idx_info.layout = &dset->shared->layout.u.chunk; idx_info.storage = &dset->shared->layout.storage.u.chunk; + /* If the dataset is not written, number of chunks will be 0 */ + if (idx_info.storage->idx_addr == HADDR_UNDEF) { + *nchunks = 0; + HGOTO_DONE(SUCCEED); + } + else { /* Iterate over the allocated chunks */ if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__get_num_chunks_cb, &num_chunks) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve allocated chunk information from index") *nchunks = num_chunks; + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -6832,22 +6859,24 @@ done: static int H5D__get_chunk_info_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) { - hsize_t ii; - int ret_value = H5_ITER_CONT; /* Callback return value */ - H5D_chunk_info_iter_ud_t *chunk_info = (H5D_chunk_info_iter_ud_t *)_udata; + hsize_t ii = 0; /* Dimension index */ + int ret_value = H5_ITER_CONT; /* Callback return value */ FUNC_ENTER_STATIC_NOERR + /* Check args */ + HDassert(chunk_rec); + HDassert(chunk_info); + /* If this is the desired chunk, retrieve its info and stop iterating */ - if (chunk_info->curr_idx == chunk_info->chunk_idx) - { + if (chunk_info->curr_idx == chunk_info->chunk_idx) { chunk_info->filter_mask = chunk_rec->filter_mask; chunk_info->chunk_addr = chunk_rec->chunk_addr; chunk_info->nbytes = chunk_rec->nbytes; - for (ii = 0; ii < chunk_info->ndims; ii++) chunk_info->scaled[ii] = chunk_rec->scaled[ii]; + chunk_info->found = TRUE; /* Stop iterating */ ret_value = H5_ITER_STOP; @@ -6866,6 +6895,9 @@ H5D__get_chunk_info_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) * Purpose: Iterate over the chunks in the dataset to get the info * of the desired chunk. * + * Note: Currently, this function only gets the number of all written + * chunks, regardless the dataspace. + * * Return: Success: SUCCEED * Failure: FAIL * @@ -6875,19 +6907,24 @@ H5D__get_chunk_info_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) *------------------------------------------------------------------------- */ herr_t -H5D__get_chunk_info(const H5D_t *dset, const H5S_t *space, hsize_t index, hsize_t *offset, unsigned *filter_mask, haddr_t *addr, hsize_t *size) +H5D__get_chunk_info(const H5D_t *dset, const H5S_t H5_ATTR_UNUSED *space, hsize_t index, hsize_t *offset, unsigned *filter_mask, haddr_t *addr, hsize_t *size) { - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - H5D_chunk_info_iter_ud_t udata; - const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);/* Raw data chunk cache */ - H5D_rdcc_ent_t *ent; /* Cache entry */ - hsize_t ii = 0; /* Dimension index */ - herr_t ret_value = SUCCEED; /* Return value */ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + H5D_chunk_info_iter_ud_t udata; /* User data for callback */ + const H5D_rdcc_t *rdcc = NULL; /* Raw data chunk cache */ + H5D_rdcc_ent_t *ent; /* Cache entry index */ + hsize_t ii = 0; /* Dimension index */ + herr_t ret_value = SUCCEED;/* Return value */ FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) HDassert(dset); HDassert(dset->shared); + HDassert(space); + + /* Get the raw data chunk cache */ + rdcc = &(dset->shared->cache.chunk); + HDassert(rdcc); /* Search for cached chunks that haven't been written out */ for(ent = rdcc->head; ent; ent = ent->next) @@ -6901,25 +6938,47 @@ H5D__get_chunk_info(const H5D_t *dset, const H5S_t *space, hsize_t index, hsize_ idx_info.layout = &dset->shared->layout.u.chunk; idx_info.storage = &dset->shared->layout.storage.u.chunk; - /* Initialize for iteration */ + /* If the dataset is not written, return the address as undefined */ + if (idx_info.storage->idx_addr == HADDR_UNDEF) { + if (addr) + *addr = HADDR_UNDEF; + if (size) + *size = 0; + HGOTO_DONE(SUCCEED); + } + + /* Initialize before iteration */ udata.chunk_idx = index; udata.curr_idx = 0; udata.ndims = dset->shared->ndims; + udata.nbytes = 0; + udata.filter_mask = 0; + udata.chunk_addr = HADDR_UNDEF; + udata.found = FALSE; /* Iterate over the allocated chunks */ if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__get_chunk_info_cb, &udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve allocated chunk information from index") - /* Obtain requested info */ - if (filter_mask) - *filter_mask = udata.filter_mask; - if (addr) - *addr = udata.chunk_addr; - if (size) - *size = udata.nbytes; - if (offset) - for (ii = 0; ii < udata.ndims; ii++) - offset[ii] = udata.scaled[ii] * dset->shared->layout.u.chunk.dim[ii]; + /* Obtain requested info if the chunk is found */ + if (udata.found) { + if (filter_mask) + *filter_mask = udata.filter_mask; + if (addr) + *addr = udata.chunk_addr; + if (size) + *size = udata.nbytes; + if (offset) + for (ii = 0; ii < udata.ndims; ii++) + offset[ii] = udata.scaled[ii] * dset->shared->layout.u.chunk.dim[ii]; + } + /* otherwise, return HADDR_UNDEF for address and 0 for size */ + else { + if (addr) + *addr = HADDR_UNDEF; + if (size) + *size = 0; + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -6943,24 +7002,28 @@ done: static int H5D__get_chunk_info_by_coord_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) { - hbool_t different = FALSE; -int ii; - int ret_value = H5_ITER_CONT; /* Callback return value */ - + hsize_t ii; H5D_chunk_info_iter_ud_t *chunk_info = (H5D_chunk_info_iter_ud_t *)_udata; + hbool_t different = FALSE; /* TRUE when a scaled value pair mismatch */ + int ret_value = H5_ITER_CONT; /* Callback return value */ FUNC_ENTER_STATIC_NOERR + /* Check args */ + HDassert(chunk_rec); + HDassert(chunk_info); + + /* Going through the scaled, stop when a mismatch is found */ for (ii = 0; ii < chunk_info->ndims && !different; ii++) - { if (chunk_info->scaled[ii] != chunk_rec->scaled[ii]) different = TRUE; - } - if (!different) - { + + /* Same scaled coords means the chunk is found, copy the chunk info */ + if (!different) { chunk_info->nbytes = chunk_rec->nbytes; chunk_info->filter_mask = chunk_rec->filter_mask; chunk_info->chunk_addr = chunk_rec->chunk_addr; + chunk_info->found = TRUE; /* Stop iterating */ ret_value = H5_ITER_STOP; @@ -6987,21 +7050,26 @@ int ii; herr_t H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *offset, unsigned* filter_mask, haddr_t *addr, hsize_t *size) { - const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */ - const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Raw data chunk cache */ - H5D_rdcc_ent_t *ent; /* Cache entry */ - H5D_chunk_info_iter_ud_t udata; - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5O_layout_t *layout = NULL; /* Dataset layout */ + const H5D_rdcc_t *rdcc = NULL; /* Raw data chunk cache */ + H5D_rdcc_ent_t *ent; /* Cache entry index */ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + H5D_chunk_info_iter_ud_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) /* Check args */ - HDassert(dset && H5D_CHUNKED == layout->type); + HDassert(dset); + HDassert(dset->shared); HDassert(offset); - HDassert(filter_mask); - HDassert(addr); /* Question: should some OUT args be allowed to be NULL? */ - HDassert(size); + + /* Get dataset layout and raw data chunk cache */ + layout = &(dset->shared->layout); + rdcc = &(dset->shared->cache.chunk); + HDassert(layout); + HDassert(rdcc); + HDassert(H5D_CHUNKED == layout->type); /* Search for cached chunks that haven't been written out */ for(ent = rdcc->head; ent; ent = ent->next) @@ -7009,28 +7077,52 @@ H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *offset, unsigned* if(H5D__chunk_flush_entry(dset, ent, FALSE) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer") - /* Calculate the scaled of this chunk */ - H5VM_chunk_scaled(dset->shared->ndims, offset, layout->u.chunk.dim, udata.scaled); - udata.scaled[dset->shared->ndims] = 0; - - /* Get the number of dimensions for use in callback function */ - udata.ndims = dset->shared->ndims; - /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout.u.chunk; idx_info.storage = &dset->shared->layout.storage.u.chunk; - /* Iterate over the allocated chunks */ - if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__get_chunk_info_by_coord_cb, &udata) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve allocated chunk information from scaled") + /* If the dataset is not written, return the address as undefined */ + if (idx_info.storage->idx_addr == HADDR_UNDEF) { + if (addr) + *addr = HADDR_UNDEF; + if (size) + *size = 0; + HGOTO_DONE(SUCCEED); + } - /* Return the filter mask and chunk address and size */ - *filter_mask = udata.filter_mask; - *addr = udata.chunk_addr; - *size = udata.nbytes; + /* Calculate the scaled of this chunk */ + H5VM_chunk_scaled(dset->shared->ndims, offset, layout->u.chunk.dim, udata.scaled); + udata.scaled[dset->shared->ndims] = 0; + + /* Initialize before iteration */ + udata.ndims = dset->shared->ndims; + udata.nbytes = 0; + udata.filter_mask = 0; + udata.chunk_addr = HADDR_UNDEF; + udata.found = FALSE; + /* Iterate over the allocated chunks to find the requested chunk */ + if((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__get_chunk_info_by_coord_cb, &udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve information of the chunk by its scaled coordinates") + + /* If the chunk is found, return the filter mask and chunk address/size */ + if (udata.found) { + if (filter_mask) + *filter_mask = udata.filter_mask; + if (addr) + *addr = udata.chunk_addr; + if (size) + *size = udata.nbytes; + } else { + /* Otherwise, return the address as undefined */ + if (addr) + *addr = HADDR_UNDEF; + if (size) + *size = 0; + HGOTO_DONE(SUCCEED); + } done: FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5D__get_chunk_info_by_coord() */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 7d550b5..ee70bae 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -568,7 +568,7 @@ H5_DLL herr_t H5D__get_chunk_storage_size(H5D_t *dset, const hsize_t *offset, hsize_t *storage_size); H5_DLL herr_t H5D__get_num_chunks(const H5D_t *dset, const H5S_t *space, hsize_t *nchunks); H5_DLL herr_t H5D__get_chunk_info(const H5D_t *dset, const H5S_t *space, hsize_t index, hsize_t *coord, unsigned *filter_mask, haddr_t *offset, hsize_t *size); -H5_DLL herr_t H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *coord, unsigned* filter_mask, haddr_t *addr, hsize_t *size); +H5_DLL herr_t H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *coord, unsigned *filter_mask, haddr_t *addr, hsize_t *size); H5_DLL haddr_t H5D__get_offset(const H5D_t *dset); H5_DLL void *H5D__vlen_get_buf_size_alloc(size_t size, void *info); H5_DLL herr_t H5D__vlen_get_buf_size(void *elem, hid_t type_id, unsigned ndim, diff --git a/test/dsets.c b/test/dsets.c index e8d86d1..b16459b 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -271,6 +271,7 @@ const char *FILENAME[] = { /* Parameters for testing chunk querying */ #define DSET_SIMPLE_CHUNKED "Chunked Dataset" +#define DSET_EMPTY "Empty Dataset" #define RANK 2 #define NX 16 #define NY 16 @@ -12900,8 +12901,8 @@ error: * Purpose: Tests various format versions. * (Currently, only virtual dataset feature) * - * Return: Success: 0 - * Failure: -1 + * Return: Success: SUCCEED + * Failure: FAIL * Description: * This function attempts to create a virtual dataset in all * valid combinations of low/high library format bounds. Creation @@ -13030,7 +13031,7 @@ test_versionbounds() TEST_ERROR dcpl = -1; PASSED(); - return 0; + return SUCCEED; error: H5E_BEGIN_TRY { @@ -13043,7 +13044,7 @@ test_versionbounds() H5Fclose(srcfile); H5Fclose(vfile); } H5E_END_TRY; - return -1; + return FAIL; } /* test_versionbounds() */ /*------------------------------------------------------------------------- @@ -13077,7 +13078,7 @@ static herr_t read_each_chunk(hid_t dset_id, hsize_t offset1, hsize_t offset2, u /* Verify that read chunk is the same as the corresponding written one */ if (HDmemcmp(direct_buf, read_buf, CHUNK_NX*CHUNK_NY) != 0) { - fprintf(stderr, "Read chunk differs than written chunk at offset (%d,%d)\n", offset1, offset2); + HDfprintf(stderr, "Read chunk differs from written chunk at offset (%d,%d)\n", offset1, offset2); return(FAIL); } @@ -13098,9 +13099,12 @@ static herr_t read_each_chunk(hid_t dset_id, hsize_t offset1, hsize_t offset2, u */ void reinit_vars(unsigned *read_filter_mask, hsize_t *addr, hsize_t *size) { - if (read_filter_mask) *read_filter_mask = 0; - if (addr) *addr = 0; - if (size) *size = 0; + if (read_filter_mask) + *read_filter_mask = 0; + if (addr) + *addr = 0; + if (size) + *size = 0; } /*------------------------------------------------------------------------- @@ -13111,6 +13115,10 @@ void reinit_vars(unsigned *read_filter_mask, hsize_t *addr, hsize_t *size) * Return: Success: 0 * Failure: 1 * + * Description: + * This function tests the new API functions added for EED-343: + * H5Dget_num_chunks, H5Dget_chunk_info, and H5Dget_chunk_info_by_coord. + * * Date: September 2018 * *------------------------------------------------------------------------- @@ -13265,6 +13273,14 @@ test_get_chunk_info() if (size != CHUNK_SIZE) TEST_ERROR; if (out_offset[0] != 4 || out_offset[1] != 12) TEST_ERROR; + /* Attempt to get info of empty chunk and verify the returned address and size */ + index = 5; + reinit_vars(&read_filter_mask, &addr, &size); + if (H5Dget_chunk_info(dset, fspace, index, out_offset, &read_filter_mask, &addr, &size) < 0) + TEST_ERROR + if (addr != HADDR_UNDEF) TEST_ERROR; + if (size != 0) TEST_ERROR; + /* Get info of the chunk at logical coordinates (0,2) */ offset[0] = 0; offset[1] = 2 * CHUNK_NY; @@ -13279,23 +13295,67 @@ test_get_chunk_info() if (read_filter_mask != filter_mask) TEST_ERROR; if (size != CHUNK_SIZE) TEST_ERROR; - /* Read each chunk and print the values */ + /* Attempt to get info of empty chunks, verify the returned address and size */ + offset[0] = 0; + offset[1] = 0; + if (H5Dget_chunk_info_by_coord(dset, offset, &read_filter_mask, &addr, &size) < 0) TEST_ERROR; + if (addr != HADDR_UNDEF) TEST_ERROR; + if (size != 0) TEST_ERROR; + + offset[0] = 3 * CHUNK_NX; + offset[1] = 3 * CHUNK_NY; + if (H5Dget_chunk_info_by_coord(dset, offset, &read_filter_mask, &addr, &size) < 0) TEST_ERROR; + if (addr != HADDR_UNDEF) TEST_ERROR; + if (size != 0) TEST_ERROR; + + /* Read each chunk and verify the values */ n = 0; for (i = 0; i < 2; i++) for (j = 2; j < 4; j++, n++) if (read_each_chunk(dset, i*CHUNK_NX, j*CHUNK_NY, filter_mask, (void*)direct_buf[n]) < 0) TEST_ERROR + /* Close the first dataset */ + if (H5Dclose(dset) < 0) TEST_ERROR + + /* Create an empty dataset */ + if((dset = H5Dcreate2(chunkfile, DSET_EMPTY, H5T_NATIVE_INT, fspace, + H5P_DEFAULT, cparms, H5P_DEFAULT)) < 0) TEST_ERROR + if (H5Dclose(dset) < 0) TEST_ERROR + + /* Reopen the empty dataset to verify the chunk query functions on it */ + if((dset = H5Dopen2(chunkfile, DSET_EMPTY, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Verify that the number of chunks is 0 */ + if (H5Dget_num_chunks(dset, mspace, &nchunks) < 0) TEST_ERROR; + if (nchunks != 0) TEST_ERROR; + + /* Attempt to get info of a chunk from an empty dataset, verify the + returned address and size */ + index = 0; + reinit_vars(&read_filter_mask, &addr, &size); + if (H5Dget_chunk_info(dset, fspace, index, out_offset, &read_filter_mask, &addr, &size) < 0) + TEST_ERROR + if (addr != HADDR_UNDEF) TEST_ERROR; + if (size != 0) TEST_ERROR; + + /* Attempt to get info of a chunk given its coords from an empty dataset, + verify the returned address and size */ + offset[0] = 0; + offset[1] = 0; + if (H5Dget_chunk_info_by_coord(dset, offset, &read_filter_mask, &addr, &size) < 0) TEST_ERROR; + if (addr != HADDR_UNDEF) TEST_ERROR; + if (size != 0) TEST_ERROR; + /* Close/release resources. */ - H5Dclose(dset); - H5Sclose(mspace); - H5Sclose(fspace); - H5Pclose(cparms); - H5Pclose(dxpl); - H5Fclose(chunkfile); + if (H5Sclose(mspace) < 0) TEST_ERROR + if (H5Sclose(fspace) < 0) TEST_ERROR + if (H5Pclose(cparms) < 0) TEST_ERROR + if (H5Pclose(dxpl) < 0) TEST_ERROR + if (H5Fclose(chunkfile) < 0) TEST_ERROR PASSED(); - return 0; + return SUCCEED; error: H5E_BEGIN_TRY { @@ -13307,7 +13367,7 @@ error: } H5E_END_TRY; H5_FAILED(); - return 1; + return FAIL; } /* test_get_chunk_info() */ -- cgit v0.12