From 47e4e67e3cd11f99ac417613eed9f47e65f55468 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 2 Jul 2009 16:10:35 -0500 Subject: [svn-r17146] Description: Bring a bunch of misc. improvements & tweaks from the revise_chunks branch back to the trunk, so that future merges won't be so painful. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.7 (amazon) in debug mode Mac OS X/32 10.5.7 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- src/H5AC.c | 2 +- src/H5Dbtree.c | 71 +++++++-------- src/H5Dchunk.c | 271 +++++++++++++++++++++++++++++++++++-------------------- src/H5Dcompact.c | 8 +- src/H5Dcontig.c | 7 +- src/H5Defl.c | 8 +- src/H5Dint.c | 39 +++++--- src/H5Doh.c | 20 +++- src/H5Dpkg.h | 31 ++++--- src/H5Dprivate.h | 5 +- src/H5F.c | 11 ++- src/H5Fpkg.h | 2 +- src/H5Olayout.c | 11 ++- src/H5Pdcpl.c | 3 +- test/dsets.c | 42 +++++---- test/tfile.c | 17 ++-- 16 files changed, 330 insertions(+), 218 deletions(-) diff --git a/src/H5AC.c b/src/H5AC.c index 145daa5..17ae55f 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -1623,7 +1623,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5AC_mark_pinned_entry_dirty() */ +} /* H5AC_mark_pinned_or_protected_entry_dirty() */ /*------------------------------------------------------------------------- diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index b0988c1..a22b0b1 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -16,29 +16,10 @@ /* Programmer: Robb Matzke * Wednesday, October 8, 1997 * - * Purpose: v1 B-tree indexed (chunked) I/O functions. The logical - * multi-dimensional data space is regularly partitioned into - * same-sized "chunks", the first of which is aligned with the - * logical origin. The chunks are given a multi-dimensional - * index which is used as a lookup key in a B-tree that maps - * chunk index to disk address. Each chunk can be compressed - * independently and the chunks may move around in the file as - * their storage requirements change. - * - * Cache: Disk I/O is performed in units of chunks and H5MF_alloc() - * contains code to optionally align chunks on disk block - * boundaries for performance. - * - * The chunk cache is an extendible hash indexed by a function - * of storage B-tree address and chunk N-dimensional offset - * within the dataset. Collisions are not resolved -- one of - * the two chunks competing for the hash slot must be preempted - * from the cache. All entries in the hash also participate in - * a doubly-linked list and entries are penalized by moving them - * toward the front of the list. When a new chunk is about to - * be added to the cache the heap is pruned by preempting - * entries near the front of the list to make room for the new - * entry which is added to the end of the list. + * Purpose: v1 B-tree indexed (chunked) I/O functions. The chunks are + * given a multi-dimensional index which is used as a lookup key + * in a B-tree that maps chunk index to disk address. + * */ /****************/ @@ -154,7 +135,8 @@ static herr_t H5D_btree_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id, int indent, int fwidth, const void *key, const void *udata); /* Chunked layout indexing callbacks */ -static herr_t H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info); +static herr_t H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info, + haddr_t dset_ohdr_addr); static herr_t H5D_btree_idx_create(const H5D_chk_idx_info_t *idx_info); static hbool_t H5D_btree_idx_is_space_alloc(const H5O_layout_t *layout); static herr_t H5D_btree_idx_insert(const H5D_chk_idx_info_t *idx_info, @@ -169,10 +151,10 @@ static herr_t H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info); static herr_t H5D_btree_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src, const H5D_chk_idx_info_t *idx_info_dst); static herr_t H5D_btree_idx_copy_shutdown(H5O_layout_t *layout_src, - H5O_layout_t *layout_dst); + H5O_layout_t *layout_dst, hid_t dxpl_id); static herr_t H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *size); -static herr_t H5D_btree_idx_reset(H5O_layout_t *layout); +static herr_t H5D_btree_idx_reset(H5O_layout_t *layout, hbool_t reset_addr); static herr_t H5D_btree_idx_dump(const H5D_chk_idx_info_t *idx_info, FILE *stream); static herr_t H5D_btree_idx_dest(const H5D_chk_idx_info_t *idx_info); @@ -861,7 +843,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info) +H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info, haddr_t UNUSED dset_ohdr_addr) { herr_t ret_value = SUCCEED; /* Return value */ @@ -870,7 +852,9 @@ H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info) /* Check args */ HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); + HDassert(H5F_addr_defined(dset_ohdr_addr)); /* Allocate the shared structure */ if(H5D_btree_shared_create(idx_info->f, idx_info->layout) < 0) @@ -910,6 +894,7 @@ H5D_btree_idx_create(const H5D_chk_idx_info_t *idx_info) /* Check args */ HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); HDassert(!H5F_addr_defined(idx_info->layout->u.chunk.u.btree.addr)); @@ -976,6 +961,7 @@ H5D_btree_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata) HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); HDassert(H5F_addr_defined(idx_info->layout->u.chunk.u.btree.addr)); HDassert(udata); @@ -1015,6 +1001,7 @@ H5D_btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); HDassert(idx_info->layout->u.chunk.ndims > 0); HDassert(udata); @@ -1079,7 +1066,7 @@ H5D_btree_idx_iterate_cb(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, /*------------------------------------------------------------------------- * Function: H5D_btree_idx_iterate * - * Purpose: Iterate over the chunks in the B-tree index, making a callback + * Purpose: Iterate over the chunks in an index, making a callback * for each one. * * Return: Non-negative on success/Negative on failure @@ -1100,6 +1087,7 @@ H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info, HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); HDassert(H5F_addr_defined(idx_info->layout->u.chunk.u.btree.addr)); HDassert(chunk_cb); @@ -1122,7 +1110,7 @@ H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info, /*------------------------------------------------------------------------- * Function: H5D_btree_idx_remove * - * Purpose: Remove chunk from v1 B-tree index. + * Purpose: Remove chunk from index. * * Return: Non-negative on success/Negative on failure * @@ -1140,6 +1128,7 @@ H5D_btree_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t * HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); HDassert(H5F_addr_defined(idx_info->layout->u.chunk.u.btree.addr)); HDassert(udata); @@ -1158,7 +1147,7 @@ done: /*------------------------------------------------------------------------- * Function: H5D_btree_idx_delete * - * Purpose: Delete v1 B-tree index and raw data storage for entire dataset + * Purpose: Delete index and raw data storage for entire dataset * (i.e. all chunks) * * Return: Success: Non-negative @@ -1179,6 +1168,7 @@ H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info) /* Sanity checks */ HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); /* Check if the index data structure has been allocated */ @@ -1233,9 +1223,11 @@ H5D_btree_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src, HDassert(idx_info_src); HDassert(idx_info_src->f); + HDassert(idx_info_src->pline); HDassert(idx_info_src->layout); HDassert(idx_info_dst); HDassert(idx_info_dst->f); + HDassert(idx_info_dst->pline); HDassert(idx_info_dst->layout); HDassert(!H5F_addr_defined(idx_info_dst->layout->u.chunk.u.btree.addr)); @@ -1268,7 +1260,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_btree_idx_copy_shutdown(H5O_layout_t *layout_src, H5O_layout_t *layout_dst) +H5D_btree_idx_copy_shutdown(H5O_layout_t *layout_src, H5O_layout_t *layout_dst, + hid_t UNUSED dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1291,7 +1284,7 @@ done: /*------------------------------------------------------------------------- * Function: H5D_btree_idx_size * - * Purpose: Retrieve the amount of B-tree storage for chunked dataset + * Purpose: Retrieve the amount of index storage for chunked dataset * * Return: Success: Non-negative * Failure: negative @@ -1301,10 +1294,10 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size) { - H5D_btree_ud0_t udata; /* User-data for loading btree nodes */ + H5D_btree_ud0_t udata; /* User-data for loading B-tree nodes */ H5B_info_t bt_info; /* B-tree info */ hbool_t shared_init = FALSE; /* Whether shared B-tree info is initialized */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1314,6 +1307,7 @@ H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size) /* Check args */ HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); HDassert(index_size); @@ -1322,7 +1316,7 @@ H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") shared_init = TRUE; - /* Initialize btree node user-data */ + /* Initialize B-tree node user-data */ HDmemset(&udata, 0, sizeof udata); udata.mesg = idx_info->layout; @@ -1358,14 +1352,15 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_btree_idx_reset(H5O_layout_t *layout) +H5D_btree_idx_reset(H5O_layout_t *layout, hbool_t reset_addr) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_idx_reset) HDassert(layout); /* Reset index info */ - layout->u.chunk.u.btree.addr = HADDR_UNDEF; + if(reset_addr) + layout->u.chunk.u.btree.addr = HADDR_UNDEF; layout->u.chunk.u.btree.shared = NULL; FUNC_LEAVE_NOAPI(SUCCEED) @@ -1391,6 +1386,7 @@ H5D_btree_idx_dump(const H5D_chk_idx_info_t *idx_info, FILE *stream) HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); HDassert(stream); @@ -1421,6 +1417,7 @@ H5D_btree_idx_dest(const H5D_chk_idx_info_t *idx_info) HDassert(idx_info); HDassert(idx_info->f); + HDassert(idx_info->pline); HDassert(idx_info->layout); /* Free the raw B-tree node buffer */ diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 1b38a70..5c99c90 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -13,6 +13,33 @@ * access to either file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Programmer: Quincey Koziol + * Thursday, April 24, 2008 + * + * Purpose: Abstract indexed (chunked) I/O functions. The logical + * multi-dimensional data space is regularly partitioned into + * same-sized "chunks", the first of which is aligned with the + * logical origin. The chunks are indexed by different methods, + * that map a chunk index to disk address. Each chunk can be + * compressed independently and the chunks may move around in the + * file as their storage requirements change. + * + * Cache: Disk I/O is performed in units of chunks and H5MF_alloc() + * contains code to optionally align chunks on disk block + * boundaries for performance. + * + * The chunk cache is an extendible hash indexed by a function + * of storage B-tree address and chunk N-dimensional offset + * within the dataset. Collisions are not resolved -- one of + * the two chunks competing for the hash slot must be preempted + * from the cache. All entries in the hash also participate in + * a doubly-linked list and entries are penalized by moving them + * toward the front of the list. When a new chunk is about to + * be added to the cache the heap is pruned by preempting + * entries near the front of the list to make room for the new + * entry which is added to the end of the list. + */ + /****************/ /* Module Setup */ /****************/ @@ -146,8 +173,7 @@ typedef struct H5D_chunk_it_ud4_t { /********************/ /* Chunked layout operation callbacks */ -static herr_t H5D_chunk_construct(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, H5D_t *dset, - const H5P_genplist_t *dc_plist); +static herr_t H5D_chunk_construct(H5F_t *f, H5D_t *dset); static herr_t H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm); @@ -190,6 +216,7 @@ static herr_t H5D_chunk_mem_cb(void *elem, hid_t type_id, unsigned ndims, /* Chunked storage layout I/O ops */ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{ H5D_chunk_construct, + H5D_chunk_init, H5D_chunk_is_space_alloc, H5D_chunk_io_init, H5D_chunk_read, @@ -215,6 +242,7 @@ const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{ NULL, NULL, NULL, + NULL, #ifdef H5_HAVE_PARALLEL NULL, NULL, @@ -227,7 +255,7 @@ const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{ /* Declare a free list to manage the H5F_rdcc_ent_ptr_t sequence information */ H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t); -/* Declare a free list to manage H5F_rdcc_ent_t objects */ +/* Declare a free list to manage H5D_rdcc_ent_t objects */ H5FL_DEFINE_STATIC(H5D_rdcc_ent_t); /* Declare a free list to manage the H5D_chunk_info_t struct */ @@ -254,8 +282,7 @@ H5FL_DEFINE_STATIC(H5D_chunk_prune_stack_t); *------------------------------------------------------------------------- */ static herr_t -H5D_chunk_construct(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, H5D_t *dset, - const H5P_genplist_t *dc_plist) +H5D_chunk_construct(H5F_t *f, H5D_t *dset) { const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */ hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */ @@ -269,7 +296,6 @@ H5D_chunk_construct(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, H5D_t *dset, /* Sanity checks */ HDassert(f); HDassert(dset); - HDassert(dc_plist); /* Set up layout information */ if((ndims = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0) @@ -314,9 +340,9 @@ H5D_chunk_construct(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, H5D_t *dset, /* Retain computed chunk size */ H5_ASSIGN_OVERFLOW(dset->shared->layout.u.chunk.size, chunk_size, uint64_t, uint32_t); - /* Initialize the chunk cache for the dataset */ - if(H5D_chunk_init(f, dapl_id, dxpl_id, dset) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize chunk cache") + /* Reset address and pointer of the array struct for the chunked storage index */ + if(H5D_chunk_idx_reset(&dset->shared->layout, TRUE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to reset chunked storage index") done: FUNC_LEAVE_NOAPI(ret_value) @@ -324,6 +350,79 @@ done: /*------------------------------------------------------------------------- + * Function: H5D_chunk_init + * + * Purpose: Initialize the raw data chunk cache for a dataset. This is + * called when the dataset is initialized. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, May 18, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id) +{ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Convenience pointer to dataset's chunk cache */ + H5P_genplist_t *dapl; /* Data access property list object pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_chunk_init, FAIL) + + /* Sanity check */ + HDassert(f); + HDassert(dset); + + if(NULL == (dapl = (H5P_genplist_t *)H5I_object(dapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for fapl ID"); + + /* Use the properties in dapl_id if they have been set, otherwise use the properties from the file */ + if(H5P_get(dapl, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &rdcc->nslots) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache number of slots"); + if(rdcc->nslots == H5D_CHUNK_CACHE_NSLOTS_DEFAULT) + rdcc->nslots = H5F_RDCC_NSLOTS(f); + + if(H5P_get(dapl, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc->nbytes_max) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache byte size"); + if(rdcc->nbytes_max == H5D_CHUNK_CACHE_NBYTES_DEFAULT) + rdcc->nbytes_max = H5F_RDCC_NBYTES(f); + + if(H5P_get(dapl, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &rdcc->w0) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get preempt read chunks"); + if(rdcc->w0 < 0) + rdcc->w0 = H5F_RDCC_W0(f); + + /* If nbytes_max or nslots is 0, set them both to 0 and avoid allocating space */ + if(!rdcc->nbytes_max || !rdcc->nslots) + rdcc->nbytes_max = rdcc->nslots = 0; + else { + rdcc->slot = H5FL_SEQ_CALLOC(H5D_rdcc_ent_ptr_t, rdcc->nslots); + if(NULL == rdcc->slot) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Reset any cached chunk info for this dataset */ + H5D_chunk_cinfo_cache_reset(&(rdcc->last)); + } /* end else */ + + /* Compose chunked index info struct */ + idx_info.f = f; + idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; + idx_info.layout = &dset->shared->layout; + + /* Allocate any indexing structures */ + if(dset->shared->layout.u.chunk.ops->init && (dset->shared->layout.u.chunk.ops->init)(&idx_info, dset->oloc.addr) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize indexing information") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_chunk_init() */ + + +/*------------------------------------------------------------------------- * Function: H5D_chunk_is_space_alloc * * Purpose: Query if space is allocated for layout @@ -1653,7 +1752,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_info_t *chunk_info; /* Chunk information */ H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */ void *chunk; /* Pointer to locked chunk buffer */ - H5D_chunk_ud_t udata; /* B-tree pass-through */ + H5D_chunk_ud_t udata; /* Index pass-through */ htri_t cacheable; /* Whether the chunk is cacheable */ /* Get the actual chunk information from the skip list node */ @@ -1698,6 +1797,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Compose chunked index info struct */ idx_info.f = io_info->dset->oloc.file; idx_info.dxpl_id = io_info->dxpl_id; + idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline); idx_info.layout = &(io_info->dset->shared->layout); /* Set up the size of chunk for user data */ @@ -1795,78 +1895,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5D_chunk_init - * - * Purpose: Initialize the raw data chunk cache for a dataset. This is - * called when the dataset is initialized. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, May 18, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D_chunk_init(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, const H5D_t *dset) -{ - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Convenience pointer to dataset's chunk cache */ - H5P_genplist_t *dapl; /* Data access property list object pointer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5D_chunk_init, FAIL) - - /* Sanity check */ - HDassert(f); - HDassert(dset); - - if(NULL == (dapl = (H5P_genplist_t *)H5I_object(dapl_id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for fapl ID"); - - /* Use the properties in dapl_id if they have been set, otherwise use the properties from the file */ - if(H5P_get(dapl, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &rdcc->nslots) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache number of slots"); - if(rdcc->nslots == H5D_CHUNK_CACHE_NSLOTS_DEFAULT) - rdcc->nslots = H5F_RDCC_NSLOTS(f); - - if(H5P_get(dapl, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc->nbytes_max) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache byte size"); - if(rdcc->nbytes_max == H5D_CHUNK_CACHE_NBYTES_DEFAULT) - rdcc->nbytes_max = H5F_RDCC_NBYTES(f); - - if(H5P_get(dapl, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &rdcc->w0) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get preempt read chunks"); - if(rdcc->w0 < 0) - rdcc->w0 = H5F_RDCC_W0(f); - - /* If nbytes_max or nslots is 0, set them both to 0 and avoid allocating space */ - if(!rdcc->nbytes_max || !rdcc->nslots) - rdcc->nbytes_max = rdcc->nslots = 0; - else { - rdcc->slot = H5FL_SEQ_CALLOC(H5D_rdcc_ent_ptr_t, rdcc->nslots); - if(NULL == rdcc->slot) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Reset any cached chunk info for this dataset */ - H5D_chunk_cinfo_cache_reset(&(rdcc->last)); - } /* end else */ - - /* Compose chunked index info struct */ - idx_info.f = f; - idx_info.dxpl_id = dxpl_id; - idx_info.layout = &dset->shared->layout; - - /* Allocate any indexing structures */ - if((dset->shared->layout.u.chunk.ops->init)(&idx_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize indexing information") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_chunk_init() */ - - -/*------------------------------------------------------------------------- * Function: H5D_chunk_idx_reset * * Purpose: Reset index information @@ -1879,7 +1907,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D_chunk_idx_reset(H5O_layout_t *layout) +H5D_chunk_idx_reset(H5O_layout_t *layout, hbool_t reset_addr) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1890,7 +1918,7 @@ H5D_chunk_idx_reset(H5O_layout_t *layout) HDassert(layout->u.chunk.ops); /* Reset index structures */ - if((layout->u.chunk.ops->reset)(layout) < 0) + if((layout->u.chunk.ops->reset)(layout, reset_addr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset chunk index info") done: @@ -2051,6 +2079,7 @@ H5D_chunk_create(H5D_t *dset /*in,out*/, hid_t dxpl_id) /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; /* Create the index for the chunks */ @@ -2105,6 +2134,7 @@ H5D_chunk_get_info(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; /* Go get the chunk information */ @@ -2146,6 +2176,7 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t * FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_flush_entry) HDassert(dset); + HDassert(dset->shared); HDassert(dxpl_cache); HDassert(ent); HDassert(!ent->locked); @@ -2216,6 +2247,7 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t * /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; /* Create the chunk it if it doesn't exist, or reallocate the chunk @@ -2231,7 +2263,7 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t * /* Write the data to the file */ HDassert(H5F_addr_defined(udata.addr)); if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.nbytes, dxpl_id, buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file") + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write raw data to file") /* Cache the chunk's info, in case it's accessed again shortly */ H5D_chunk_cinfo_cache_update(&dset->shared->cache.chunk.last, &udata); @@ -2451,7 +2483,7 @@ done: * directly into the chunk cache and should not be freed * by the caller but will be valid until it is unlocked. The * input value IDX_HINT is used to speed up cache lookups and - * it's output value should be given to H5F_chunk_unlock(). + * it's output value should be given to H5D_chunk_unlock(). * IDX_HINT is ignored if it is out of range, and if it points * to the wrong entry then we fall back to the normal search * method. @@ -2654,6 +2686,8 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, rdcc->head = rdcc->tail = ent; ent->prev = NULL; } /* end else */ + + /* Indicate that the chunk is in the cache now */ found = TRUE; } else if(!found) { /* @@ -2757,16 +2791,16 @@ H5D_chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, * don't discard the `const' qualifier. */ if(dirty) { - H5D_rdcc_ent_t x; + H5D_rdcc_ent_t fake_ent; /* "fake" chunk cache entry */ - HDmemset(&x, 0, sizeof(x)); - x.dirty = TRUE; - HDmemcpy(x.offset, io_info->store->chunk.offset, layout->u.chunk.ndims * sizeof(x.offset[0])); + HDmemset(&fake_ent, 0, sizeof(fake_ent)); + fake_ent.dirty = TRUE; + HDmemcpy(fake_ent.offset, io_info->store->chunk.offset, layout->u.chunk.ndims * sizeof(fake_ent.offset[0])); HDassert(layout->u.chunk.size > 0); - x.chunk_addr = udata->addr; - x.chunk = (uint8_t *)chunk; + fake_ent.chunk_addr = udata->addr; + fake_ent.chunk = (uint8_t *)chunk; - if(H5D_chunk_flush_entry(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, &x, TRUE) < 0) + if(H5D_chunk_flush_entry(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, &fake_ent, TRUE) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer") } /* end if */ else { @@ -2902,6 +2936,7 @@ H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes) FUNC_ENTER_NOAPI(H5D_chunk_allocated, FAIL) HDassert(dset); + HDassert(dset->shared); /* Fill the DXPL cache values for later use */ if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) @@ -2917,9 +2952,10 @@ H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes) /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; - /* Call the index-specific "get all the allocated chunks sizes" routine */ + /* Iterate over the chunks */ if((dset->shared->layout.u.chunk.ops->iterate)(&idx_info, H5D_chunk_allocated_cb, &chunk_bytes) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve allocated chunk information from index") @@ -3067,6 +3103,7 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite) /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; /* Reset the chunk offset indices */ @@ -3599,6 +3636,7 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims) /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; /* Initialize the user data for the iteration */ @@ -3787,6 +3825,7 @@ H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[], FUNC_ENTER_NOAPI(H5D_chunk_addrmap, FAIL) HDassert(dset); + HDassert(dset->shared); HDassert(chunk_addr); HDassert(down_chunks); @@ -3825,16 +3864,34 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout) +H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_layout_t *layout) { H5D_chk_idx_info_t idx_info; /* Chunked index info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5O_pline_t pline; /* I/O pipeline message */ + htri_t exists; /* Flag if header message of interest exists */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_chunk_delete, FAIL) + /* Sanity check */ + HDassert(f); + HDassert(oh); + HDassert(layout); + + /* Check for I/O pipeline message */ + if((exists = H5O_msg_exists_oh(oh, H5O_PLINE_ID)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header") + else if(exists) { + if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_PLINE_ID, &pline)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find I/O pipeline message") + } /* end else if */ + else + HDmemset(&pline, 0, sizeof(pline)); + /* Compose chunked index info struct */ idx_info.f = f; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &pline; idx_info.layout = layout; /* Delete the chunked storage information in the file */ @@ -4137,11 +4194,13 @@ done: herr_t H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, - H5O_pline_t *pline, hid_t dxpl_id) + H5O_pline_t *pline_src, hid_t dxpl_id) { H5D_chunk_it_ud3_t udata; /* User data for iteration callback */ H5D_chk_idx_info_t idx_info_dst; /* Dest. chunked index info */ H5D_chk_idx_info_t idx_info_src; /* Source chunked index info */ + H5O_pline_t _pline; /* Temporary pipeline info */ + H5O_pline_t *pline; /* Pointer to pipeline info to use */ H5T_path_t *tpath_src_mem = NULL, *tpath_mem_dst = NULL; /* Datatype conversion paths */ hid_t tid_src = -1; /* Datatype ID for source datatype */ hid_t tid_dst = -1; /* Datatype ID for destination datatype */ @@ -4167,13 +4226,23 @@ H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, HDassert(layout_dst && H5D_CHUNKED == layout_dst->type); HDassert(dt_src); + /* Initialize the temporary pipeline info */ + if(NULL == pline_src) { + HDmemset(&_pline, 0, sizeof(_pline)); + pline = &_pline; + } /* end if */ + else + pline = pline_src; + /* Compose source & dest chunked index info structs */ idx_info_src.f = f_src; idx_info_src.dxpl_id = dxpl_id; + idx_info_src.pline = pline; idx_info_src.layout = layout_src; idx_info_dst.f = f_dst; idx_info_dst.dxpl_id = dxpl_id; + idx_info_dst.pline = pline; /* Use same I/O filter pipeline for dest. */ idx_info_dst.layout = layout_dst; /* Call the index-specific "copy setup" routine */ @@ -4330,7 +4399,7 @@ done: /* Clean up any index information */ if(copy_setup_done) - if((layout_src->u.chunk.ops->copy_shutdown)(layout_src, layout_dst) < 0) + if((layout_src->u.chunk.ops->copy_shutdown)(layout_src, layout_dst, dxpl_id) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to shut down index copying info") FUNC_LEAVE_NOAPI(ret_value) @@ -4352,7 +4421,7 @@ done: */ herr_t H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout, - hsize_t *index_size) + const H5O_pline_t *pline, hsize_t *index_size) { H5D_chk_idx_info_t idx_info; /* Chunked index info */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4362,11 +4431,13 @@ H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout, /* Check args */ HDassert(f); HDassert(layout); + HDassert(pline); HDassert(index_size); /* Compose chunked index info struct */ idx_info.f = f; idx_info.dxpl_id = dxpl_id; + idx_info.pline = pline; idx_info.layout = layout; /* Get size of index structure */ @@ -4456,6 +4527,7 @@ H5D_chunk_dump_index(H5D_t *dset, hid_t dxpl_id, FILE *stream) /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; /* Display info for index */ @@ -4527,6 +4599,7 @@ H5D_chunk_dest(H5F_t *f, hid_t dxpl_id, H5D_t *dset) /* Compose chunked index info struct */ idx_info.f = f; idx_info.dxpl_id = dxpl_id; + idx_info.pline = &dset->shared->dcpl_cache.pline; idx_info.layout = &dset->shared->layout; /* Free any index structures */ diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index f773f5f..09abee0 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -57,8 +57,7 @@ /********************/ /* Layout operation callbacks */ -static herr_t H5D_compact_construct(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, H5D_t *dset, - const H5P_genplist_t *dc_plist); +static herr_t H5D_compact_construct(H5F_t *f, H5D_t *dset); static hbool_t H5D_compact_is_space_alloc(const H5O_layout_t *layout); static herr_t H5D_compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, @@ -78,6 +77,7 @@ static ssize_t H5D_compact_writevv(const H5D_io_info_t *io_info, /* Compact storage layout I/O ops */ const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{ H5D_compact_construct, + NULL, H5D_compact_is_space_alloc, H5D_compact_io_init, H5D_contig_read, @@ -167,8 +167,7 @@ done: */ /* ARGSUSED */ static herr_t -H5D_compact_construct(H5F_t *f, hid_t UNUSED dapl_id, hid_t UNUSED dxpl_id, H5D_t *dset, - const H5P_genplist_t UNUSED *dc_plist) +H5D_compact_construct(H5F_t *f, H5D_t *dset) { hssize_t tmp_size; /* Temporary holder for raw data size */ hsize_t comp_data_size; /* Size of compact data */ @@ -179,7 +178,6 @@ H5D_compact_construct(H5F_t *f, hid_t UNUSED dapl_id, hid_t UNUSED dxpl_id, H5D_ /* Sanity checks */ HDassert(f); HDassert(dset); - HDassert(dc_plist); /* * Compact dataset is stored in dataset object header message of diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 1275ee1..887f37a 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -61,8 +61,7 @@ /********************/ /* Layout operation callbacks */ -static herr_t H5D_contig_construct(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, H5D_t *dset, - const H5P_genplist_t *dc_plist); +static herr_t H5D_contig_construct(H5F_t *f, H5D_t *dset); static hbool_t H5D_contig_is_space_alloc(const H5O_layout_t *layout); static herr_t H5D_contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, @@ -80,6 +79,7 @@ static herr_t H5D_contig_write_one(H5D_io_info_t *io_info, hsize_t offset, /* Contiguous storage layout I/O ops */ const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{ H5D_contig_construct, + NULL, H5D_contig_is_space_alloc, H5D_contig_io_init, H5D_contig_read, @@ -373,8 +373,7 @@ H5D_contig_get_addr(const H5D_t *dset) */ /* ARGSUSED */ static herr_t -H5D_contig_construct(H5F_t *f, hid_t UNUSED dapl_id, hid_t UNUSED dxpl_id, H5D_t *dset, - const H5P_genplist_t UNUSED *dc_plist) +H5D_contig_construct(H5F_t *f, H5D_t *dset) { hssize_t snelmts; /* Temporary holder for number of elements in dataspace */ hsize_t nelmts; /* Number of elements in dataspace */ diff --git a/src/H5Defl.c b/src/H5Defl.c index a22ca2d..cb31630 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -49,8 +49,7 @@ /********************/ /* Layout operation callbacks */ -static herr_t H5D_efl_construct(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, H5D_t *dset, - const H5P_genplist_t *dc_plist); +static herr_t H5D_efl_construct(H5F_t *f, H5D_t *dset); static hbool_t H5D_efl_is_space_alloc(const H5O_layout_t *layout); static herr_t H5D_efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, @@ -76,6 +75,7 @@ static herr_t H5D_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size, /* External File List (EFL) storage layout I/O ops */ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{ H5D_efl_construct, + NULL, H5D_efl_is_space_alloc, H5D_efl_io_init, H5D_contig_read, @@ -109,8 +109,7 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{ *------------------------------------------------------------------------- */ static herr_t -H5D_efl_construct(H5F_t *f, hid_t UNUSED dapl_id, hid_t UNUSED dxpl_id, H5D_t *dset, - const H5P_genplist_t *dc_plist) +H5D_efl_construct(H5F_t *f, H5D_t *dset) { size_t dt_size; /* Size of datatype */ hsize_t dim[H5O_LAYOUT_NDIMS]; /* Current size of data in elements */ @@ -127,7 +126,6 @@ H5D_efl_construct(H5F_t *f, hid_t UNUSED dapl_id, hid_t UNUSED dxpl_id, H5D_t *d /* Sanity checks */ HDassert(f); HDassert(dset); - HDassert(dc_plist); /* * The maximum size of the dataset cannot exceed the storage size. diff --git a/src/H5Dint.c b/src/H5Dint.c index 36ad640..7247b46 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -65,7 +65,8 @@ static herr_t H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type); static herr_t H5D_init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space); static herr_t H5D_set_io_ops(H5D_t *dataset); -static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset); +static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, + hid_t dapl_id); static herr_t H5D_open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id); static herr_t H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags); @@ -756,7 +757,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) +H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) { H5O_t *oh = NULL; /* Pointer to dataset's object header */ size_t ohdr_size = H5D_MINHDR_SIZE; /* Size of dataset's object header */ @@ -767,6 +768,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) H5O_fill_t *fill_prop; /* Pointer to dataset's fill value information */ H5D_fill_value_t fill_status; /* Fill value status */ hbool_t fill_changed = FALSE; /* Flag indicating the fill value was changed */ + hbool_t layout_init = FALSE; /* Flag to indicate that chunk information was initialized */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_update_oh_info) @@ -883,6 +885,13 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message") } /* end if */ + /* Initialize the layout information for the new dataset */ + if(dset->shared->layout.ops->init && (dset->shared->layout.ops->init)(file, dxpl_id, dset, dapl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize layout information") + + /* Indicate that the layout information was initialized */ + layout_init = TRUE; + /* * Allocate storage if space allocate time is early; otherwise delay * allocation until later. @@ -984,6 +993,14 @@ done: if(H5O_unpin(oloc, oh) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header") + /* Error cleanup */ + if(ret_value < 0) { + if(dset->shared->layout.type == H5D_CHUNKED && layout_init) { + if(H5D_chunk_dest(file, dxpl_id, dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy chunk cache") + } /* end if */ + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_update_oh_info() */ @@ -1137,16 +1154,16 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize I/O operations") /* Create the layout information for the new dataset */ - if((new_dset->shared->layout.ops->construct)(file, dapl_id, dxpl_id, new_dset, dc_plist) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize layout information") - - /* Indicate that the layout information was initialized */ - layout_init = TRUE; + if((new_dset->shared->layout.ops->construct)(file, new_dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to construct layout information") /* Update the dataset's object header info. */ - if(H5D_update_oh_info(file, dxpl_id, new_dset) != SUCCEED) + if(H5D_update_oh_info(file, dxpl_id, new_dset, dapl_id) != SUCCEED) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the metadata cache") + /* Indicate that the layout information was initialized */ + layout_init = TRUE; + /* Add the dataset to the list of opened objects in the file */ if(H5FO_top_incr(new_dset->oloc.file, new_dset->oloc.addr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't incr object ref. count") @@ -1428,7 +1445,7 @@ H5D_open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id) case H5D_CHUNKED: /* Initialize the chunk cache for the dataset */ - if(H5D_chunk_init(dataset->oloc.file, dapl_id, dxpl_id, dataset) < 0) + if(H5D_chunk_init(dataset->oloc.file, dxpl_id, dataset, dapl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize chunk cache") break; @@ -2324,11 +2341,11 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) /* Check if we are shrinking or expanding any of the dimensions */ if((rank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions") + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions") /* Modify the size of the data space */ if((changed = H5S_set_extent(space, size)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") /* Don't bother updating things, unless they've changed */ if(changed) { diff --git a/src/H5Doh.c b/src/H5Doh.c index 039f055..93fd21a 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -373,12 +373,26 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) /* Get the layout message from the object header */ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_LAYOUT_ID, &layout)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find LAYOUT message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find layout message") /* Check for chunked dataset storage */ - if(layout.type == H5D_CHUNKED && H5D_chunk_is_space_alloc(&layout)) - if(H5D_chunk_bh_info(f, dxpl_id, &layout, &(bh_info->index_size)) < 0) + if(layout.type == H5D_CHUNKED && H5D_chunk_is_space_alloc(&layout)) { + H5O_pline_t pline; /* I/O pipeline message */ + htri_t exists; /* Flag if header message of interest exists */ + + /* Check for I/O pipeline message */ + if((exists = H5O_msg_exists_oh(oh, H5O_PLINE_ID)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header") + else if(exists) { + if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_PLINE_ID, &pline)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find I/O pipeline message") + } /* end else if */ + else + HDmemset(&pline, 0, sizeof(pline)); + + if(H5D_chunk_bh_info(f, dxpl_id, &layout, &pline, &(bh_info->index_size)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine chunked dataset btree info") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 45d9a7d..5ce45a8 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -33,8 +33,6 @@ /* Other private headers needed by this file */ #include "H5Gprivate.h" /* Groups */ -#include "H5Oprivate.h" /* Object headers */ -#include "H5Sprivate.h" /* Dataspaces */ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatypes */ @@ -100,8 +98,9 @@ struct H5D_io_info_t; struct H5D_chunk_map_t; /* Function pointers for I/O on particular types of dataset layouts */ -typedef herr_t (*H5D_layout_construct_func_t)(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, - H5D_t *dset, const H5P_genplist_t *dc_plist); +typedef herr_t (*H5D_layout_construct_func_t)(H5F_t *f, H5D_t *dset); +typedef herr_t (*H5D_layout_init_func_t)(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, + hid_t dapl_id); typedef hbool_t (*H5D_layout_is_space_alloc_func_t)(const H5O_layout_t *layout); typedef herr_t (*H5D_layout_io_init_func_t)(const struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info, @@ -123,7 +122,8 @@ typedef herr_t (*H5D_layout_io_term_func_t)(const struct H5D_chunk_map_t *cm); /* Typedef for grouping layout I/O routines */ typedef struct H5D_layout_ops_t { - H5D_layout_construct_func_t construct; /* Layout constructor for new datasets */ + H5D_layout_construct_func_t construct; /* Layout constructor for new datasets */ + H5D_layout_init_func_t init; /* Layout initializer for dataset */ H5D_layout_is_space_alloc_func_t is_space_alloc; /* Query routine to determine if storage is allocated */ H5D_layout_io_init_func_t io_init; /* I/O initialization routine */ H5D_layout_read_func_t ser_read; /* High-level I/O routine for reading data in serial */ @@ -217,6 +217,7 @@ typedef struct H5D_io_info_t { typedef struct H5D_chk_idx_info_t { H5F_t *f; /* File pointer for operation */ hid_t dxpl_id; /* DXPL ID for operation */ + const H5O_pline_t *pline; /* I/O pipeline info */ H5O_layout_t *layout; /* Layout info for chunks */ } H5D_chk_idx_info_t; @@ -264,7 +265,8 @@ typedef int (*H5D_chunk_cb_func_t)(const H5D_chunk_rec_t *chunk_rec, void *udata); /* Typedefs for chunk operations */ -typedef herr_t (*H5D_chunk_init_func_t)(const H5D_chk_idx_info_t *idx_info); +typedef herr_t (*H5D_chunk_init_func_t)(const H5D_chk_idx_info_t *idx_info, + haddr_t dset_ohdr_addr); typedef herr_t (*H5D_chunk_create_func_t)(const H5D_chk_idx_info_t *idx_info); typedef hbool_t (*H5D_chunk_is_space_alloc_func_t)(const H5O_layout_t *layout); typedef herr_t (*H5D_chunk_insert_func_t)(const H5D_chk_idx_info_t *idx_info, @@ -279,10 +281,10 @@ typedef herr_t (*H5D_chunk_delete_func_t)(const H5D_chk_idx_info_t *idx_info); typedef herr_t (*H5D_chunk_copy_setup_func_t)(const H5D_chk_idx_info_t *idx_info_src, const H5D_chk_idx_info_t *idx_info_dst); typedef herr_t (*H5D_chunk_copy_shutdown_func_t)(H5O_layout_t *layout_src, - H5O_layout_t *layout_dst); + H5O_layout_t *layout_dst, hid_t dxpl_id); typedef herr_t (*H5D_chunk_size_func_t)(const H5D_chk_idx_info_t *idx_info, hsize_t *idx_size); -typedef herr_t (*H5D_chunk_reset_func_t)(H5O_layout_t *layout); +typedef herr_t (*H5D_chunk_reset_func_t)(H5O_layout_t *layout, hbool_t reset_addr); typedef herr_t (*H5D_chunk_dump_func_t)(const H5D_chk_idx_info_t *idx_info, FILE *stream); typedef herr_t (*H5D_chunk_dest_func_t)(const H5D_chk_idx_info_t *idx_info); @@ -369,15 +371,15 @@ typedef struct H5D_rdcc_t { } stats; size_t nbytes_max; /* Maximum cached raw data in bytes */ size_t nslots; /* Number of chunk slots allocated */ - double w0; /* Chunk preemption policy */ + double w0; /* Chunk preemption policy */ struct H5D_rdcc_ent_t *head; /* Head of doubly linked list */ struct H5D_rdcc_ent_t *tail; /* Tail of doubly linked list */ size_t nbytes_used; /* Current cached raw data in bytes */ - int nused; /* Number of chunk slots in use */ + int nused; /* Number of chunk slots in use */ H5D_chunk_cached_t last; /* Cached copy of last chunk information */ struct H5D_rdcc_ent_t **slot; /* Chunk slots, each points to a chunk*/ - H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ - H5S_t *single_space; /* Dataspace for single element I/O on chunks */ + H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ + H5S_t *single_space; /* Dataspace for single element I/O on chunks */ H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */ } H5D_rdcc_t; @@ -576,7 +578,8 @@ H5_DLL htri_t H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op); H5_DLL herr_t H5D_chunk_cinfo_cache_reset(H5D_chunk_cached_t *last); H5_DLL herr_t H5D_chunk_create(H5D_t *dset /*in,out*/, hid_t dxpl_id); -H5_DLL herr_t H5D_chunk_init(H5F_t *f, hid_t dapl_id, hid_t dxpl_id, const H5D_t *dset); +H5_DLL herr_t H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, + hid_t dapl_id); H5_DLL hbool_t H5D_chunk_is_space_alloc(const H5O_layout_t *layout); H5_DLL herr_t H5D_chunk_get_info(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset, H5D_chunk_ud_t *udata); @@ -599,7 +602,7 @@ H5_DLL herr_t H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id); H5_DLL herr_t H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout, - hsize_t *btree_size); + const H5O_pline_t *pline, hsize_t *btree_size); H5_DLL herr_t H5D_chunk_dump_index(H5D_t *dset, hid_t dxpl_id, FILE *stream); H5_DLL herr_t H5D_chunk_dest(H5F_t *f, hid_t dxpl_id, H5D_t *dset); #ifdef H5D_CHUNK_DEBUG diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 7c78d71..ad9c795 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -166,8 +166,9 @@ H5_DLL herr_t H5D_contig_delete(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout); /* Functions that operate on chunked storage */ -H5_DLL herr_t H5D_chunk_idx_reset(H5O_layout_t *layout); -H5_DLL herr_t H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout); +H5_DLL herr_t H5D_chunk_idx_reset(H5O_layout_t *layout, hbool_t reset_addr); +H5_DLL herr_t H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5O_layout_t *layout); /* Functions that operate on indexed storage */ H5_DLL herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, diff --git a/src/H5F.c b/src/H5F.c index f6e0a8b..72cff79 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1501,11 +1501,15 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); /* Check/fix arguments */ - if (!filename || !*filename) + if(!filename || !*filename) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") - if (flags & ~(H5F_ACC_EXCL|H5F_ACC_TRUNC|H5F_ACC_DEBUG)) + /* In this routine, we only accept the following flags: + * H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_DEBUG + */ + if(flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_DEBUG)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") - if ((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC)) + /* The H5F_ACC_EXCL and H5F_ACC_TRUNC flags are mutually exclusive */ + if((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation") /* Check file creation property list */ @@ -1605,6 +1609,7 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) /* Check/fix arguments. */ if(!filename || !*filename) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") + /* Reject undefined flags (~H5F_ACC_PUBLIC_FLAGS) and the H5F_ACC_TRUNC & H5F_ACC_EXCL flags */ if((flags & ~H5F_ACC_PUBLIC_FLAGS) || (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags") diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 44ded9f..5b22266 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -61,7 +61,7 @@ #define H5F_SUPER_ALL_FLAGS (H5F_SUPER_WRITE_ACCESS | H5F_SUPER_FILE_OK) /* Mask for removing private file access flags */ -#define H5F_ACC_PUBLIC_FLAGS 0x00ffu +#define H5F_ACC_PUBLIC_FLAGS 0x001fu /* Free space section+aggregator merge flags */ #define H5F_FS_MERGE_METADATA 0x01 /* Section can merge with metadata aggregator */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 73d2c81..da8f2a8 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -390,6 +390,10 @@ H5O_layout_copy(const void *_mesg, void *_dest) HDmemcpy(dest->u.compact.buf, mesg->u.compact.buf, dest->u.compact.size); } /* end if */ + /* Reset the pointer of the chunked storage index but not the address */ + if(dest->type == H5D_CHUNKED && dest->u.chunk.ops) + H5D_chunk_idx_reset(dest, FALSE); + /* Set return value */ ret_value = dest; @@ -517,7 +521,7 @@ H5O_layout_free(void *_mesg) *------------------------------------------------------------------------- */ static herr_t -H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg) +H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg) { H5O_layout_t *mesg = (H5O_layout_t *) _mesg; herr_t ret_value = SUCCEED; /* Return value */ @@ -526,6 +530,7 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg) /* check args */ HDassert(f); + HDassert(open_oh); HDassert(mesg); /* Perform different actions, depending on the type of storage */ @@ -542,7 +547,7 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg) case H5D_CHUNKED: /* Chunked blocks on disk */ /* Free the file space for the index & chunk raw data */ - if(H5D_chunk_delete(f, dxpl_id, mesg) < 0) + if(H5D_chunk_delete(f, dxpl_id, open_oh, mesg) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") break; @@ -626,7 +631,7 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, case H5D_CHUNKED: if(H5D_chunk_is_space_alloc(layout_src)) { /* Layout is not created in the destination file, reset index address */ - if(H5D_chunk_idx_reset(layout_dst) < 0) + if(H5D_chunk_idx_reset(layout_dst, TRUE) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to reset chunked storage index in dest") /* Create chunked layout */ diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index c64a70b..cd4e98c 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -279,7 +279,8 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) /* Reset index info, if the chunk ops are set */ if(dst_layout.u.chunk.ops) - if(H5D_chunk_idx_reset(&dst_layout) < 0) + /* Reset address and pointer of the array struct for the chunked storage index */ + if(H5D_chunk_idx_reset(&dst_layout, TRUE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to reset chunked storage index in dest") /* Reset chunk index ops */ diff --git a/test/dsets.c b/test/dsets.c index 3357a4e..bd02c24 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -138,10 +138,12 @@ const char *FILENAME[] = { #define FILTER_HS_SIZE2 50 /* Names for noencoder test */ +#ifdef H5_HAVE_FILTER_SZIP #define NOENCODER_FILENAME "noencoder.h5" #define NOENCODER_TEST_DATASET "noencoder_tdset.h5" #define NOENCODER_SZIP_DATASET "noencoder_szip_dset.h5" #define NOENCODER_SZIP_SHUFF_FLETCH_DATASET "noencoder_szip_shuffle_fletcher_dset.h5" +#endif /* H5_HAVE_FILTER_SZIP */ /* Names for zero-dim test */ #define ZERODIM_DATASET "zerodim" @@ -974,9 +976,9 @@ test_tconv(hid_t file) hsize_t dims[1]; hid_t space, dataset; - out = HDmalloc((size_t)(4 * 1000 * 1000)); + out = (char *)HDmalloc((size_t)(4 * 1000 * 1000)); HDassert(out); - in = HDmalloc((size_t)(4 * 1000 * 1000)); + in = (char *)HDmalloc((size_t)(4 * 1000 * 1000)); HDassert(in); TESTING("data type conversion"); @@ -1131,7 +1133,7 @@ set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t UNUSED space_id) return(FAIL); /* Set "local" parameters for this dataset */ - cd_values[2]=(add_on>0); /* Flag to indicate data is modified */ + cd_values[2]=(unsigned)(add_on>0); /* Flag to indicate data is modified */ cd_values[3]=add_on; /* Amount the data was modified by */ /* Modify the filter's parameters for this dataset */ @@ -1185,12 +1187,12 @@ filter_bogus2(unsigned int flags, size_t cd_nelmts, /* "Compressing" */ else { unsigned add_on=cd_values[3]; /* Get "add on" value */ - int *int_ptr=*buf; /* Pointer to the data values */ + int *int_ptr=(int *)*buf; /* Pointer to the data values */ size_t buf_left=*buf_size; /* Amount of data buffer left to process */ /* Add the "add on" value to all the data values */ while(buf_left>0) { - *int_ptr++ += add_on; + *int_ptr++ += (int)add_on; buf_left -= sizeof(int); } /* end while */ } /* end else */ @@ -2661,7 +2663,7 @@ test_nbit_int(hid_t file) /* Check that the values read are the same as the values written * Use mask for checking the significant bits, ignoring the padding bits */ - mask = ~(~0 << (precision + offset)) & (~0 << offset); + mask = ~((unsigned)~0 << (precision + offset)) & ((unsigned)~0 << offset); for(i=0; i<(size_t)size[0]; i++) { for(j=0; j<(size_t)size[1]; j++) { if((new_data[i][j] & mask) != (orig_data[i][j] & mask)) { @@ -3220,7 +3222,7 @@ test_nbit_compound(hid_t file) /* some even-numbered integer values are negtive */ if((i*size[1]+j+1)%2 == 0) { orig_data[i][j].i = -orig_data[i][j].i; - orig_data[i][j].s = -orig_data[i][j].s; + orig_data[i][j].s = (short)-orig_data[i][j].s; } } @@ -3262,9 +3264,9 @@ test_nbit_compound(hid_t file) /* Check that the values read are the same as the values written * Use mask for checking the significant bits, ignoring the padding bits */ - i_mask = ~(~0 << (precision[0] + offset[0])) & (~0 << offset[0]); - c_mask = ~(~0 << (precision[1] + offset[1])) & (~0 << offset[1]); - s_mask = ~(~0 << (precision[2] + offset[2])) & (~0 << offset[2]); + i_mask = ~((unsigned)~0 << (precision[0] + offset[0])) & ((unsigned)~0 << offset[0]); + c_mask = ~((unsigned)~0 << (precision[1] + offset[1])) & ((unsigned)~0 << offset[1]); + s_mask = ~((unsigned)~0 << (precision[2] + offset[2])) & ((unsigned)~0 << offset[2]); for(i=0; i