From 74c005fdb21644607cd93b3c2dd9098d9cc7e7c5 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 6 Dec 2007 14:24:30 -0500 Subject: [svn-r14326] Description: - Keep skip list for tracking chunks with dataset (instead of creating/ destroying it for each I/O operation) and just delete the skip list nodes. - Avoid computations for normalizing selection offset when offset not set. - Avoid updating object modification time twice during dataset creation. - Avoid updating dataset layout message (and object modification time) until dataset is closed. Tested on: FreeBSD/32 6.2 (duty) in debug mode FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Mac OS X/32 10.4.10 (amazon) in debug mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode --- src/H5Ddeprec.c | 9 +-- src/H5Dint.c | 231 ++++++++++++++++++++++++++++++++++--------------------- src/H5Dio.c | 56 +++++++------- src/H5Dmpio.c | 18 ++--- src/H5Dpkg.h | 6 +- src/H5Gobj.c | 2 +- src/H5Omessage.c | 57 ++++++++++++-- src/H5Oprivate.h | 16 ++-- src/H5S.c | 40 ++++------ src/H5Shyper.c | 47 ++++++----- src/H5Spkg.h | 1 + src/H5Sprivate.h | 9 +-- src/H5Sselect.c | 15 ++-- 13 files changed, 299 insertions(+), 208 deletions(-) diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 95f89cf..eaa9057 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -344,10 +344,6 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id) /* Updated the dataset's info if the dataspace was successfully extended */ if(changed) { - /* Save the new dataspace in the file if necessary */ - if(H5S_write(&(dataset->oloc), space, TRUE, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace") - /* Update the index values for the cached chunks for this dataset */ if(H5D_CHUNKED == dataset->shared->layout.type) if(H5D_istore_update_cache(dataset, dxpl_id) < 0) @@ -356,8 +352,11 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id) /* Allocate space for the new parts of the dataset, if appropriate */ fill = &dataset->shared->dcpl_cache.fill; if(fill->alloc_time == H5D_ALLOC_TIME_EARLY) - if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_EXTEND, TRUE, FALSE) < 0) + if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_EXTEND, FALSE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value") + + /* Mark the dataspace as dirty, for later writing to the file */ + dataset->shared->space_dirty = TRUE; } /* end if */ done: diff --git a/src/H5Dint.c b/src/H5Dint.c index 4340578..d344d41 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -65,6 +65,7 @@ static herr_t H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, static herr_t H5D_init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space); static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset); static herr_t H5D_open_oid(H5D_t *dataset, hid_t dxpl_id); +static herr_t H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags); /*********************/ @@ -567,7 +568,7 @@ done: static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) { - struct H5O_t *oh = NULL; /* Pointer to dataset's object header */ + H5O_t *oh = NULL; /* Pointer to dataset's object header */ size_t ohdr_size = H5D_MINHDR_SIZE; /* Size of dataset's object header */ H5O_loc_t *oloc = NULL; /* Dataset's object location */ H5O_layout_t *layout; /* Dataset's layout information */ @@ -653,10 +654,10 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) /* Get a pointer to the object header itself */ if((oh = H5O_protect(oloc, dxpl_id)) == NULL) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to protect dataset object header") + HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect dataset object header") /* Write new fill value message */ - if(H5O_msg_append(file, dxpl_id, oh, H5O_FILL_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, fill_prop) < 0) + if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_FILL_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, fill_prop) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update new fill value header message") /* If there is valid information for the old fill value struct, add it */ @@ -672,12 +673,12 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) H5O_msg_reset_share(H5O_FILL_ID, &old_fill_prop); /* Write old fill value */ - if(H5O_msg_append(file, dxpl_id, oh, H5O_FILL_ID, H5O_MSG_FLAG_CONSTANT, 0, &old_fill_prop) < 0) + if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_FILL_ID, H5O_MSG_FLAG_CONSTANT, 0, &old_fill_prop) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update old fill value header message") } /* end if */ /* Update the datatype and dataspace header messages */ - if(H5O_msg_append(file, dxpl_id, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT, 0, type) < 0) + if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT, 0, type) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update datatype header message") if(H5S_append(file, dxpl_id, oh, dset->shared->space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update dataspace header message") @@ -687,7 +688,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) H5O_pline_t *pline; /* Dataset's I/O pipeline information */ pline = &dset->shared->dcpl_cache.pline; - if(pline->nused > 0 && H5O_msg_append(file, dxpl_id, oh, H5O_PLINE_ID, H5O_MSG_FLAG_CONSTANT, 0, pline) < 0) + if(pline->nused > 0 && H5O_msg_append_oh(file, dxpl_id, oh, H5O_PLINE_ID, H5O_MSG_FLAG_CONSTANT, 0, pline) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message") } /* end if */ @@ -696,7 +697,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) * allocation until later. */ if(fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY) - if(H5D_alloc_storage(file, dxpl_id, dset, H5D_ALLOC_CREATE, FALSE, FALSE) < 0) + if(H5D_alloc_storage(file, dxpl_id, dset, H5D_ALLOC_CREATE, FALSE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") /* Update external storage message, if it's used */ @@ -716,7 +717,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) /* Pin the heap down in memory */ if(NULL == (heap = H5HL_protect(file, dxpl_id, efl->heap_addr, H5AC_WRITE))) - HGOTO_ERROR(H5E_DATASET, H5E_PROTECT, FAIL, "unable to protect EFL file name heap") + HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect EFL file name heap") /* Insert "empty" name first */ if((size_t)(-1) == H5HL_insert(file, dxpl_id, heap, (size_t)1, "")) { @@ -741,18 +742,18 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) /* Release the heap */ if(H5HL_unprotect(file, dxpl_id, heap, efl->heap_addr) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_PROTECT, FAIL, "unable to unprotect EFL file name heap") + HGOTO_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect EFL file name heap") heap = NULL; /* Insert EFL message into dataset object header */ - if(H5O_msg_append(file, dxpl_id, oh, H5O_EFL_ID, H5O_MSG_FLAG_CONSTANT, 0, efl) < 0) + if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_EFL_ID, H5O_MSG_FLAG_CONSTANT, 0, efl) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update external file list message") } /* end if */ /* Create layout message */ /* (Don't make layout message constant unless allocation time is early, since space may not be allocated) */ /* (Note: this is relying on H5D_alloc_storage not calling H5O_msg_write during dataset creation) */ - if(H5O_msg_append(file, dxpl_id, oh, H5O_LAYOUT_ID, ((fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != layout->type) ? H5O_MSG_FLAG_CONSTANT : 0), 0, layout) < 0) + if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID, ((fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != layout->type) ? H5O_MSG_FLAG_CONSTANT : 0), 0, layout) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout") #ifdef H5O_ENABLE_BOGUS @@ -778,15 +779,16 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset) } #endif /* H5O_ENABLE_BOGUS */ - /* Add a modification time message. */ - if(H5O_touch_oh(file, dxpl_id, oh, TRUE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message") + /* Add a modification time message, if using older format. */ + if(!use_latest_format) + if(H5O_touch_oh(file, dxpl_id, oh, TRUE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message") done: /* Release pointer to object header itself */ if(oloc != NULL && oh != NULL) if(H5O_unprotect(oloc, oh) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header") + HDONE_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect dataset object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_update_oh_info() */ @@ -1428,7 +1430,7 @@ H5D_open_oid(H5D_t *dataset, hid_t dxpl_id) && ((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr)) || (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr))) && IS_H5FD_MPI(dataset->oloc.file)) { - if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_OPEN, TRUE, FALSE) < 0) + if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_OPEN, FALSE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file storage") } /* end if */ @@ -1491,28 +1493,14 @@ H5D_close(H5D_t *dataset) dataset->shared->fo_count--; if(dataset->shared->fo_count == 0) { - /* Update the dataspace on disk, if it's been changed */ - if(dataset->shared->space_dirty) { - if(H5S_write(&(dataset->oloc), dataset->shared->space, TRUE, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace") - dataset->shared->space_dirty = FALSE; - } /* end if */ + /* Flush the dataset's information */ + if(H5D_flush_real(dataset, H5AC_dxpl_id, H5F_FLUSH_NONE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to flush cached dataset info") /* Free the data sieve buffer, if it's been allocated */ if(dataset->shared->cache.contig.sieve_buf) { HDassert(dataset->shared->layout.type != H5D_COMPACT); /* We should never have a sieve buffer for compact storage */ - /* Flush the raw data buffer, if its dirty */ - if(dataset->shared->cache.contig.sieve_dirty) { - /* Write dirty data sieve buffer to file */ - if(H5F_block_write(dataset->oloc.file, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc, - dataset->shared->cache.contig.sieve_size, H5AC_dxpl_id, dataset->shared->cache.contig.sieve_buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed") - - /* Reset sieve buffer dirty flag */ - dataset->shared->cache.contig.sieve_dirty = FALSE; - } /* end if */ - dataset->shared->cache.contig.sieve_buf = (unsigned char *)H5FL_BLK_FREE(sieve_buf,dataset->shared->cache.contig.sieve_buf); } /* end if */ @@ -1522,19 +1510,19 @@ H5D_close(H5D_t *dataset) break; case H5D_CHUNKED: + /* Check for skip list for iterating over chunks during I/O to close */ + if(dataset->shared->cache.chunk.sel_chunks) { + HDassert(H5SL_count(dataset->shared->cache.chunk.sel_chunks) == 0); + H5SL_close(dataset->shared->cache.chunk.sel_chunks); + dataset->shared->cache.chunk.sel_chunks = NULL; + } /* end if */ + /* Flush and destroy chunks in the cache */ - if(H5D_istore_dest(dataset,H5AC_dxpl_id) < 0) + if(H5D_istore_dest(dataset, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy chunk cache") break; case H5D_COMPACT: - /* Update header message of layout for compact dataset. */ - if(dataset->shared->layout.u.compact.dirty) { - if(H5O_msg_write(&(dataset->oloc), H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to update layout message") - dataset->shared->layout.u.compact.dirty = FALSE; - } /* end if */ - /* Free the buffer for the raw data for compact datasets */ dataset->shared->layout.u.compact.buf = H5MM_xfree(dataset->shared->layout.u.compact.buf); break; @@ -1716,7 +1704,7 @@ H5D_get_file(const H5D_t *dset) */ herr_t H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc, - hbool_t update_time, hbool_t full_overwrite) + hbool_t full_overwrite) { struct H5O_layout_t *layout; /* The dataset's layout information */ hbool_t must_init_space = FALSE; /* Flag to indicate that space should be initialized */ @@ -1833,12 +1821,15 @@ H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc } /* end else */ } /* end if */ - /* Also update header message for layout with new address, if we - * set the address. (this is improves forward compatibility). + /* If we set the address (and aren't in the middle of creating the + * dataset), mark the layout header message for later writing to + * the file. (this improves forward compatibility). + */ + /* (The layout message is already in the dataset's object header, this + * operation just sets the address and makes it constant) */ if(time_alloc != H5D_ALLOC_CREATE && addr_set) - if(H5O_msg_write(&dset->oloc, H5O_LAYOUT_ID, H5O_MSG_FLAG_CONSTANT, update_time, &dset->shared->layout, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message") + dset->shared->layout_dirty = TRUE; } /* end if */ done: @@ -2309,7 +2300,7 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) /* Allocate space for the new parts of the dataset, if appropriate */ if(expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY) - if(H5D_alloc_storage(dset->oloc.file, dxpl_id, dset, H5D_ALLOC_EXTEND, TRUE, FALSE) < 0) + if(H5D_alloc_storage(dset->oloc.file, dxpl_id, dset, H5D_ALLOC_EXTEND, FALSE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset storage") @@ -2349,7 +2340,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5D_flush_cb + * Function: H5D_flush_real * * Purpose: Flush any dataset information cached in memory * @@ -2357,69 +2348,132 @@ done: * Failure: Negative * * Programmer: Quincey Koziol - * November 8, 2007 + * December 6, 2007 * *------------------------------------------------------------------------- */ -static int -H5D_flush_cb(void *_dataset, hid_t UNUSED id, void *_udata) +static herr_t +H5D_flush_real(H5D_t *dataset, hid_t dxpl_id, unsigned flags) { - H5D_t *dataset = (H5D_t *)_dataset; /* Dataset pointer */ - H5D_flush_ud_t *udata = (H5D_flush_ud_t *)_udata; /* User data for callback */ - int ret_value = H5_ITER_CONT; /* Return value */ + H5O_t *oh = NULL; /* Pointer to dataset's object header */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5D_flush_cb) + FUNC_ENTER_NOAPI_NOINIT(H5D_flush_real) /* Check args */ HDassert(dataset); - /* Check for dataset in same file */ - if(udata->f == dataset->oloc.file) { + /* Check for metadata changes that will require updating the object's modification time */ + if(dataset->shared->layout_dirty || dataset->shared->space_dirty) { + unsigned update_flags = H5O_UPDATE_TIME; /* Modification time flag */ + + /* Get a pointer to the dataset's object header */ + if((oh = H5O_protect(&dataset->oloc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect dataset object header") + + /* Update the layout on disk, if it's been changed */ + if(dataset->shared->layout_dirty) { + if(H5O_msg_write_oh(dataset->oloc.file, dxpl_id, oh, H5O_LAYOUT_ID, H5O_MSG_FLAG_CONSTANT, update_flags, &dataset->shared->layout) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update layout message") + dataset->shared->layout_dirty = FALSE; + + /* Reset the "update the modification time" flag, so we only do it once */ + update_flags = 0; + } /* end if */ + /* Update the dataspace on disk, if it's been changed */ if(dataset->shared->space_dirty) { - if(H5S_write(&(dataset->oloc), dataset->shared->space, TRUE, udata->dxpl_id) < 0) + if(H5S_write(dataset->oloc.file, dxpl_id, oh, update_flags, dataset->shared->space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace") dataset->shared->space_dirty = FALSE; + + /* Reset the "update the modification time" flag, so we only do it once */ + update_flags = 0; } /* end if */ - /* Flush the raw data buffer, if we have a dirty one */ - if(dataset->shared->cache.contig.sieve_buf && dataset->shared->cache.contig.sieve_dirty) { - HDassert(dataset->shared->layout.type != H5D_COMPACT); /* We should never have a sieve buffer for compact storage */ + /* _Somebody_ should have update the modification time! */ + HDassert(update_flags == 0); + } /* end if */ - /* Write dirty data sieve buffer to file */ - if(H5F_block_write(udata->f, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc, - dataset->shared->cache.contig.sieve_size, udata->dxpl_id, dataset->shared->cache.contig.sieve_buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed") + /* Flush the raw data buffer, if we have a dirty one */ + if(dataset->shared->cache.contig.sieve_buf && dataset->shared->cache.contig.sieve_dirty) { + HDassert(dataset->shared->layout.type != H5D_COMPACT); /* We should never have a sieve buffer for compact storage */ - /* Reset sieve buffer dirty flag */ - dataset->shared->cache.contig.sieve_dirty = FALSE; - } /* end if */ + /* Write dirty data sieve buffer to file */ + if(H5F_block_write(dataset->oloc.file, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc, + dataset->shared->cache.contig.sieve_size, dxpl_id, dataset->shared->cache.contig.sieve_buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed") - /* Flush cached information for each kind of dataset */ - switch(dataset->shared->layout.type) { - case H5D_CONTIGUOUS: - break; + /* Reset sieve buffer dirty flag */ + dataset->shared->cache.contig.sieve_dirty = FALSE; + } /* end if */ - case H5D_CHUNKED: - /* Flush the raw data cache */ - if(H5D_istore_flush(dataset, udata->dxpl_id, udata->flags & H5F_FLUSH_INVALIDATE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush raw data cache") - break; + /* Flush cached information for each kind of dataset */ + switch(dataset->shared->layout.type) { + case H5D_CONTIGUOUS: + break; - case H5D_COMPACT: - if(dataset->shared->layout.u.compact.dirty) { - if(H5O_msg_write(&(dataset->oloc), H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message") - dataset->shared->layout.u.compact.dirty = FALSE; - } /* end if */ - break; + case H5D_CHUNKED: + /* Flush the raw data cache */ + if(H5D_istore_flush(dataset, dxpl_id, flags & H5F_FLUSH_INVALIDATE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush raw data cache") + break; - default: - HDassert("not implemented yet" && 0); + case H5D_COMPACT: + if(dataset->shared->layout.u.compact.dirty) { + if(H5O_msg_write(&(dataset->oloc), H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message") + dataset->shared->layout.u.compact.dirty = FALSE; + } /* end if */ + break; + + default: + HDassert("not implemented yet" && 0); #ifdef NDEBUG - HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout") + HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout") #endif /* NDEBUG */ - } /* end switch */ /*lint !e788 All appropriate cases are covered */ + } /* end switch */ /*lint !e788 All appropriate cases are covered */ + +done: + /* Release pointer to object header */ + if(oh != NULL) + if(H5O_unprotect(&(dataset->oloc), oh) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTUNPROTECT, FAIL, "unable to unprotect dataset object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_flush_real() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_flush_cb + * + * Purpose: Flush any dataset information cached in memory + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * November 8, 2007 + * + *------------------------------------------------------------------------- + */ +static int +H5D_flush_cb(void *_dataset, hid_t UNUSED id, void *_udata) +{ + H5D_t *dataset = (H5D_t *)_dataset; /* Dataset pointer */ + H5D_flush_ud_t *udata = (H5D_flush_ud_t *)_udata; /* User data for callback */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_flush_cb) + + /* Check args */ + HDassert(dataset); + + /* Check for dataset in same file */ + if(udata->f == dataset->oloc.file) { + /* Flush the dataset's information */ + if(H5D_flush_real(dataset, udata->dxpl_id, udata->flags) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, H5_ITER_ERROR, "unable to flush cached dataset info") } /* end if */ done: @@ -2460,7 +2514,6 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags) H5I_search(H5I_DATASET, H5D_flush_cb, &udata); done: - FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_flush() */ diff --git a/src/H5Dio.c b/src/H5Dio.c index d3df42a..189d9f1 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -700,7 +700,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, full_overwrite = (hsize_t)file_nelmts==nelmts ? TRUE : FALSE; /* Allocate storage */ - if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_WRITE, TRUE, full_overwrite) < 0) + if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_WRITE, full_overwrite) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") } /* end if */ @@ -1412,7 +1412,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, else {/* sequential or independent read */ #endif /* Get first node in chunk skip list */ - chunk_node = H5SL_first(fm.fsel); + chunk_node = H5SL_first(fm.sel_chunks); while(chunk_node) { H5D_chunk_info_t *chunk_info; /* chunk information */ @@ -1521,7 +1521,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, /* Loop over all the chunks, performing I/O on each */ /* Get first node in chunk skip list */ - chunk_node=H5SL_first(fm.fsel); + chunk_node=H5SL_first(fm.sel_chunks); /* Iterate through chunks to be operated on */ while(chunk_node) { @@ -1810,7 +1810,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, else {/* sequential or independent write */ #endif /* H5_HAVE_PARALLEL */ /* Get first node in chunk skip list */ - chunk_node=H5SL_first(fm.fsel); + chunk_node=H5SL_first(fm.sel_chunks); while(chunk_node) { H5D_chunk_info_t *chunk_info; /* Chunk information */ @@ -1928,7 +1928,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, /* Loop over all the chunks, performing I/O on each */ /* Get first node in chunk skip list */ - chunk_node=H5SL_first(fm.fsel); + chunk_node=H5SL_first(fm.sel_chunks); /* Iterate through chunks to be operated on */ while(chunk_node) { @@ -2347,7 +2347,7 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, H5D_t *dataset=io_info->dset; /* Local pointer to dataset info */ H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */ hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */ - hbool_t file_space_normalized = FALSE; /* File dataspace was normalized */ + htri_t file_space_normalized = FALSE; /* File dataspace was normalized */ hid_t f_tid = (-1); /* Temporary copy of file datatype for iteration */ hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */ unsigned f_ndims; /* The number of dimensions of the file's dataspace */ @@ -2382,9 +2382,8 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, * speed up hyperslab calculations by removing the extra checks and/or * additions involving the offset and the hyperslab selection -QAK) */ - if(H5S_hyper_normalize_offset((H5S_t *)file_space, old_offset) < 0) + if((file_space_normalized = H5S_hyper_normalize_offset((H5S_t *)file_space, old_offset)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") - file_space_normalized = TRUE; /* Decide the number of chunks in each dimension*/ for(u=0; ufsel = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5D_DEFAULT_SKIPLIST_HEIGHT))==NULL) - HGOTO_ERROR(H5E_DATASET,H5E_CANTCREATE,FAIL,"can't create skip list for chunk selections") + if(NULL == dataset->shared->cache.chunk.sel_chunks) { + if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5D_DEFAULT_SKIPLIST_HEIGHT))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections") + } /* end if */ + fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks; + HDassert(fm->sel_chunks); /* Initialize "last chunk" information */ fm->last_index = (hsize_t)-1; @@ -2455,7 +2458,7 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") /* Clean file chunks' hyperslab span "scratch" information */ - curr_node=H5SL_first(fm->fsel); + curr_node=H5SL_first(fm->sel_chunks); while(curr_node) { H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ @@ -2530,7 +2533,7 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, /* Clean up hyperslab stuff, if necessary */ if(fm->msel_type != H5S_SEL_POINTS) { /* Clean memory chunks' hyperslab span "scratch" information */ - curr_node=H5SL_first(fm->fsel); + curr_node=H5SL_first(fm->sel_chunks); while(curr_node) { H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ @@ -2641,14 +2644,10 @@ H5D_destroy_chunk_map(const H5D_chunk_map_t *fm) FUNC_ENTER_NOAPI_NOINIT(H5D_destroy_chunk_map) - /* Free the chunk info skip list */ - if(fm->fsel) { - if(H5SL_count(fm->fsel)>0) - if(H5SL_iterate(fm->fsel,H5D_free_chunk_info,NULL) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTNEXT,FAIL,"can't iterate over chunks") - - H5SL_close(fm->fsel); - } /* end if */ + /* Release the nodes on the list of selected chunks */ + if(fm->sel_chunks) + if(H5SL_free(fm->sel_chunks, H5D_free_chunk_info, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTNEXT, FAIL, "can't iterate over chunks") /* Free the memory chunk dataspace template */ if(fm->mchunk_tmpl) @@ -2744,7 +2743,7 @@ H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t new_chunk_info->mspace_shared = 1; /* Insert the new chunk into the skip list */ - if(H5SL_insert(fm->fsel, new_chunk_info, &new_chunk_info->index) < 0) + if(H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list") done: @@ -2883,7 +2882,7 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t new_chunk_info->coords[fm->f_ndims]=0; /* Insert the new chunk into the skip list */ - if(H5SL_insert(fm->fsel,new_chunk_info,&new_chunk_info->index) < 0) { + if(H5SL_insert(fm->sel_chunks,new_chunk_info,&new_chunk_info->index) < 0) { H5D_free_chunk_info(new_chunk_info,NULL,NULL); HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert chunk into skip list") } /* end if */ @@ -2974,11 +2973,11 @@ H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) assert(fm->f_ndims>0); /* Check for all I/O going to a single chunk */ - if(H5SL_count(fm->fsel)==1) { + if(H5SL_count(fm->sel_chunks)==1) { H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ /* Get the node */ - curr_node=H5SL_first(fm->fsel); + curr_node=H5SL_first(fm->sel_chunks); /* Get pointer to chunk's information */ chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); @@ -3009,7 +3008,7 @@ H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) } /* end for */ /* Iterate over each chunk in the chunk list */ - curr_node=H5SL_first(fm->fsel); + curr_node=H5SL_first(fm->sel_chunks); while(curr_node) { H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ @@ -3092,7 +3091,7 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const * find the chunk in the skip list. */ /* Get the chunk node from the skip list */ - if(NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->fsel, &chunk_index))) { + if(NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index))) { H5S_t *fspace; /* Memory chunk's dataspace */ /* Allocate the file & memory chunk information */ @@ -3135,7 +3134,7 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const chunk_info->coords[fm->f_ndims]=0; /* Insert the new chunk into the skip list */ - if(H5SL_insert(fm->fsel,chunk_info,&chunk_info->index) < 0) { + if(H5SL_insert(fm->sel_chunks,chunk_info,&chunk_info->index) < 0) { H5D_free_chunk_info(chunk_info,NULL,NULL); HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert chunk into skip list") } /* end if */ @@ -3203,7 +3202,7 @@ H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const * find the chunk in the skip list. */ /* Get the chunk node from the skip list */ - if(NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->fsel, &chunk_index))) + if(NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index))) HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't locate chunk in skip list") /* Check if the chunk already has a memory space */ @@ -3412,3 +3411,4 @@ done: } /* end H5D_ioinfo_term() */ #endif + diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index ccfaac9..22f32ab 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -550,7 +550,7 @@ H5D_mpio_get_min_chunk(const H5D_io_info_t *io_info, FUNC_ENTER_NOAPI_NOINIT(H5D_mpio_get_min_chunk); /* Get the number of chunks to perform I/O on */ - num_chunkf = H5SL_count(fm->fsel); + num_chunkf = H5SL_count(fm->sel_chunks); /* Determine the minimum # of chunks for all processes */ if (MPI_SUCCESS != (mpi_code = MPI_Allreduce(&num_chunkf, min_chunkf, 1, MPI_INT, MPI_MIN, io_info->comm))) @@ -586,7 +586,7 @@ H5D_mpio_get_sum_chunk(const H5D_io_info_t *io_info, /* Get the number of chunks to perform I/O on */ num_chunkf = 0; - ori_num_chunkf = H5SL_count(fm->fsel); + ori_num_chunkf = H5SL_count(fm->sel_chunks); H5_ASSIGN_OVERFLOW(num_chunkf,ori_num_chunkf,size_t,int); /* Determine the summation of number of chunks for all processes */ @@ -856,7 +856,7 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info,H5D_chunk_map_t *fm,const vo H5D_chunk_info_t *chunk_info; H5D_storage_t store; - chunk_node = H5SL_first(fm->fsel); + chunk_node = H5SL_first(fm->sel_chunks); if(chunk_node == NULL) { if(H5D_istore_chunkmap(io_info, &chunk_base_addr, fm->down_chunks) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address"); @@ -884,7 +884,7 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info,H5D_chunk_map_t *fm,const vo } /* Allocate chunking information */ - ori_num_chunk = H5SL_count(fm->fsel); + ori_num_chunk = H5SL_count(fm->sel_chunks); H5_ASSIGN_OVERFLOW(num_chunk,ori_num_chunk,size_t,int); #ifdef H5D_DEBUG @@ -1114,7 +1114,7 @@ H5D_multi_chunk_collective_io(H5D_io_info_t *io_info,H5D_chunk_map_t *fm,const v #endif select_chunk = fm->select_chunk[i]; if(select_chunk == 1){/* Have selection elements in this chunk. Find the chunk info. */ - if(NULL ==(chunk_node = H5SL_first(fm->fsel))) + if(NULL ==(chunk_node = H5SL_first(fm->sel_chunks))) HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get chunk node from skipped list"); while(chunk_node){ @@ -1313,7 +1313,7 @@ H5D_multi_chunk_collective_io_no_opt(H5D_io_info_t *io_info,H5D_chunk_map_t *fm, count_chunk = 0; /* Get first node in chunk skip list */ - chunk_node=H5SL_first(fm->fsel); + chunk_node=H5SL_first(fm->sel_chunks); /* Iterate through chunks to be operated on */ while(chunk_node) { @@ -1618,7 +1618,7 @@ H5D_sort_chunk(H5D_io_info_t * io_info, FUNC_ENTER_NOAPI_NOINIT(H5D_sort_chunk) - num_chunks = H5SL_count(fm->fsel); + num_chunks = H5SL_count(fm->sel_chunks); #ifdef H5D_DEBUG if(H5DEBUG(D)) HDfprintf(H5DEBUG(D),"many_chunk_opt= %d\n",many_chunk_opt); @@ -1657,7 +1657,7 @@ H5D_sort_chunk(H5D_io_info_t * io_info, } /* end if */ /* Get first node in chunk skip list */ - if(NULL ==(chunk_node = H5SL_first(fm->fsel))) + if(NULL ==(chunk_node = H5SL_first(fm->sel_chunks))) HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get chunk node from skipped list"); /* Set dataset storage for I/O info */ io_info->store = &store; @@ -1843,7 +1843,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, mem_cleanup = 1; - chunk_node = H5SL_first(fm->fsel); + chunk_node = H5SL_first(fm->sel_chunks); /*Obtain the regularity and selection information for all chunks in this process. */ while(chunk_node){ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 3967cf9..4f4bc35 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -143,6 +143,7 @@ typedef struct H5D_rdcc_t { 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 */ } H5D_rdcc_t; /* The raw data contiguous data cache */ @@ -166,6 +167,7 @@ typedef struct H5D_shared_t { H5T_t *type; /* datatype of this dataset */ H5S_t *space; /* dataspace of this dataset */ hbool_t space_dirty; /* Whether the dataspace info needs to be flushed to the file */ + hbool_t layout_dirty; /* Whether the layout info needs to be flushed to the file */ hid_t dcpl_id; /* dataset creation property id */ H5D_dcpl_cache_t dcpl_cache; /* Cached DCPL values */ H5D_io_ops_t io_ops; /* I/O operations */ @@ -223,7 +225,7 @@ typedef struct H5D_chunk_map_t { unsigned m_ndims; /* Number of dimensions for memory dataspace */ H5S_sel_type msel_type; /* Selection type in memory */ - H5SL_t *fsel; /* Skip list containing file dataspaces for all chunks */ + H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ hsize_t last_index; /* Index of last chunk operated on */ H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */ hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Number of chunks in each dimension */ @@ -343,7 +345,7 @@ H5_DLL H5D_t *H5D_create_named(const H5G_loc_t *loc, const char *name, H5_DLL herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id); H5_DLL herr_t H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset, H5D_time_alloc_t time_alloc, - hbool_t update_time, hbool_t full_overwrite); + hbool_t full_overwrite); H5_DLL hsize_t H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id); H5_DLL haddr_t H5D_get_offset(const H5D_t *dset); H5_DLL herr_t H5D_iterate(void *buf, hid_t type_id, const H5S_t *space, diff --git a/src/H5Gobj.c b/src/H5Gobj.c index af8f6df..8ca8c52 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -881,7 +881,7 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) if(can_convert) { /* Insert link messages into group */ for(u = 0; u < linfo->nlinks; u++) - if(H5O_msg_append(oloc->file, dxpl_id, oh, H5O_LINK_ID, 0, H5O_UPDATE_TIME, &(ltable.lnks[u])) < 0) { + if(H5O_msg_append_oh(oloc->file, dxpl_id, oh, H5O_LINK_ID, 0, H5O_UPDATE_TIME, &(ltable.lnks[u])) < 0) { /* Release object header */ if(H5O_unprotect(oloc, oh) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header") diff --git a/src/H5Omessage.c b/src/H5Omessage.c index 799f267..3130066 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -136,7 +136,7 @@ H5O_msg_create(const H5O_loc_t *loc, unsigned type_id, unsigned mesg_flags, HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Go append message to object header */ - if(H5O_msg_append(loc->file, dxpl_id, oh, type_id, mesg_flags, update_flags, mesg) < 0) + if(H5O_msg_append_oh(loc->file, dxpl_id, oh, type_id, mesg_flags, update_flags, mesg) < 0) HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to append to object header") done: @@ -148,7 +148,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_msg_append + * Function: H5O_msg_append_oh * * Purpose: Simplified version of H5O_msg_create, used when creating a new * object header message (usually during object creation) and @@ -165,13 +165,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_msg_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, +H5O_msg_append_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned mesg_flags, unsigned update_flags, void *mesg) { const H5O_msg_class_t *type; /* Original H5O class type for the ID */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_msg_append, FAIL) + FUNC_ENTER_NOAPI(H5O_msg_append_oh, FAIL) /* check args */ HDassert(f); @@ -189,7 +189,7 @@ H5O_msg_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_msg_append() */ +} /* end H5O_msg_append_oh() */ /*------------------------------------------------------------------------- @@ -301,6 +301,53 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_msg_write_oh + * + * Purpose: Modifies an existing message or creates a new message. + * + * The UPDATE_FLAGS argument are flags that allow the caller + * to skip updating the modification time or reseting the message + * data. This is useful when several calls to H5O_msg_write will be + * made in a sequence. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Dec 6 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_msg_write_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, + unsigned mesg_flags, unsigned update_flags, void *mesg) +{ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_msg_write_oh, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(H5O_ATTR_ID != type_id); /* Attributes are modified in another routine */ + HDassert(type_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ + HDassert(type); + HDassert(mesg); + HDassert(0 == (mesg_flags & ~H5O_MSG_FLAG_BITS)); + + /* Call the "real" modify routine */ + if(H5O_msg_write_real(f, dxpl_id, oh, type, mesg_flags, update_flags, mesg) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header message") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_msg_write_oh() */ + + +/*------------------------------------------------------------------------- * Function: H5O_msg_write_real * * Purpose: Modifies an existing message or creates a new message. diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index ce7aba0..72d9e2d 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -536,13 +536,13 @@ H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5_DLL herr_t H5O_open(H5O_loc_t *loc); H5_DLL herr_t H5O_close(H5O_loc_t *loc); H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id); -H5_DLL struct H5O_t *H5O_protect(H5O_loc_t *loc, hid_t dxpl_id); -H5_DLL herr_t H5O_unprotect(H5O_loc_t *loc, struct H5O_t *oh); +H5_DLL H5O_t *H5O_protect(H5O_loc_t *loc, hid_t dxpl_id); +H5_DLL herr_t H5O_unprotect(H5O_loc_t *loc, H5O_t *oh); H5_DLL herr_t H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id); -H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, +H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force); #ifdef H5O_ENABLE_BOGUS -H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, unsigned mesg_flags); +H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned mesg_flags); #endif /* H5O_ENABLE_BOGUS */ H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, @@ -558,10 +558,12 @@ H5_DLL herr_t H5O_get_rc_and_type(const H5O_loc_t *oloc, hid_t dxpl_id, unsigned /* Object header message routines */ H5_DLL herr_t H5O_msg_create(const H5O_loc_t *loc, unsigned type_id, unsigned mesg_flags, unsigned update_flags, void *mesg, hid_t dxpl_id); -H5_DLL herr_t H5O_msg_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, unsigned type_id, +H5_DLL herr_t H5O_msg_append_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned mesg_flags, unsigned update_flags, void *mesg); -H5_DLL herr_t H5O_msg_write(const H5O_loc_t *loc, unsigned type_id, unsigned flags, - unsigned update_flags, void *mesg, hid_t dxpl_id); +H5_DLL herr_t H5O_msg_write(const H5O_loc_t *loc, unsigned type_id, + unsigned mesg_flags, unsigned update_flags, void *mesg, hid_t dxpl_id); +H5_DLL herr_t H5O_msg_write_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + unsigned type_id, unsigned mesg_flags, unsigned update_flags, void *mesg); H5_DLL void *H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg, hid_t dxpl_id); H5_DLL herr_t H5O_msg_reset(unsigned type_id, void *native); diff --git a/src/H5S.c b/src/H5S.c index 8a498aa..8a58cba 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -1055,27 +1055,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5S_write(H5O_loc_t *loc, const H5S_t *ds, hbool_t update_time, hid_t dxpl_id) +H5S_write(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned update_flags, H5S_t *ds) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5S_write, FAIL) - HDassert(loc); + HDassert(f); + HDassert(oh); HDassert(ds); + HDassert(H5S_GET_EXTENT_TYPE(ds) >= 0); - switch(H5S_GET_EXTENT_TYPE(ds)) { - case H5S_NULL: - case H5S_SCALAR: - case H5S_SIMPLE: - if(H5O_msg_write(loc, H5O_SDSPACE_ID, 0, update_time, &(ds->extent), dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple dataspace message") - break; - - default: - HDassert("unknown dataspace class" && 0); - break; - } /* end switch */ + /* Write the current dataspace extent to the dataspace message */ + if(H5O_msg_write_oh(f, dxpl_id, oh, H5O_SDSPACE_ID, 0, update_flags, &(ds->extent)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple dataspace message") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1103,7 +1096,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, const H5S_t *ds) +H5S_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5S_t *ds) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1112,19 +1105,11 @@ H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, const H5S_t *ds) HDassert(f); HDassert(oh); HDassert(ds); + HDassert(H5S_GET_EXTENT_TYPE(ds) >= 0); - switch (H5S_GET_EXTENT_TYPE(ds)) { - case H5S_NULL: - case H5S_SCALAR: - case H5S_SIMPLE: - if(H5O_msg_append(f, dxpl_id, oh, H5O_SDSPACE_ID, 0, 0, &(ds->extent)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple data space message") - break; - - default: - assert("unknown data space class" && 0); - break; - } + /* Add the dataspace message to the object header */ + if(H5O_msg_append_oh(f, dxpl_id, oh, H5O_SDSPACE_ID, 0, 0, &(ds->extent)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't add simple dataspace message") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1388,6 +1373,7 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, /* Set offset to zeros */ for(u = 0; u < space->extent.rank; u++) space->select.offset[u] = 0; + space->select.offset_changed = FALSE; /* If the selection is 'all', update the number of elements selected */ if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_ALL) diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 9ca1fdc..8c56056 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -4238,35 +4238,37 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset) { unsigned u; /* Local index variable */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = FALSE; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_normalize_offset); + FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_normalize_offset) - assert(space); + HDassert(space); - /* Check for 'all' selection, instead of a hyperslab selection */ - /* (Technically, this check shouldn't be in the "hyperslab" routines...) */ - if(H5S_GET_SELECT_TYPE(space)==H5S_SEL_HYPERSLABS) { + /* Check for hyperslab selection & offset changed */ + if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS && space->select.offset_changed) { /* Copy & invert the selection offset */ - for(u=0; uextent.rank; u++) { + for(u = 0; uextent.rank; u++) { old_offset[u] = space->select.offset[u]; space->select.offset[u] = -space->select.offset[u]; } /* end for */ /* Call the existing 'adjust' routine */ - if(H5S_hyper_adjust_s(space, space->select.offset)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab normalization"); + if(H5S_hyper_adjust_s(space, space->select.offset) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab normalization") /* Zero out the selection offset */ HDmemset(space->select.offset, 0, sizeof(hssize_t) * space->extent.rank); + + /* Indicate that the offset was normalized */ + ret_value = TRUE; } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5S_hyper_normalize_offset() */ @@ -4294,25 +4296,22 @@ done: herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset) { - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_denormalize_offset); + FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_denormalize_offset) - assert(space); + HDassert(space); + HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); - /* Check for 'all' selection, instead of a hyperslab selection */ - /* (Technically, this check shouldn't be in the "hyperslab" routines...) */ - if(H5S_GET_SELECT_TYPE(space)==H5S_SEL_HYPERSLABS) { - /* Call the existing 'adjust' routine */ - if(H5S_hyper_adjust_s(space, old_offset)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab normalization"); + /* Call the existing 'adjust' routine */ + if(H5S_hyper_adjust_s(space, old_offset) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab normalization") - /* Copy the selection offset over */ - HDmemcpy(space->select.offset, old_offset, sizeof(hssize_t) * space->extent.rank); - } /* end if */ + /* Copy the selection offset over */ + HDmemcpy(space->select.offset, old_offset, sizeof(hssize_t) * space->extent.rank); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5S_hyper_denormalize_offset() */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 3fe2ac3..e13e6be 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -172,6 +172,7 @@ typedef struct { /* Selection information object */ typedef struct { const H5S_select_class_t *type; /* Pointer to selection's class info */ + hbool_t offset_changed; /* Indicate that the offset for the selection has been changed */ hssize_t offset[H5S_MAX_RANK]; /* Offset within the extent */ hsize_t num_elem; /* Number of elements in selection */ union { diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 8970890..ace2559 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -207,10 +207,9 @@ H5_DLL hbool_t H5S_has_extent(const H5S_t *ds); H5_DLL int H5S_get_simple_extent_ndims(const H5S_t *ds); H5_DLL int H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[]/*out*/, hsize_t max_dims[]/*out*/); -H5_DLL herr_t H5S_write(struct H5O_loc_t *loc, const H5S_t *space, - hbool_t update_time, hid_t dxpl_id); -H5_DLL herr_t H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, - const H5S_t *ds); +H5_DLL herr_t H5S_write(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned update_flags, + H5S_t *ds); +H5_DLL herr_t H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, H5S_t *ds); H5_DLL H5S_t *H5S_read(const struct H5O_loc_t *loc, hid_t dxpl_id); H5_DLL int H5S_set_extent(H5S_t *space, const hsize_t *size); H5_DLL herr_t H5S_set_extent_real(H5S_t *space, const hsize_t *size); @@ -274,7 +273,7 @@ H5_DLL htri_t H5S_hyper_intersect (H5S_t *space1, H5S_t *space2); H5_DLL htri_t H5S_hyper_intersect_block (H5S_t *space, hsize_t *start, hsize_t *end); H5_DLL herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset); H5_DLL herr_t H5S_hyper_move(H5S_t *space, const hssize_t *offset); -H5_DLL herr_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset); +H5_DLL htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset); H5_DLL herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset); /* Operations on selection iterators */ diff --git a/src/H5Sselect.c b/src/H5Sselect.c index eba17a8..41b565f 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -62,17 +62,20 @@ static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter); herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset) { - FUNC_ENTER_NOAPI_NOFUNC(H5S_select_offset); + FUNC_ENTER_NOAPI_NOFUNC(H5S_select_offset) /* Check args */ - assert(space); - assert(space->extent.rank); - assert(offset); + HDassert(space); + HDassert(space->extent.rank); + HDassert(offset); /* Copy the offset over */ - HDmemcpy(space->select.offset,offset,sizeof(hssize_t)*space->extent.rank); + HDmemcpy(space->select.offset, offset, sizeof(hssize_t)*space->extent.rank); + + /* Indicate that the offset was changed */ + space->select.offset_changed = TRUE; - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5S_select_offset() */ -- cgit v0.12