summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Ddeprec.c9
-rw-r--r--src/H5Dint.c231
-rw-r--r--src/H5Dio.c56
-rw-r--r--src/H5Dmpio.c18
-rw-r--r--src/H5Dpkg.h6
-rw-r--r--src/H5Gobj.c2
-rw-r--r--src/H5Omessage.c57
-rw-r--r--src/H5Oprivate.h16
-rw-r--r--src/H5S.c40
-rw-r--r--src/H5Shyper.c47
-rw-r--r--src/H5Spkg.h1
-rw-r--r--src/H5Sprivate.h9
-rw-r--r--src/H5Sselect.c15
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; u<f_ndims; u++) {
@@ -2414,8 +2413,12 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info,
/* Initialize skip list for chunk selections */
- if((fm->fsel = 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; u<space->extent.rank; u++) {
+ for(u = 0; u<space->extent.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() */