summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5C2journal.c2
-rw-r--r--src/H5D.c2
-rw-r--r--src/H5Dcontig.c8
-rw-r--r--src/H5Ddeprec.c11
-rw-r--r--src/H5Dint.c250
-rw-r--r--src/H5Dio.c338
-rw-r--r--src/H5Distore.c427
-rw-r--r--src/H5Dmpio.c18
-rw-r--r--src/H5Dpkg.h52
-rw-r--r--src/H5Dpublic.h4
-rw-r--r--src/H5Dselect.c416
-rw-r--r--src/H5F.c59
-rw-r--r--src/H5FD.c1632
-rw-r--r--src/H5FDlog.c4
-rw-r--r--src/H5FDmpio.c95
-rw-r--r--src/H5FDpkg.h67
-rw-r--r--src/H5FDprivate.h3
-rw-r--r--src/H5FDpublic.h36
-rw-r--r--src/H5FDspace.c1738
-rw-r--r--src/H5FS.c13
-rw-r--r--src/H5FSsection.c21
-rw-r--r--src/H5Fpkg.h5
-rw-r--r--src/H5Fprivate.h2
-rw-r--r--src/H5Fpublic.h6
-rw-r--r--src/H5G.c486
-rw-r--r--src/H5Gcompact.c8
-rw-r--r--src/H5Gdense.c47
-rw-r--r--src/H5Gdeprec.c4
-rw-r--r--src/H5Glink.c33
-rw-r--r--src/H5Gname.c282
-rw-r--r--src/H5Gnode.c52
-rw-r--r--src/H5Gobj.c47
-rw-r--r--src/H5Gpkg.h40
-rw-r--r--src/H5Gprivate.h5
-rw-r--r--src/H5Gstab.c10
-rw-r--r--src/H5HFdbg.c94
-rw-r--r--src/H5HFpkg.h2
-rw-r--r--src/H5HFspace.c52
-rw-r--r--src/H5HL.c115
-rw-r--r--src/H5L.c132
-rw-r--r--src/H5Lpublic.h5
-rw-r--r--src/H5MF.c225
-rw-r--r--src/H5MFprivate.h9
-rw-r--r--src/H5O.c455
-rw-r--r--src/H5Ocache.c22
-rw-r--r--src/H5Olinfo.c7
-rw-r--r--src/H5Omessage.c57
-rw-r--r--src/H5Opkg.h6
-rw-r--r--src/H5Oprivate.h21
-rw-r--r--src/H5Opublic.h23
-rw-r--r--src/H5Pfapl.c135
-rw-r--r--src/H5Pfcpl.c2
-rw-r--r--src/H5Ppublic.h8
-rw-r--r--src/H5R.c2
-rw-r--r--src/H5S.c40
-rw-r--r--src/H5SL.c243
-rw-r--r--src/H5SLprivate.h3
-rwxr-xr-xsrc/H5SM.c24
-rw-r--r--src/H5Sall.c61
-rw-r--r--src/H5Shyper.c240
-rw-r--r--src/H5Snone.c41
-rw-r--r--src/H5Spkg.h6
-rw-r--r--src/H5Spoint.c264
-rw-r--r--src/H5Sprivate.h21
-rw-r--r--src/H5Spublic.h12
-rw-r--r--src/H5Sselect.c68
-rw-r--r--src/H5TS.c51
-rw-r--r--src/H5TSprivate.h1
-rw-r--r--src/H5Znbit.c3
-rw-r--r--src/H5Zpublic.h19
-rw-r--r--src/H5Zscaleoffset.c1
-rw-r--r--src/H5Zshuffle.c2
-rw-r--r--src/H5Zszip.c7
-rw-r--r--src/H5checksum.c33
-rw-r--r--src/H5config.h.in3
-rw-r--r--src/H5private.h7
-rw-r--r--src/H5public.h4
-rw-r--r--src/H5trace.c20
-rwxr-xr-xsrc/Makefile.am2
-rw-r--r--src/Makefile.in73
80 files changed, 5497 insertions, 3347 deletions
diff --git a/src/H5C2journal.c b/src/H5C2journal.c
index a481e4d..84dcd8f 100644
--- a/src/H5C2journal.c
+++ b/src/H5C2journal.c
@@ -3517,7 +3517,7 @@ H5Pset_journal(hid_t fapl_id, const char *journal_file)
HDstrcpy(mdj_config.journal_file_path, journal_file);
/* set latest format */
- if (H5Pset_latest_format(fapl_id, TRUE) < 0)
+ if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format'")
/* set cache config struct information */
diff --git a/src/H5D.c b/src/H5D.c
index b120736..9cd9330 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -990,7 +990,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Dset_extent(hid_t dset_id, const hsize_t *size)
+H5Dset_extent(hid_t dset_id, const hsize_t size[])
{
H5D_t *dset; /* Dataset for this operation */
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 8a081c3..5cb1df9 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -661,7 +661,7 @@ H5D_contig_writevv(const H5D_io_info_t *io_info,
H5F_t *file = io_info->dset->oloc.file; /* File for dataset */
H5D_rdcdc_t *dset_contig=&(io_info->dset->shared->cache.contig); /* Cached information about contiguous data */
const H5D_contig_storage_t *store_contig=&(io_info->store->contig); /* Contiguous storage info for this I/O operation */
- const unsigned char *buf=_buf; /* Pointer to buffer to fill */
+ const unsigned char *buf=(const unsigned char *)_buf; /* Pointer to buffer to fill */
haddr_t addr; /* Actual address to read */
size_t total_size=0; /* Size of sequence in bytes */
size_t size; /* Size of sequence in bytes */
@@ -1204,11 +1204,11 @@ done:
if(H5I_dec_ref(tid_mem) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(buf)
- H5FL_BLK_FREE(type_conv, buf);
+ (void)H5FL_BLK_FREE(type_conv, buf);
if(reclaim_buf)
- H5FL_BLK_FREE(type_conv, reclaim_buf);
+ (void)H5FL_BLK_FREE(type_conv, reclaim_buf);
if(bkg)
- H5FL_BLK_FREE(type_conv, bkg);
+ (void)H5FL_BLK_FREE(type_conv, bkg);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_contig_copy() */
diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c
index 2810f5a..9fcf367 100644
--- a/src/H5Ddeprec.c
+++ b/src/H5Ddeprec.c
@@ -280,7 +280,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Dextend(hid_t dset_id, const hsize_t *size)
+H5Dextend(hid_t dset_id, const hsize_t size[])
{
H5D_t *dset;
herr_t ret_value = SUCCEED; /* Return value */
@@ -346,10 +346,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)
@@ -358,8 +354,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 94b53d3..a5ea398 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);
/*********************/
@@ -97,6 +98,9 @@ H5FL_DEFINE_STATIC(H5D_shared_t);
/* Declare the external PQ free list for the sieve buffer information */
H5FL_BLK_EXTERN(sieve_buf);
+/* Declare the external free list to manage the H5D_chunk_info_t struct */
+H5FL_EXTERN(H5D_chunk_info_t);
+
/* Define a static "default" dataset structure to use to initialize new datasets */
static H5D_shared_t H5D_def_dset;
@@ -567,7 +571,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 +657,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 +676,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 +691,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 +700,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 +720,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 +745,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 +782,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 +1433,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 +1496,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 +1513,31 @@ 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 */
+
+ /* Check for cached single chunk dataspace */
+ if(dataset->shared->cache.chunk.single_space) {
+ (void)H5S_close(dataset->shared->cache.chunk.single_space);
+ dataset->shared->cache.chunk.single_space = NULL;
+ } /* end if */
+
+ /* Check for cached single element chunk info */
+ if(dataset->shared->cache.chunk.single_chunk_info) {
+ (void)H5FL_FREE(H5D_chunk_info_t, dataset->shared->cache.chunk.single_chunk_info);
+ dataset->shared->cache.chunk.single_chunk_info = 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 +1719,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 */
@@ -1771,7 +1774,7 @@ H5D_alloc_storage(H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc
*/
if(dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY
&& time_alloc == H5D_ALLOC_EXTEND)
- must_init_space = 1;
+ must_init_space = TRUE;
break;
case H5D_COMPACT:
@@ -1833,12 +1836,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:
@@ -2171,7 +2177,7 @@ H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, unsigned UNUSED ndim, co
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't resize tbuf")
/* Select point to read in */
- if(H5Sselect_elements(vlen_bufsize->fspace_id, H5S_SELECT_SET, (size_t)1, (const hsize_t **)point) < 0)
+ if(H5Sselect_elements(vlen_bufsize->fspace_id, H5S_SELECT_SET, (size_t)1, point) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't select point")
/* Read in the point (with the custom VL memory allocator) */
@@ -2309,7 +2315,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 +2355,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_flush_cb
+ * Function: H5D_flush_real
*
* Purpose: Flush any dataset information cached in memory
*
@@ -2357,69 +2363,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 +2529,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 78140e0..cef34ee 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -45,6 +45,12 @@
#define H5D_DEFAULT_SKIPLIST_HEIGHT 8
+/* Macros for iterating over chunks to operate on */
+#define H5D_CHUNK_GET_FIRST_NODE(map) (map.use_single ? (H5SL_node_t *)(1) : H5SL_first(map.sel_chunks))
+#define H5D_CHUNK_GET_NODE_INFO(map, node) (map.use_single ? map.single_chunk_info : (H5D_chunk_info_t *)H5SL_item(node))
+#define H5D_CHUNK_GET_NEXT_NODE(map, node) (map.use_single ? (H5SL_node_t *)NULL : H5SL_next(node))
+
+
/******************/
/* Local Typedefs */
/******************/
@@ -120,7 +126,7 @@ static herr_t H5D_chunk_mem_cb(void *elem, hid_t type_id, unsigned ndims,
H5FL_BLK_DEFINE(type_conv);
/* Declare a free list to manage the H5D_chunk_info_t struct */
-H5FL_DEFINE_STATIC(H5D_chunk_info_t);
+H5FL_DEFINE(H5D_chunk_info_t);
/* Declare a free list to manage sequences of size_t */
H5FL_SEQ_DEFINE_STATIC(size_t);
@@ -161,7 +167,7 @@ H5D_get_dxpl_cache_real(hid_t dxpl_id, H5D_dxpl_cache_t *cache)
assert(cache);
/* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5I_object(dxpl_id)))
+ if (NULL == (dx_plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list")
/* Get maximum temporary buffer size */
@@ -302,12 +308,12 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
plist_id, buf);
/* check arguments */
- if(NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
if(NULL == dset->oloc.file)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
if(H5S_ALL != mem_space_id) {
- if(NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
@@ -315,7 +321,7 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent")
} /* end if */
if(H5S_ALL != file_space_id) {
- if(NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
@@ -394,12 +400,12 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
plist_id, buf);
/* check arguments */
- if(NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
if(NULL == dset->oloc.file)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
if(H5S_ALL != mem_space_id) {
- if(NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
@@ -407,7 +413,7 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "memory selection+offset not within extent")
} /* end if */
if(H5S_ALL != file_space_id) {
- if(NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
@@ -475,7 +481,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
HDassert(dataset && dataset->oloc.file);
/* Get memory datatype */
- if(NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ if(NULL == (mem_type = (const H5T_t *)H5I_object_verify(mem_type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
if(!file_space)
@@ -617,7 +623,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
HDassert(dataset && dataset->oloc.file);
/* Get the memory datatype */
- if(NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ if(NULL == (mem_type = (const H5T_t *)H5I_object_verify(mem_type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* All filters in the DCPL must have encoding enabled. */
@@ -701,7 +707,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 */
@@ -918,15 +924,15 @@ H5D_contig_read(H5D_io_info_t *io_info, hsize_t nelmts,
} else {
need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
} /* end else */
- if (NULL==(tconv_buf=dxpl_cache->tconv_buf)) {
+ if(NULL == (tconv_buf = (uint8_t *)dxpl_cache->tconv_buf)) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_conv, target_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
} /* end if */
- if (need_bkg && NULL==(bkg_buf=dxpl_cache->bkgr_buf)) {
+ if(need_bkg && NULL == (bkg_buf = (uint8_t *)dxpl_cache->bkgr_buf)) {
/* Allocate background buffer */
/* (Need calloc()-like call since memory needs to be initialized) */
- if((bkg_buf=H5FL_BLK_CALLOC(type_conv,(request_nelmts*dst_type_size)))==NULL)
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, (request_nelmts * dst_type_size))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion")
} /* end if */
@@ -1035,9 +1041,9 @@ done:
} /* end if */
if (tconv_buf && NULL==dxpl_cache->tconv_buf)
- H5FL_BLK_FREE(type_conv,tconv_buf);
+ (void)H5FL_BLK_FREE(type_conv,tconv_buf);
if (bkg_buf && NULL==dxpl_cache->bkgr_buf)
- H5FL_BLK_FREE(type_conv,bkg_buf);
+ (void)H5FL_BLK_FREE(type_conv,bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_contig_read() */
@@ -1196,15 +1202,15 @@ H5D_contig_write(H5D_io_info_t *io_info, hsize_t nelmts,
} else {
need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
} /* end else */
- if (NULL==(tconv_buf=dxpl_cache->tconv_buf)) {
+ if(NULL == (tconv_buf = (uint8_t *)dxpl_cache->tconv_buf)) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_conv, target_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
} /* end if */
- if (need_bkg && NULL==(bkg_buf=dxpl_cache->bkgr_buf)) {
+ if(need_bkg && NULL == (bkg_buf = (uint8_t *)dxpl_cache->bkgr_buf)) {
/* Allocate background buffer */
/* (Don't need calloc()-like call since file data is already initialized) */
- if((bkg_buf=H5FL_BLK_MALLOC(type_conv,(request_nelmts*dst_type_size)))==NULL)
+ if(NULL == (bkg_buf = H5FL_BLK_MALLOC(type_conv, (request_nelmts * dst_type_size))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion")
} /* end if */
@@ -1303,9 +1309,9 @@ done:
} /* end if */
if (tconv_buf && NULL==dxpl_cache->tconv_buf)
- H5FL_BLK_FREE(type_conv,tconv_buf);
+ (void)H5FL_BLK_FREE(type_conv,tconv_buf);
if (bkg_buf && NULL==dxpl_cache->bkgr_buf)
- H5FL_BLK_FREE(type_conv,bkg_buf);
+ (void)H5FL_BLK_FREE(type_conv,bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_contig_write() */
@@ -1378,6 +1384,11 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
/* Set dataset storage for I/O info */
io_info->store=&store;
+ /* Compute element sizes */
+ src_type_size = H5T_get_size(dataset->shared->type);
+ dst_type_size = H5T_get_size(mem_type);
+ max_type_size = MAX(src_type_size, dst_type_size);
+
/*
* If there is no type conversion then read directly into the
* application's buffer. This saves at least one mem-to-mem copy.
@@ -1408,13 +1419,13 @@ 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 = H5D_CHUNK_GET_FIRST_NODE(fm);
while(chunk_node) {
H5D_chunk_info_t *chunk_info; /* chunk information */
/* Get the actual chunk information from the skip list node */
- chunk_info = H5SL_item(chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* Pass in chunk's coordinates in a union. */
store.chunk.offset = chunk_info->coords;
@@ -1430,19 +1441,19 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
/* Perform the actual read operation */
if((io_info->ops.read)(io_info, chunk_info->chunk_points,
- H5T_get_size(dataset->shared->type), chunk_info->fspace,
+ src_type_size, chunk_info->fspace,
chunk_info->mspace, chunk_addr, chunk, buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, " chunked read failed")
/* Release the cache lock on the chunk. */
if(chunk) {
- accessed_bytes = chunk_info->chunk_points * H5T_get_size(dataset->shared->type);
+ accessed_bytes = chunk_info->chunk_points * src_type_size;
if(H5D_istore_unlock(io_info, FALSE, idx_hint, chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
/* Advance to next chunk in list */
- chunk_node = H5SL_next(chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
} /* end while */
#ifdef H5_HAVE_PARALLEL
}
@@ -1451,7 +1462,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
#ifdef H5S_DEBUG
H5_timer_end(&(io_info->stats->stats[1].read_timer), &timer);
- io_info->stats->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->shared->type);
+ io_info->stats->stats[1].read_nbytes += nelmts * src_type_size;
io_info->stats->stats[1].read_ncalls++;
#endif
@@ -1465,10 +1476,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
if(nelmts==0)
HGOTO_DONE(SUCCEED)
- /* Compute element sizes and other parameters */
- src_type_size = H5T_get_size(dataset->shared->type);
- dst_type_size = H5T_get_size(mem_type);
- max_type_size = MAX(src_type_size, dst_type_size);
+ /* Compute buffer sizes and other parameters */
target_size = dxpl_cache->max_temp_buf;
/* XXX: This could cause a problem if the user sets their buffer size
* to the same size as the default, and then the dataset elements are
@@ -1505,29 +1513,29 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
} else {
need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
} /* end else */
- if (NULL==(tconv_buf=dxpl_cache->tconv_buf)) {
+ if(NULL == (tconv_buf = (uint8_t *)dxpl_cache->tconv_buf)) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_conv, target_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
} /* end if */
- if (need_bkg && NULL==(bkg_buf=dxpl_cache->bkgr_buf)) {
+ if(need_bkg && NULL == (bkg_buf = (uint8_t *)dxpl_cache->bkgr_buf)) {
/* Allocate background buffer */
/* (Need calloc()-like call since memory needs to be initialized) */
- if((bkg_buf=H5FL_BLK_CALLOC(type_conv,(request_nelmts*dst_type_size)))==NULL)
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, (request_nelmts * dst_type_size))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion")
} /* end if */
/* 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 = H5D_CHUNK_GET_FIRST_NODE(fm);
/* Iterate through chunks to be operated on */
while(chunk_node) {
H5D_chunk_info_t *chunk_info; /* chunk information */
/* Get the actual chunk information from the skip list nodes */
- chunk_info=H5SL_item(chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* initialize selection iterator */
if (H5S_select_iter_init(&file_iter, chunk_info->fspace, src_type_size) < 0)
@@ -1647,7 +1655,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
/* Release the cache lock on the chunk. */
if(chunk) {
- accessed_bytes = chunk_info->chunk_points * H5T_get_size(dataset->shared->type);
+ accessed_bytes = chunk_info->chunk_points * src_type_size;
if(H5D_istore_unlock(io_info, FALSE, idx_hint, chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
@@ -1670,7 +1678,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
} /* end if */
/* Get the next chunk node in the skip list */
- chunk_node=H5SL_next(chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
} /* end while */
done:
@@ -1689,9 +1697,9 @@ done:
} /* end if */
if(tconv_buf && NULL == dxpl_cache->tconv_buf)
- H5FL_BLK_FREE(type_conv, tconv_buf);
+ (void)H5FL_BLK_FREE(type_conv, tconv_buf);
if(bkg_buf && NULL == dxpl_cache->bkgr_buf)
- H5FL_BLK_FREE(type_conv, bkg_buf);
+ (void)H5FL_BLK_FREE(type_conv, bkg_buf);
/* Release chunk mapping information */
if(H5D_destroy_chunk_map(&fm) < 0)
@@ -1779,6 +1787,11 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
} /* end if */
#endif /* H5_HAVE_PARALLEL */
+ /* Compute element sizes and other parameters */
+ src_type_size = H5T_get_size(mem_type);
+ dst_type_size = H5T_get_size(dataset->shared->type);
+ max_type_size = MAX(src_type_size, dst_type_size);
+
/*
* If there is no type conversion then write directly from the
* application's buffer. This saves at least one mem-to-mem copy.
@@ -1804,13 +1817,13 @@ 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 = H5D_CHUNK_GET_FIRST_NODE(fm);
while(chunk_node) {
H5D_chunk_info_t *chunk_info; /* Chunk information */
/* Get the actual chunk information from the skip list node */
- chunk_info=H5SL_item(chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* Pass in chunk's coordinates in a union. */
store.chunk.offset = chunk_info->coords;
@@ -1821,7 +1834,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
chunk_addr = H5D_istore_get_addr(io_info, &udata);
if(H5D_istore_if_load(io_info, chunk_addr)) {
- accessed_bytes = chunk_info->chunk_points * H5T_get_size(dataset->shared->type);
+ accessed_bytes = chunk_info->chunk_points * dst_type_size;
if(accessed_bytes != dataset->shared->layout.u.chunk.size)
relax = FALSE;
@@ -1832,7 +1845,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
/* Perform the actual read operation */
if((io_info->ops.write)(io_info, chunk_info->chunk_points,
- H5T_get_size(dataset->shared->type), chunk_info->fspace,
+ dst_type_size, chunk_info->fspace,
chunk_info->mspace, chunk_addr, chunk, buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, " chunked write failed")
@@ -1844,7 +1857,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
relax = TRUE;
/* Advance to next chunk in list */
- chunk_node = H5SL_next(chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
} /* end while */
#ifdef H5_HAVE_PARALLEL
}
@@ -1852,7 +1865,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
#ifdef H5S_DEBUG
H5_timer_end(&(io_info->stats->stats[0].write_timer), &timer);
- io_info->stats->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type);
+ io_info->stats->stats[0].write_nbytes += nelmts * src_type_size;
io_info->stats->stats[0].write_ncalls++;
#endif
@@ -1866,10 +1879,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
if(nelmts==0)
HGOTO_DONE(SUCCEED)
- /* Compute element sizes and other parameters */
- src_type_size = H5T_get_size(mem_type);
- dst_type_size = H5T_get_size(dataset->shared->type);
- max_type_size = MAX(src_type_size, dst_type_size);
+ /* Compute buffer sizes and other parameters */
target_size = dxpl_cache->max_temp_buf;
/* XXX: This could cause a problem if the user sets their buffer size
* to the same size as the default, and then the dataset elements are
@@ -1910,29 +1920,29 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
} else {
need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
} /* end else */
- if (NULL==(tconv_buf=dxpl_cache->tconv_buf)) {
+ if(NULL == (tconv_buf = (uint8_t *)dxpl_cache->tconv_buf)) {
/* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_conv, target_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
} /* end if */
- if (need_bkg && NULL==(bkg_buf=dxpl_cache->bkgr_buf)) {
+ if(need_bkg && NULL == (bkg_buf = (uint8_t *)dxpl_cache->bkgr_buf)) {
/* Allocate background buffer */
/* (Don't need calloc()-like call since file data is already initialized) */
- if((bkg_buf=H5FL_BLK_MALLOC(type_conv,(request_nelmts*dst_type_size)))==NULL)
+ if(NULL == (bkg_buf = H5FL_BLK_MALLOC(type_conv, (request_nelmts * dst_type_size))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion")
} /* end if */
/* 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 = H5D_CHUNK_GET_FIRST_NODE(fm);
/* Iterate through chunks to be operated on */
while(chunk_node) {
H5D_chunk_info_t *chunk_info; /* chunk information */
/* Get the actual chunk information from the skip list node */
- chunk_info=H5SL_item(chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* initialize selection iterator */
if (H5S_select_iter_init(&file_iter, chunk_info->fspace, dst_type_size) < 0)
@@ -1954,11 +1964,11 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
chunk_addr = H5D_istore_get_addr(io_info, &udata);
if(H5D_istore_if_load(io_info, chunk_addr)) {
- accessed_bytes = chunk_info->chunk_points * H5T_get_size(dataset->shared->type);
+ accessed_bytes = chunk_info->chunk_points * dst_type_size;
if(accessed_bytes != dataset->shared->layout.u.chunk.size)
relax=FALSE;
if(relax) {
- accessed_bytes = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)*H5T_get_size(mem_type);
+ accessed_bytes = H5S_GET_SELECT_NPOINTS(chunk_info->mspace) * src_type_size;
if(accessed_bytes != dataset->shared->layout.u.chunk.size)
relax = FALSE;
}
@@ -2056,7 +2066,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
/* Release the cache lock on the chunk. */
if(chunk) {
- accessed_bytes = chunk_info->chunk_points * H5T_get_size(dataset->shared->type);
+ accessed_bytes = chunk_info->chunk_points * dst_type_size;
if(H5D_istore_unlock(io_info, TRUE, idx_hint, chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
@@ -2080,7 +2090,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
} /* end if */
/* Get the next chunk node in the skip list */
- chunk_node=H5SL_next(chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
} /* end while */
done:
@@ -2099,9 +2109,9 @@ done:
} /* end if */
if (tconv_buf && NULL==dxpl_cache->tconv_buf)
- H5FL_BLK_FREE(type_conv,tconv_buf);
+ (void)H5FL_BLK_FREE(type_conv,tconv_buf);
if (bkg_buf && NULL==dxpl_cache->bkgr_buf)
- H5FL_BLK_FREE(type_conv,bkg_buf);
+ (void)H5FL_BLK_FREE(type_conv,bkg_buf);
/* Release chunk mapping information */
if(H5D_destroy_chunk_map(&fm) < 0)
@@ -2193,7 +2203,7 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space,
off=_off;
} /* end else */
- if (NULL == (src = H5I_object(src_id)) || NULL == (dst = H5I_object(dst_id)))
+ if (NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
src_stride = H5T_get_size(src);
@@ -2299,7 +2309,7 @@ H5D_compound_opt_write(size_t nelmts, hid_t src_id, hid_t dst_id, void *data_buf
assert (data_buf);
assert (nelmts>0);
- if (NULL == (src = H5I_object(src_id)) || NULL == (dst = H5I_object(dst_id)))
+ if (NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
src_stride = H5T_get_size(src);
@@ -2344,7 +2354,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 */
@@ -2379,9 +2389,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++) {
@@ -2410,10 +2419,6 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info,
#endif /* H5_HAVE_PARALLEL */
- /* 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")
-
/* Initialize "last chunk" information */
fm->last_index = (hsize_t)-1;
fm->last_chunk_info = NULL;
@@ -2424,7 +2429,40 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info,
/* Special case for only one element in selection */
/* (usually appending a record) */
- if(nelmts == 1) {
+ if(nelmts == 1
+#ifdef H5_HAVE_PARALLEL
+ && !(io_info->using_mpi_vfd)
+#endif /* H5_HAVE_PARALLEL */
+ ) {
+ /* Initialize skip list for chunk selections */
+ fm->sel_chunks = NULL;
+ fm->use_single = TRUE;
+
+ /* Initialize single chunk dataspace */
+ if(NULL == dataset->shared->cache.chunk.single_space) {
+ /* Make a copy of the dataspace for the dataset */
+ if((dataset->shared->cache.chunk.single_space = H5S_copy(file_space, TRUE, FALSE)) == NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space")
+
+ /* Resize chunk's dataspace dimensions to size of chunk */
+ if(H5S_set_extent_real(dataset->shared->cache.chunk.single_space, fm->chunk_dim) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust chunk dimensions")
+
+ /* Set the single chunk dataspace to 'all' selection */
+ if(H5S_select_all(dataset->shared->cache.chunk.single_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to set all selection")
+ } /* end if */
+ fm->single_space = dataset->shared->cache.chunk.single_space;
+ HDassert(fm->single_space);
+
+ /* Allocate the single chunk information */
+ if(NULL == dataset->shared->cache.chunk.single_chunk_info) {
+ if(NULL == (dataset->shared->cache.chunk.single_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
+ } /* end if */
+ fm->single_chunk_info = dataset->shared->cache.chunk.single_chunk_info;
+ HDassert(fm->single_chunk_info);
+
/* Reset chunk template information */
fm->mchunk_tmpl = NULL;
@@ -2433,6 +2471,17 @@ 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 chunk selections for single element")
} /* end if */
else {
+ /* Initialize 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);
+
+ /* We are not using single element mode */
+ fm->use_single = FALSE;
+
/* Get type of selection on disk & in memory */
if((fsel_type = H5S_GET_SELECT_TYPE(file_space)) < H5S_SEL_NONE)
HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
@@ -2452,12 +2501,12 @@ 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 */
/* Get pointer to chunk's information */
- chunk_info=H5SL_item(curr_node);
+ chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
assert(chunk_info);
/* Clean hyperslab span's "scratch" information */
@@ -2527,12 +2576,12 @@ 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 */
/* Get pointer to chunk's information */
- chunk_info=H5SL_item(curr_node);
+ chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
assert(chunk_info);
/* Clean hyperslab span's "scratch" information */
@@ -2590,7 +2639,7 @@ done:
RETURNS
No return value
DESCRIPTION
- Releases all the memory for a chunk info node. Called by H5SL_iterate
+ Releases all the memory for a chunk info node. Called by H5SL_free
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
@@ -2599,21 +2648,24 @@ done:
static herr_t
H5D_free_chunk_info(void *item, void UNUSED *key, void UNUSED *opdata)
{
- H5D_chunk_info_t *chunk_info=(H5D_chunk_info_t *)item;
+ H5D_chunk_info_t *chunk_info = (H5D_chunk_info_t *)item;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_free_chunk_info)
- assert(chunk_info);
+ HDassert(chunk_info);
- /* Close the chunk's file dataspace */
- (void)H5S_close(chunk_info->fspace);
+ /* Close the chunk's file dataspace, if it's not shared */
+ if(!chunk_info->fspace_shared)
+ (void)H5S_close(chunk_info->fspace);
+ else
+ H5S_select_all(chunk_info->fspace, TRUE);
/* Close the chunk's memory dataspace, if it's not shared */
if(!chunk_info->mspace_shared)
(void)H5S_close(chunk_info->mspace);
/* Free the actual chunk info */
- H5FL_FREE(H5D_chunk_info_t,chunk_info);
+ H5FL_FREE(H5D_chunk_info_t, chunk_info);
FUNC_LEAVE_NOAPI(0);
} /* H5D_free_chunk_info() */
@@ -2638,14 +2690,23 @@ 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")
+ /* Single element I/O vs. multiple element I/O cleanup */
+ if(fm->use_single) {
+ /* Sanity checks */
+ HDassert(fm->sel_chunks == NULL);
+ HDassert(fm->single_chunk_info);
+ HDassert(fm->single_chunk_info->fspace_shared);
+ HDassert(fm->single_chunk_info->mspace_shared);
- H5SL_close(fm->fsel);
+ /* Reset the selection for the single element I/O */
+ H5S_select_all(fm->single_space, TRUE);
} /* end if */
+ else {
+ /* 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")
+ } /* end else */
/* Free the memory chunk dataspace template */
if(fm->mchunk_tmpl)
@@ -2680,8 +2741,7 @@ H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
#endif /* H5_HAVE_PARALLEL */
*io_info)
{
- H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
- H5D_chunk_info_t *new_chunk_info = NULL; /* chunk information to insert into skip list */
+ H5D_chunk_info_t *chunk_info; /* Chunk information to insert into skip list */
hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
unsigned u; /* Local index variable */
@@ -2696,62 +2756,49 @@ H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
if(H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
- /* Allocate the file & memory chunk information */
- if(NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
- new_chunk_info->chunk_points = 1;
+ /* Initialize the 'single chunk' file & memory chunk information */
+ chunk_info = fm->single_chunk_info;
+ chunk_info->chunk_points = 1;
/* Set chunk location & hyperslab size */
for(u = 0; u < fm->f_ndims; u++) {
HDassert(sel_start[u] == sel_end[u]);
- new_chunk_info->coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u];
+ chunk_info->coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u];
} /* end for */
- new_chunk_info->coords[fm->f_ndims] = 0;
+ chunk_info->coords[fm->f_ndims] = 0;
/* Calculate the index of this chunk */
- if(H5V_chunk_index(fm->f_ndims, new_chunk_info->coords, fm->layout->u.chunk.dim, fm->down_chunks, &new_chunk_info->index) < 0)
+ if(H5V_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_info->index) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
- /* Create chunk dataspace for selection operations (copy file space) */
- if((tmp_fchunk = H5S_copy(fm->file_space, FALSE, FALSE)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
-
- /* Resize chunk's dataspace dimensions to size of chunk */
- if(H5S_set_extent_real(tmp_fchunk, fm->chunk_dim) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk dimensions")
+ /* Copy selection for file's dataspace into chunk dataspace */
+ if(H5S_select_copy(fm->single_space, fm->file_space, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file selection")
/* Move selection back to have correct offset in chunk */
- if(H5S_SELECT_ADJUST_U(tmp_fchunk, new_chunk_info->coords) < 0)
+ if(H5S_SELECT_ADJUST_U(fm->single_space, chunk_info->coords) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection")
#ifdef H5_HAVE_PARALLEL
/* store chunk selection information */
if(io_info->using_mpi_vfd)
- fm->select_chunk[new_chunk_info->index] = TRUE;
+ fm->select_chunk[chunk_info->index] = TRUE;
#endif /* H5_HAVE_PARALLEL */
- /* Set the file chunk dataspace */
- new_chunk_info->fspace = tmp_fchunk;
+ /* Set the file dataspace for the chunk to the shared 'single' dataspace */
+ chunk_info->fspace = fm->single_space;
+
+ /* Indicate that the chunk's file dataspace is shared */
+ chunk_info->fspace_shared = TRUE;
/* Just point at the memory dataspace & selection */
/* (Casting away const OK -QAK) */
- new_chunk_info->mspace = (H5S_t *)fm->mem_space;
-
- /* Indicate that the chunk's memory space is shared */
- new_chunk_info->mspace_shared = 1;
+ chunk_info->mspace = (H5S_t *)fm->mem_space;
- /* Insert the new chunk into the skip list */
- if(H5SL_insert(fm->fsel, new_chunk_info, &new_chunk_info->index) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list")
+ /* Indicate that the chunk's memory dataspace is shared */
+ chunk_info->mspace_shared = TRUE;
done:
- if(ret_value < 0) {
- if(new_chunk_info)
- (void)H5D_free_chunk_info(new_chunk_info, NULL, NULL);
- if(tmp_fchunk)
- (void)H5S_close(tmp_fchunk);
- } /* end if */
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_create_chunk_map_single() */
@@ -2868,11 +2915,12 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
#endif /* H5_HAVE_PARALLEL */
/* Set the file chunk dataspace */
- new_chunk_info->fspace=tmp_fchunk;
+ new_chunk_info->fspace = tmp_fchunk;
+ new_chunk_info->fspace_shared = FALSE;
/* Set the memory chunk dataspace */
new_chunk_info->mspace=NULL;
- new_chunk_info->mspace_shared=0;
+ new_chunk_info->mspace_shared = FALSE;
/* Copy the chunk's coordinates */
for(u=0; u<fm->f_ndims; u++)
@@ -2880,7 +2928,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 */
@@ -2971,14 +3019,14 @@ 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=H5SL_item(curr_node);
+ chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
assert(chunk_info);
/* Just point at the memory dataspace & selection */
@@ -2986,7 +3034,7 @@ H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
chunk_info->mspace=(H5S_t *)fm->mem_space;
/* Indicate that the chunk's memory space is shared */
- chunk_info->mspace_shared=1;
+ chunk_info->mspace_shared = TRUE;
} /* end if */
else {
/* Get bounding box for file selection */
@@ -3006,12 +3054,12 @@ 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 */
/* Get pointer to chunk's information */
- chunk_info=H5SL_item(curr_node);
+ chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
assert(chunk_info);
/* Copy the information */
@@ -3089,7 +3137,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((chunk_info=H5SL_search(fm->fsel,&chunk_index))==NULL) {
+ 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 */
@@ -3115,11 +3163,12 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
} /* end if */
/* Set the file chunk dataspace */
- chunk_info->fspace=fspace;
+ chunk_info->fspace = fspace;
+ chunk_info->fspace_shared = FALSE;
/* Set the memory chunk dataspace */
chunk_info->mspace=NULL;
- chunk_info->mspace_shared=0;
+ chunk_info->mspace_shared = FALSE;
/* Set the number of selected elements in chunk to zero */
chunk_info->chunk_points=0;
@@ -3132,7 +3181,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 */
@@ -3148,7 +3197,7 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
coords_in_chunk[u]=coords[u]%fm->layout->u.chunk.dim[u];
/* Add point to file selection for chunk */
- if(H5S_select_elements(chunk_info->fspace, H5S_SELECT_APPEND, (size_t)1, (const hsize_t **)coords_in_chunk) < 0)
+ if(H5S_select_elements(chunk_info->fspace, H5S_SELECT_APPEND, (size_t)1, coords_in_chunk) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
/* Increment the number of elemented selected in chunk */
@@ -3200,8 +3249,8 @@ 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((chunk_info=H5SL_search(fm->fsel,&chunk_index))==NULL)
- HGOTO_ERROR(H5E_DATASPACE,H5E_NOTFOUND,FAIL,"can't locate chunk in skip list")
+ 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 */
if(chunk_info->mspace==NULL) {
@@ -3221,7 +3270,7 @@ H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const
/* Add point to memory selection for chunk */
if(fm->msel_type==H5S_SEL_POINTS) {
- if(H5S_select_elements(chunk_info->mspace, H5S_SELECT_APPEND, (size_t)1, (const hsize_t **)coords_in_mem) < 0)
+ if(H5S_select_elements(chunk_info->mspace, H5S_SELECT_APPEND, (size_t)1, coords_in_mem) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
} /* end if */
else {
@@ -3331,7 +3380,7 @@ H5D_ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
H5P_genplist_t *dx_plist; /* Data transer property list */
/* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5I_object(dxpl_id)))
+ if (NULL == (dx_plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list")
/* Change the xfer_mode to independent for handling the I/O */
@@ -3395,7 +3444,7 @@ H5D_ioinfo_term(H5D_io_info_t *io_info)
H5P_genplist_t *dx_plist; /* Data transer property list */
/* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5I_object(io_info->dxpl_id)))
+ if (NULL == (dx_plist = (H5P_genplist_t *)H5I_object(io_info->dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list")
/* Restore the original parallel I/O mode */
@@ -3409,3 +3458,4 @@ done:
} /* end H5D_ioinfo_term() */
#endif
+
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 8a3c1b0..3b8fba7 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -540,22 +540,20 @@ H5D_istore_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_uda
/* slightly odd way the library initializes the right-most node in the */
/* indexed storage B-tree... */
/* (Dump the B-tree with h5debug to look at it) -QAK */
- if(udata->mesg->u.chunk.ndims==2) {
- if(udata->key.offset[0]>rt_key->offset[0])
- ret_value=1;
- else if(udata->key.offset[0]==rt_key->offset[0] &&
- udata->key.offset[1]>=rt_key->offset[1])
- ret_value=1;
- else if(udata->key.offset[0]<lt_key->offset[0])
- ret_value=(-1);
+ if(udata->mesg->u.chunk.ndims == 2) {
+ if(udata->offset[0] > rt_key->offset[0])
+ ret_value = 1;
+ else if(udata->offset[0] == rt_key->offset[0] &&
+ udata->offset[1] >= rt_key->offset[1])
+ ret_value = 1;
+ else if(udata->offset[0] < lt_key->offset[0])
+ ret_value = (-1);
} /* end if */
else {
- if (H5V_vector_ge_u(udata->mesg->u.chunk.ndims, udata->key.offset,
- rt_key->offset))
+ if(H5V_vector_ge_u(udata->mesg->u.chunk.ndims, udata->offset, rt_key->offset))
ret_value = 1;
- else if (H5V_vector_lt_u(udata->mesg->u.chunk.ndims, udata->key.offset,
- lt_key->offset))
- ret_value = -1;
+ else if(H5V_vector_lt_u(udata->mesg->u.chunk.ndims, udata->offset, lt_key->offset))
+ ret_value = (-1);
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
@@ -602,9 +600,9 @@ H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
HDassert(addr_p);
/* Allocate new storage */
- HDassert(udata->common.key.nbytes > 0);
- H5_CHECK_OVERFLOW(udata->common.key.nbytes ,size_t, hsize_t);
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->common.key.nbytes)))
+ HDassert(udata->nbytes > 0);
+ H5_CHECK_OVERFLOW(udata->nbytes, size_t, hsize_t);
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "couldn't allocate new file storage")
udata->addr = *addr_p;
@@ -612,24 +610,24 @@ H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
* The left key describes the storage of the UDATA chunk being
* inserted into the tree.
*/
- lt_key->nbytes = udata->common.key.nbytes;
- lt_key->filter_mask = udata->common.key.filter_mask;
- for (u=0; u<udata->common.mesg->u.chunk.ndims; u++)
- lt_key->offset[u] = udata->common.key.offset[u];
+ lt_key->nbytes = udata->nbytes;
+ lt_key->filter_mask = udata->filter_mask;
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ lt_key->offset[u] = udata->common.offset[u];
/*
* The right key might already be present. If not, then add a zero-width
* chunk.
*/
- if (H5B_INS_LEFT != op) {
+ if(H5B_INS_LEFT != op) {
rt_key->nbytes = 0;
rt_key->filter_mask = 0;
- for (u=0; u<udata->common.mesg->u.chunk.ndims; u++) {
- HDassert(udata->common.key.offset[u]+udata->common.mesg->u.chunk.dim[u] >
- udata->common.key.offset[u]);
- rt_key->offset[u] = udata->common.key.offset[u] + udata->common.mesg->u.chunk.dim[u];
- }
- }
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++) {
+ HDassert(udata->common.offset[u] + udata->common.mesg->u.chunk.dim[u] >
+ udata->common.offset[u]);
+ rt_key->offset[u] = udata->common.offset[u] + udata->common.mesg->u.chunk.dim[u];
+ } /* end if */
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -680,16 +678,14 @@ H5D_istore_found(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, const void
/* Is this *really* the requested chunk? */
for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
- if(udata->common.key.offset[u] >= lt_key->offset[u] + udata->common.mesg->u.chunk.dim[u])
+ if(udata->common.offset[u] >= lt_key->offset[u] + udata->common.mesg->u.chunk.dim[u])
HGOTO_DONE(FAIL)
/* Initialize return values */
+ HDassert(lt_key->nbytes > 0);
udata->addr = addr;
- udata->common.key.nbytes = lt_key->nbytes;
- udata->common.key.filter_mask = lt_key->filter_mask;
- HDassert(lt_key->nbytes>0);
- for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
- udata->common.key.offset[u] = lt_key->offset[u];
+ udata->nbytes = lt_key->nbytes;
+ udata->filter_mask = lt_key->filter_mask;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -755,18 +751,18 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
cmp = H5D_istore_cmp3(f, dxpl_id, lt_key, udata, rt_key);
HDassert(cmp <= 0);
- if (cmp < 0) {
+ if(cmp < 0) {
/* Negative indices not supported yet */
HGOTO_ERROR(H5E_STORAGE, H5E_UNSUPPORTED, H5B_INS_ERROR, "internal error")
- } else if (H5V_vector_eq_u (udata->common.mesg->u.chunk.ndims,
- udata->common.key.offset, lt_key->offset) &&
- lt_key->nbytes>0) {
+ } else if(H5V_vector_eq_u(udata->common.mesg->u.chunk.ndims,
+ udata->common.offset, lt_key->offset) &&
+ lt_key->nbytes > 0) {
/*
* Already exists. If the new size is not the same as the old size
* then we should reallocate storage.
*/
- if (lt_key->nbytes != udata->common.key.nbytes) {
+ if(lt_key->nbytes != udata->nbytes) {
/* Currently, the old chunk data is "thrown away" after the space is reallocated,
* so avoid data copy in H5MF_realloc() call by just free'ing the space and
* allocating new space.
@@ -778,18 +774,18 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
*/
#ifdef OLD_WAY
if(HADDR_UNDEF == (*new_node_p = H5MF_realloc(f, H5FD_MEM_DRAW, addr,
- (hsize_t)lt_key->nbytes, (hsize_t)udata->common.key.nbytes)))
+ (hsize_t)lt_key->nbytes, (hsize_t)udata->nbytes)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "unable to reallocate chunk storage")
#else /* OLD_WAY */
H5_CHECK_OVERFLOW( lt_key->nbytes ,size_t, hsize_t);
if(H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes)<0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, H5B_INS_ERROR, "unable to free chunk")
- H5_CHECK_OVERFLOW(udata->common.key.nbytes ,size_t, hsize_t);
- if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->common.key.nbytes)))
+ H5_CHECK_OVERFLOW(udata->nbytes ,size_t, hsize_t);
+ if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "unable to reallocate chunk")
#endif /* OLD_WAY */
- lt_key->nbytes = udata->common.key.nbytes;
- lt_key->filter_mask = udata->common.key.filter_mask;
+ lt_key->nbytes = udata->nbytes;
+ lt_key->filter_mask = udata->filter_mask;
*lt_key_changed = TRUE;
udata->addr = *new_node_p;
ret_value = H5B_INS_CHANGE;
@@ -800,26 +796,26 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
} else if (H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
lt_key->offset, udata->common.mesg->u.chunk.dim,
- udata->common.key.offset, udata->common.mesg->u.chunk.dim)) {
+ udata->common.offset, udata->common.mesg->u.chunk.dim)) {
HDassert(H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
rt_key->offset, udata->common.mesg->u.chunk.dim,
- udata->common.key.offset, udata->common.mesg->u.chunk.dim));
+ udata->common.offset, udata->common.mesg->u.chunk.dim));
/*
* Split this node, inserting the new new node to the right of the
* current node. The MD_KEY is where the split occurs.
*/
- md_key->nbytes = udata->common.key.nbytes;
- md_key->filter_mask = udata->common.key.filter_mask;
+ md_key->nbytes = udata->nbytes;
+ md_key->filter_mask = udata->filter_mask;
for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++) {
- HDassert(0 == udata->common.key.offset[u] % udata->common.mesg->u.chunk.dim[u]);
- md_key->offset[u] = udata->common.key.offset[u];
- }
+ HDassert(0 == udata->common.offset[u] % udata->common.mesg->u.chunk.dim[u]);
+ md_key->offset[u] = udata->common.offset[u];
+ } /* end for */
/*
* Allocate storage for the new chunk
*/
- H5_CHECK_OVERFLOW(udata->common.key.nbytes ,size_t, hsize_t);
- if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->common.key.nbytes)))
+ H5_CHECK_OVERFLOW(udata->nbytes, size_t, hsize_t);
+ if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "file allocation failed")
udata->addr = *new_node_p;
ret_value = H5B_INS_RIGHT;
@@ -898,7 +894,7 @@ H5D_istore_iter_chunkmap (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_lt
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_istore_iter_allocated() */
+} /* H5D_istore_iter_chunkmap() */
/*-------------------------------------------------------------------------
@@ -1082,17 +1078,19 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
HDmemcpy(buf, bkg, buf_size);
} /* end if */
- /* Copy source chunk callback information for insertion */
- HDmemset(&udata_dst, 0, sizeof(udata_dst));
- HDmemcpy(&(udata_dst.common.key), lt_key, sizeof(H5D_istore_key_t));
+ /* Set up destination chunk callback information for insertion */
udata_dst.common.mesg = udata->common.mesg; /* Share this pointer for a short while */
+ udata_dst.common.offset = lt_key->offset;
+ udata_dst.nbytes = lt_key->nbytes;
+ udata_dst.filter_mask = lt_key->filter_mask;
+ udata_dst.addr = HADDR_UNDEF;
/* Need to compress variable-length & reference data elements before writing to file */
if(is_compressed && (is_vlen || fix_ref) ) {
- if(H5Z_pipeline(pline, 0, &(udata_dst.common.key.filter_mask), edc_read,
+ if(H5Z_pipeline(pline, 0, &(udata_dst.filter_mask), edc_read,
cb_struct, &nbytes, &buf_size, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "output pipeline failed")
- udata_dst.common.key.nbytes = nbytes;
+ udata_dst.nbytes = nbytes;
udata->buf = buf;
udata->buf_size = buf_size;
} /* end if */
@@ -1112,6 +1110,120 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_cinfo_cache_reset
+ *
+ * Purpose: Reset the cached chunk info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * November 27, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_istore_cinfo_cache_reset(H5D_chunk_cached_t *last)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_cinfo_cache_reset)
+
+ /* Sanity check */
+ HDassert(last);
+
+ /* Indicate that the cached info is not valid */
+ last->valid = FALSE;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5D_istore_cinfo_cache_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_istore_cinfo_cache_update
+ *
+ * Purpose: Update the cached chunk info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * November 27, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_istore_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_istore_ud1_t *udata)
+{
+ unsigned u; /* Local index variable */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_cinfo_cache_update)
+
+ /* Sanity check */
+ HDassert(last);
+ HDassert(udata);
+ HDassert(udata->common.mesg);
+ HDassert(udata->common.offset);
+
+ /* Stored the information to cache */
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ last->offset[u] = udata->common.offset[u];
+ last->nbytes = udata->nbytes;
+ last->filter_mask = udata->filter_mask;
+ last->addr = udata->addr;
+
+ /* Indicate that the cached info is valid */
+ last->valid = TRUE;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5D_istore_cinfo_cache_update() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_istore_cinfo_cache_found
+ *
+ * Purpose: Look for chunk info in cache
+ *
+ * Return: TRUE/FALSE/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * November 27, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+H5D_istore_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_istore_ud1_t *udata)
+{
+ hbool_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_cinfo_cache_found)
+
+ /* Sanity check */
+ HDassert(last);
+ HDassert(udata);
+ HDassert(udata->common.mesg);
+ HDassert(udata->common.offset);
+
+ /* Check if the cached information is what is desired */
+ if(last->valid) {
+ unsigned u; /* Local index variable */
+
+ /* Check that the offset is the same */
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ if(last->offset[u] != udata->common.offset[u])
+ HGOTO_DONE(FALSE)
+
+ /* Retrieve the information from the cache */
+ udata->nbytes = last->nbytes;
+ udata->filter_mask = last->filter_mask;
+ udata->addr = last->addr;
+
+ /* Indicate that the data was found */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D_istore_cinfo_cache_found() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_init
*
* Purpose: Initialize the raw data chunk cache for a dataset. This is
@@ -1125,23 +1237,26 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_istore_init (const H5F_t *f, const H5D_t *dset)
+H5D_istore_init(const H5F_t *f, const H5D_t *dset)
{
H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_init, FAIL)
- if (H5F_RDCC_NBYTES(f)>0 && H5F_RDCC_NELMTS(f)>0) {
- rdcc->nbytes=H5F_RDCC_NBYTES(f);
+ if(H5F_RDCC_NBYTES(f) > 0 && H5F_RDCC_NELMTS(f) > 0) {
+ rdcc->nbytes = H5F_RDCC_NBYTES(f);
rdcc->nslots = H5F_RDCC_NELMTS(f);
rdcc->slot = H5FL_SEQ_CALLOC (H5D_rdcc_ent_ptr_t,rdcc->nslots);
- if (NULL==rdcc->slot)
+ if(NULL==rdcc->slot)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Reset any cached chunk info for this dataset */
+ H5D_istore_cinfo_cache_reset(&(rdcc->last));
} /* end if */
/* Allocate the shared structure */
- if(H5D_istore_shared_create(f, &dset->shared->layout)<0)
+ if(H5D_istore_shared_create(f, &dset->shared->layout) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1166,11 +1281,10 @@ done:
static herr_t
H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_t reset)
{
- herr_t ret_value=SUCCEED; /*return value */
- unsigned u; /*counters */
- void *buf=NULL; /*temporary buffer */
+ void *buf = NULL; /*temporary buffer */
size_t alloc; /*bytes allocated for BUF */
hbool_t point_of_no_return = FALSE;
+ herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_flush_entry)
@@ -1180,30 +1294,33 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
assert(!ent->locked);
buf = ent->chunk;
- if (ent->dirty) {
+ if(ent->dirty) {
H5D_istore_ud1_t udata; /*pass through B-tree */
+ /* Initial buffer size */
+ alloc = ent->alloc_size;
+
+ /* Set up user data for B-tree callbacks */
udata.common.mesg = &io_info->dset->shared->layout;
- udata.common.key.filter_mask = 0;
+ udata.common.offset = ent->offset;
+ udata.filter_mask = 0;
+ udata.nbytes = ent->chunk_size;
udata.addr = HADDR_UNDEF;
- udata.common.key.nbytes = ent->chunk_size;
- for (u=0; u<io_info->dset->shared->layout.u.chunk.ndims; u++)
- udata.common.key.offset[u] = ent->offset[u];
- alloc = ent->alloc_size;
/* Should the chunk be filtered before writing it to disk? */
- if (io_info->dset->shared->dcpl_cache.pline.nused) {
- if (!reset) {
+ if(io_info->dset->shared->dcpl_cache.pline.nused) {
+ if(!reset) {
/*
* Copy the chunk to a new buffer before running it through
* the pipeline because we'll want to save the original buffer
* for later.
*/
alloc = ent->chunk_size;
- if (NULL==(buf = H5MM_malloc(alloc)))
+ if(NULL == (buf = H5MM_malloc(alloc)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline")
HDmemcpy(buf, ent->chunk, ent->chunk_size);
- } else {
+ } /* end if */
+ else {
/*
* If we are reseting and something goes wrong after this
* point then it's too late to recover because we may have
@@ -1213,11 +1330,11 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
*/
point_of_no_return = TRUE;
ent->chunk = NULL;
- }
- if (H5Z_pipeline(&(io_info->dset->shared->dcpl_cache.pline), 0, &(udata.common.key.filter_mask), io_info->dxpl_cache->err_detect,
- io_info->dxpl_cache->filter_cb, &(udata.common.key.nbytes), &alloc, &buf)<0)
+ } /* end else */
+ if(H5Z_pipeline(&(io_info->dset->shared->dcpl_cache.pline), 0, &(udata.filter_mask), io_info->dxpl_cache->err_detect,
+ io_info->dxpl_cache->filter_cb, &(udata.nbytes), &alloc, &buf) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "output pipeline failed")
- }
+ } /* end if */
/*
* Create the chunk it if it doesn't exist, or reallocate the chunk if
@@ -1225,9 +1342,12 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
*/
if(H5B_insert(io_info->dset->oloc.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, &udata)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
- if(H5F_block_write(io_info->dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, io_info->dxpl_id, buf) < 0)
+ if(H5F_block_write(io_info->dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.nbytes, io_info->dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
+ /* Cache the chunk's info, in case it's accessed again shortly */
+ H5D_istore_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
+
/* Mark cache entry as clean */
ent->dirty = FALSE;
#ifdef H5D_ISTORE_DEBUG
@@ -1236,17 +1356,17 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
} /* end if */
/* Reset, but do not free or removed from list */
- if (reset) {
+ if(reset) {
point_of_no_return = FALSE;
- if(buf==ent->chunk)
+ if(buf == ent->chunk)
buf = NULL;
- if(ent->chunk!=NULL)
- ent->chunk = H5D_istore_chunk_xfree(ent->chunk,&(io_info->dset->shared->dcpl_cache.pline));
+ if(ent->chunk != NULL)
+ ent->chunk = (uint8_t *)H5D_istore_chunk_xfree(ent->chunk, &(io_info->dset->shared->dcpl_cache.pline));
} /* end if */
done:
/* Free the temp buffer only if it's different than the entry chunk */
- if (buf!=ent->chunk)
+ if(buf != ent->chunk)
H5MM_xfree(buf);
/*
@@ -1255,9 +1375,9 @@ done:
* output pipeline failed. Do not free the entry or remove it from the
* list.
*/
- if (ret_value<0 && point_of_no_return) {
+ if(ret_value < 0 && point_of_no_return) {
if(ent->chunk)
- ent->chunk = H5D_istore_chunk_xfree(ent->chunk,&(io_info->dset->shared->dcpl_cache.pline));
+ ent->chunk = (uint8_t *)H5D_istore_chunk_xfree(ent->chunk, &(io_info->dset->shared->dcpl_cache.pline));
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1294,12 +1414,12 @@ H5D_istore_preempt(const H5D_io_info_t *io_info, H5D_rdcc_ent_t * ent, hbool_t f
/* Flush */
if(H5D_istore_flush_entry(io_info, ent, TRUE) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer")
- }
+ } /* end if */
else {
/* Don't flush, just free chunk */
if(ent->chunk != NULL)
- ent->chunk = H5D_istore_chunk_xfree(ent->chunk,&(io_info->dset->shared->dcpl_cache.pline));
- }
+ ent->chunk = (uint8_t *)H5D_istore_chunk_xfree(ent->chunk, &(io_info->dset->shared->dcpl_cache.pline));
+ } /* end else */
/* Unlink from list */
if(ent->prev)
@@ -1520,13 +1640,13 @@ H5D_istore_shared_free (void *_shared)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_shared_free)
/* Free the raw B-tree node buffer */
- H5FL_BLK_FREE(chunk_page,shared->page);
+ (void)H5FL_BLK_FREE(chunk_page, shared->page);
/* Free the B-tree native key offsets buffer */
- H5FL_SEQ_FREE(size_t,shared->nkey);
+ H5FL_SEQ_FREE(size_t, shared->nkey);
/* Free the shared B-tree info */
- H5FL_FREE(H5B_shared_t,shared);
+ H5FL_FREE(H5B_shared_t, shared);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5D_istore_shared_free() */
@@ -1770,15 +1890,15 @@ H5D_istore_lock(const H5D_io_info_t *io_info, H5D_istore_ud1_t *udata,
*/
/* Chunk size on disk isn't [likely] the same size as the final chunk
* size in memory, so allocate memory big enough. */
- chunk_alloc = udata->common.key.nbytes;
+ chunk_alloc = udata->nbytes;
if(NULL == (chunk = H5D_istore_chunk_alloc (chunk_alloc, pline)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk")
- if(H5F_block_read(dset->oloc.file, H5FD_MEM_DRAW, chunk_addr, udata->common.key.nbytes, io_info->dxpl_id, chunk) < 0)
+ if(H5F_block_read(dset->oloc.file, H5FD_MEM_DRAW, chunk_addr, udata->nbytes, io_info->dxpl_id, chunk) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk")
if(pline->nused)
- if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->common.key.filter_mask), io_info->dxpl_cache->err_detect,
- io_info->dxpl_cache->filter_cb, &(udata->common.key.nbytes), &chunk_alloc, &chunk) < 0)
+ if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->filter_mask), io_info->dxpl_cache->err_detect,
+ io_info->dxpl_cache->filter_cb, &(udata->nbytes), &chunk_alloc, &chunk) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, NULL, "data pipeline read failed")
#ifdef H5D_ISTORE_DEBUG
rdcc->nmisses++;
@@ -2336,7 +2456,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a
H5D_BUILD_IO_INFO(&chk_io_info,dset,io_info->dxpl_cache,io_info->dxpl_id,&chk_store);
/* Do I/O directly on chunk without reading it into the cache */
- if ((ret_value=H5D_contig_writevv(&chk_io_info, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, (haddr_t)0, NULL, buf))<0)
+ if((ret_value = H5D_contig_writevv(&chk_io_info, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, (haddr_t)0, NULL, buf)) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
} /* end if */
else {
@@ -2524,7 +2644,6 @@ H5D_istore_get_addr(const H5D_io_info_t *io_info, H5D_istore_ud1_t *_udata)
{
H5D_istore_ud1_t tmp_udata; /* Information about a chunk */
H5D_istore_ud1_t *udata; /* Pointer to information about a chunk */
- unsigned u;
haddr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_get_addr)
@@ -2538,28 +2657,39 @@ H5D_istore_get_addr(const H5D_io_info_t *io_info, H5D_istore_ud1_t *_udata)
udata = (_udata != NULL ? _udata : &tmp_udata);
/* Initialize the information about the chunk we are looking for */
- for(u = 0; u < io_info->dset->shared->layout.u.chunk.ndims; u++)
- udata->common.key.offset[u] = io_info->store->chunk.offset[u];
udata->common.mesg = &(io_info->dset->shared->layout);
+ udata->common.offset = io_info->store->chunk.offset;
+ udata->nbytes = 0;
+ udata->filter_mask = 0;
udata->addr = HADDR_UNDEF;
- /* Go get the chunk information */
- if (H5B_find (io_info->dset->oloc.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, udata)<0) {
- /* Note: don't push error on stack, leave that to next higher level,
- * since many times the B-tree is searched in order to determine
- * if a chunk exists in the B-tree or not. -QAK
- */
+ /* Check for cached information */
+ if(!H5D_istore_cinfo_cache_found(&io_info->dset->shared->cache.chunk.last, udata)) {
+ /* Go get the chunk information */
+ if(H5B_find(io_info->dset->oloc.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, udata) < 0) {
+ /* Note: don't push error on stack, leave that to next higher level,
+ * since many times the B-tree is searched in order to determine
+ * if a chunk exists in the B-tree or not. -QAK
+ */
#ifdef OLD_WAY
- H5E_clear_stack(NULL);
+ H5E_clear_stack(NULL);
- HGOTO_ERROR(H5E_BTREE,H5E_NOTFOUND,HADDR_UNDEF,"Can't locate chunk info")
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, HADDR_UNDEF, "Can't locate chunk info")
#else /* OLD_WAY */
- HGOTO_DONE(HADDR_UNDEF)
+ /* Cache the fact that the chunk is not in the B-tree */
+ H5D_istore_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, udata);
+
+ HGOTO_DONE(HADDR_UNDEF)
#endif /* OLD_WAY */
- } /* end if */
+ } /* end if */
+
+ /* Cache the information retrieved */
+ HDassert(H5F_addr_defined(udata->addr));
+ H5D_istore_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, udata);
+ } /* end else */
/* Success! Set the return value */
- ret_value=udata->addr;
+ ret_value = udata->addr;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2624,7 +2754,7 @@ H5D_istore_chunk_xfree(void *chk, const H5O_pline_t *pline)
if(pline->nused > 0)
H5MM_xfree(chk);
else
- H5FL_BLK_FREE(chunk, chk);
+ (void)H5FL_BLK_FREE(chunk, chk);
} /* end if */
FUNC_LEAVE_NOAPI(NULL)
@@ -2834,11 +2964,10 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Initialize the chunk information */
udata.common.mesg = layout;
- udata.common.key.filter_mask = filter_mask;
+ udata.common.offset = chunk_offset;
+ udata.nbytes = chunk_size;
+ udata.filter_mask = filter_mask;
udata.addr = HADDR_UNDEF;
- udata.common.key.nbytes = chunk_size;
- for(u = 0; u < layout->u.chunk.ndims; u++)
- udata.common.key.offset[u] = chunk_offset[u];
/* Allocate the chunk with all processes */
if(H5B_insert(dset->oloc.file, dxpl_id, H5B_ISTORE, layout->u.chunk.addr, &udata) < 0)
@@ -2855,7 +2984,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Write the chunks out from only one process */
/* !! Use the internal "independent" DXPL!! -QAK */
if(H5_PAR_META_WRITE == mpi_rank)
- if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, data_dxpl_id, fb_info.fill_buf) < 0)
+ if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.nbytes, data_dxpl_id, fb_info.fill_buf) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
/* Indicate that blocks are being written */
@@ -2863,7 +2992,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, data_dxpl_id, fb_info.fill_buf) < 0)
+ if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.nbytes, data_dxpl_id, fb_info.fill_buf) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -2902,6 +3031,9 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
} /* end if */
#endif /* H5_HAVE_PARALLEL */
+ /* Reset any cached chunk info for this dataset */
+ H5D_istore_cinfo_cache_reset(&dset->shared->cache.chunk.last);
+
done:
/* Release the fill buffer info, if it's been initialized */
if(fb_info_init && H5D_fill_term(&fb_info) < 0)
@@ -3002,9 +3134,8 @@ H5D_istore_prune_remove(void *item, void UNUSED *key, void *op_data)
HDassert(rm_info);
/* Initialize the user data for the B-tree callback */
- HDmemset(&bt_udata, 0, sizeof bt_udata);
- bt_udata.key = sl_node->key;
bt_udata.mesg = rm_info->mesg;
+ bt_udata.offset = sl_node->key.offset;
/* Remove */
if(H5B_remove(rm_info->f, rm_info->dxpl_id, H5B_ISTORE, rm_info->mesg->u.chunk.addr, &bt_udata) < 0)
@@ -3212,6 +3343,9 @@ H5D_istore_prune_by_extent(const H5D_io_info_t *io_info, const hsize_t *old_dims
/* Destroy the skip list, deleting the chunks in the callback */
H5SL_destroy(udata.outside, H5D_istore_prune_remove, &rm_info);
+ /* Reset any cached chunk info for this dataset */
+ H5D_istore_cinfo_cache_reset(&dset->shared->cache.chunk.last);
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_istore_prune_by_extent() */
@@ -3406,7 +3540,7 @@ H5D_istore_initialize_by_extent(H5D_io_info_t *io_info)
/* Lock the chunk into the cache, to get a pointer to the chunk buffer */
store.chunk.offset = chunk_offset;
- if(NULL == (chunk = H5D_istore_lock(io_info, NULL, FALSE, &idx_hint)))
+ if(NULL == (chunk = (uint8_t *)H5D_istore_lock(io_info, NULL, FALSE, &idx_hint)))
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk")
@@ -3546,39 +3680,46 @@ H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id)
H5D_rdcc_ent_t *ent, *next; /*cache entry */
H5D_rdcc_ent_t *old_ent; /* Old cache entry */
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
- H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */
- unsigned rank; /*current # of dimensions */
+ H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
+ unsigned rank; /*current # of dimensions */
hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /*current dataspace dimensions */
hsize_t chunks[H5O_LAYOUT_NDIMS]; /*current number of chunks in each dimension */
hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of elements in each dimension */
- unsigned u; /*counters */
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned u; /*counters */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_update_cache, FAIL)
/* Check args */
- assert(dset && H5D_CHUNKED == dset->shared->layout.type);
- assert(dset->shared->layout.u.chunk.ndims > 0 && dset->shared->layout.u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(dset && H5D_CHUNKED == dset->shared->layout.type);
+ HDassert(dset->shared->layout.u.chunk.ndims > 0 && dset->shared->layout.u.chunk.ndims <= H5O_LAYOUT_NDIMS);
- /* Go get the rank & dimensions */
+ /* Get the rank */
rank = dset->shared->layout.u.chunk.ndims-1;
+ HDassert(rank > 0);
+
+ /* 1-D dataset's chunks can't have their index change */
+ if(rank == 1)
+ HGOTO_DONE(SUCCEED)
+
+ /* Go get the dimensions */
if(H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
/* Round up to the next integer # of chunks, to accomodate partial chunks */
for(u = 0; u < rank; u++)
- chunks[u] = ((curr_dims[u]+dset->shared->layout.u.chunk.dim[u])-1) / dset->shared->layout.u.chunk.dim[u];
+ chunks[u] = ((curr_dims[u] + dset->shared->layout.u.chunk.dim[u]) - 1) / dset->shared->layout.u.chunk.dim[u];
/* Get the "down" sizes for each dimension */
- if(H5V_array_down(rank,chunks,down_chunks) < 0)
+ if(H5V_array_down(rank, chunks, down_chunks) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes")
/* Fill the DXPL cache values for later use */
- if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache) < 0)
+ if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
/* Construct dataset I/O info */
- H5D_BUILD_IO_INFO(&io_info,dset,dxpl_cache,dxpl_id,NULL);
+ H5D_BUILD_IO_INFO(&io_info, dset, dxpl_cache, dxpl_id, NULL);
/* Recompute the index for each cached chunk that is in a dataset */
for(ent = rdcc->head; ent; ent = next) {
@@ -3596,26 +3737,26 @@ H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id)
old_idx=ent->idx; /* Save for later */
ent->idx=H5D_HASH(dset->shared,idx);
- if(old_idx!=ent->idx) {
+ if(old_idx != ent->idx) {
/* Check if there is already a chunk at this chunk's new location */
old_ent = rdcc->slot[ent->idx];
- if(old_ent!=NULL) {
- assert(old_ent->locked==0);
+ if(old_ent != NULL) {
+ HDassert(old_ent->locked == 0);
/* Check if we are removing the entry we would walk to next */
- if(old_ent==next)
- next=old_ent->next;
+ if(old_ent == next)
+ next = old_ent->next;
/* Remove the old entry from the cache */
- if (H5D_istore_preempt(&io_info, old_ent, TRUE )<0)
+ if(H5D_istore_preempt(&io_info, old_ent, TRUE) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks")
} /* end if */
/* Insert this chunk into correct location in hash table */
- rdcc->slot[ent->idx]=ent;
+ rdcc->slot[ent->idx] = ent;
/* Null out previous location */
- rdcc->slot[old_idx]=NULL;
+ rdcc->slot[old_idx] = NULL;
} /* end if */
} /* end for */
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 4fbec67..aec5e19 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -119,6 +119,26 @@ typedef struct H5D_io_info_t {
#endif /* H5S_DEBUG */
} H5D_io_info_t;
+/* Structure holding information about a chunk's selection for mapping */
+typedef struct H5D_chunk_info_t {
+ hsize_t index; /* "Index" of chunk in dataset */
+ size_t chunk_points; /* Number of elements selected in chunk */
+ hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */
+ H5S_t *fspace; /* Dataspace describing chunk & selection in it */
+ unsigned fspace_shared; /* Indicate that the file space for a chunk is shared and shouldn't be freed */
+ H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
+ unsigned mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */
+} H5D_chunk_info_t;
+
+/* Cached information about a particular chunk */
+typedef struct {
+ hbool_t valid; /*whether cache info is valid*/
+ hsize_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/
+ size_t nbytes; /*size of stored data */
+ unsigned filter_mask; /*excluded filters */
+ haddr_t addr; /*file address of chunk */
+} H5D_chunk_cached_t;
+
/* The raw data chunk cache */
typedef struct H5D_rdcc_t {
#ifdef H5D_ISTORE_DEBUG
@@ -132,7 +152,11 @@ typedef struct H5D_rdcc_t {
struct H5D_rdcc_ent_t *head; /* Head of doubly linked list */
struct H5D_rdcc_ent_t *tail; /* Tail of doubly linked list */
int nused; /* Number of chunk slots in use */
+ H5D_chunk_cached_t last; /* Cached copy of last chunk information */
struct H5D_rdcc_ent_t **slot; /* Chunk slots, each points to a chunk*/
+ H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */
+ H5S_t *single_space; /* Dataspace for single element I/O on chunks */
+ H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */
} H5D_rdcc_t;
/* The raw data contiguous data cache */
@@ -156,6 +180,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 */
@@ -188,16 +213,6 @@ typedef enum {
} H5D_time_alloc_t;
-/* Structure holding information about a chunk's selection for mapping */
-typedef struct H5D_chunk_info_t {
- hsize_t index; /* "Index" of chunk in dataset */
- size_t chunk_points; /* Number of elements selected in chunk */
- H5S_t *fspace; /* Dataspace describing chunk & selection in it */
- hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */
- H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
- unsigned mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */
-} H5D_chunk_info_t;
-
/* Main structure holding the mapping between file chunks and memory */
typedef struct H5D_chunk_map_t {
H5O_layout_t *layout; /* Dataset layout information*/
@@ -213,7 +228,10 @@ 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 */
+ H5S_t *single_space; /* Dataspace for single chunk */
+ H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */
+ hbool_t use_single; /* Whether I/O is on a single element */
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 */
@@ -289,14 +307,18 @@ typedef struct H5D_istore_key_t {
*/
typedef struct H5D_istore_bt_ud_common_t {
/* downward */
- H5D_istore_key_t key; /*key values */
- const H5O_layout_t *mesg; /*layout message */
+ const H5O_layout_t *mesg; /*layout message */
+ const hsize_t *offset; /*logical offset of chunk*/
} H5D_istore_bt_ud_common_t;
/* B-tree callback info for various operations */
typedef struct H5D_istore_ud1_t {
H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
- haddr_t addr; /*file address of chunk */
+
+ /* Upward */
+ size_t nbytes; /*size of stored data */
+ unsigned filter_mask; /*excluded filters */
+ haddr_t addr; /*file address of chunk */
} H5D_istore_ud1_t;
/* Internal data structure for computing variable-length dataset's total size */
@@ -329,7 +351,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/H5Dpublic.h b/src/H5Dpublic.h
index d7f6574..0d8b63f 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -113,7 +113,7 @@ H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, voi
H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size);
H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
hid_t buf_type, hid_t space);
-H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t *size);
+H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]);
H5_DLL herr_t H5Ddebug(hid_t dset_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
@@ -132,7 +132,7 @@ H5_DLL herr_t H5Ddebug(hid_t dset_id);
H5_DLL hid_t H5Dcreate1(hid_t file_id, const char *name, hid_t type_id,
hid_t space_id, hid_t dcpl_id);
H5_DLL hid_t H5Dopen1(hid_t file_id, const char *name);
-H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t *size);
+H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t size[]);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/H5Dselect.c b/src/H5Dselect.c
index 105b4e5..f08672f 100644
--- a/src/H5Dselect.c
+++ b/src/H5Dselect.c
@@ -46,6 +46,18 @@
/* Local Prototypes */
/********************/
+/* Struct for holding the vectorized I/O operation buffers "loosely" */
+typedef struct {
+ enum {
+ H5S_SELECT_READ, /* Read selection */
+ H5S_SELECT_WRITE /* Write selection */
+ } op_type;
+ union {
+ void *rbuf; /* Buffer for read */
+ const void *wbuf; /* Buffer to write */
+ } u;
+} H5D_select_buf_t;
+
/*********************/
/* Package Variables */
/*********************/
@@ -419,153 +431,199 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_select_read
+ * Function: H5D_select_io
*
- * Purpose: Reads directly from file into application memory.
+ * Purpose: Perform I/O directly from application memory and a file
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Tuesday, July 23, 2002
+ * Tuesday, November 27, 2007
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5D_select_read(H5D_io_info_t *io_info,
+static herr_t
+H5D_select_io(H5D_io_info_t *io_info,
size_t nelmts, size_t elmt_size,
const H5S_t *file_space, const H5S_t *mem_space,
haddr_t addr, void *chunk/*in*/,
- void *buf/*out*/)
+ const H5D_select_buf_t *io_buf)
{
H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
- hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
+ hbool_t mem_iter_init = 0; /* Memory selection iteration info has been initialized */
H5S_sel_iter_t file_iter; /* File selection iteration info */
- hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
+ hbool_t file_iter_init = 0; /* File selection iteration info has been initialized */
hsize_t _mem_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */
- hsize_t *mem_off=NULL; /* Pointer to sequence offsets in memory */
+ hsize_t *mem_off = NULL; /* Pointer to sequence offsets in memory */
hsize_t _file_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in the file */
- hsize_t *file_off=NULL; /* Pointer to sequence offsets in the file */
+ hsize_t *file_off = NULL; /* Pointer to sequence offsets in the file */
size_t _mem_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */
- size_t *mem_len=NULL; /* Pointer to sequence lengths in memory */
+ size_t *mem_len = NULL; /* Pointer to sequence lengths in memory */
size_t _file_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in the file */
- size_t *file_len=NULL; /* Pointer to sequence lengths in the file */
- size_t mem_nseq; /* Number of sequences generated in the file */
- size_t file_nseq; /* Number of sequences generated in memory */
- size_t mem_nelem; /* Number of elements used in memory sequences */
- size_t file_nelem; /* Number of elements used in file sequences */
+ size_t *file_len = NULL; /* Pointer to sequence lengths in the file */
size_t curr_mem_seq; /* Current memory sequence to operate on */
size_t curr_file_seq; /* Current file sequence to operate on */
+ size_t mem_nseq; /* Number of sequences generated in the file */
+ size_t file_nseq; /* Number of sequences generated in memory */
ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5D_select_read, FAIL);
+ FUNC_ENTER_NOAPI(H5D_select_io, FAIL)
/* Check args */
- assert(io_info);
- assert(io_info->dset);
- assert(io_info->dxpl_cache);
- assert(io_info->store);
- assert(buf);
- assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));
-
- /* Initialize file iterator */
- if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- file_iter_init=1; /* File selection iteration info has been initialized */
-
- /* Initialize memory iterator */
- if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- mem_iter_init=1; /* Memory selection iteration info has been initialized */
+ HDassert(io_info);
+ HDassert(io_info->dset);
+ HDassert(io_info->store);
+ HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER));
+ HDassert(io_buf->u.rbuf);
/* Allocate the vector I/O arrays */
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
- if((mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- if((file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
+ if(NULL == (mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array")
+ if(NULL == (mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array")
+ if(NULL == (file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array")
+ if(NULL == (file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array")
} /* end if */
else {
- mem_len=_mem_len;
- mem_off=_mem_off;
- file_len=_file_len;
- file_off=_file_off;
+ mem_len = _mem_len;
+ mem_off = _mem_off;
+ file_len = _file_len;
+ file_off = _file_off;
} /* end else */
- /* Initialize sequence counts */
- curr_mem_seq=curr_file_seq=0;
- mem_nseq=file_nseq=0;
-
- /* Loop, until all bytes are processed */
- while(nelmts>0) {
- /* Check if more file sequences are needed */
- if(curr_file_seq>=file_nseq) {
- /* Get sequences for file selection */
- if(H5S_SELECT_GET_SEQ_LIST(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,io_info->dxpl_cache->vec_size,nelmts,&file_nseq,&file_nelem,file_off,file_len)<0)
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
-
- /* Start at the beginning of the sequences again */
- curr_file_seq=0;
+ /* Check for only one element in selection */
+ if(nelmts == 1) {
+ /* Get offset of first element in selections */
+ if(H5S_SELECT_OFFSET(file_space, file_off) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve file selection offset")
+ if(H5S_SELECT_OFFSET(mem_space, mem_off) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve memory selection offset")
+
+ /* Set up necessary information for I/O operation */
+ file_nseq = mem_nseq = 1;
+ curr_mem_seq = curr_file_seq = 0;
+ *file_off *= elmt_size;
+ *mem_off *= elmt_size;
+ *file_len = *mem_len = elmt_size;
+
+ /* Perform I/O on memory and file sequences */
+ if(io_buf->op_type == H5S_SELECT_READ) {
+ if((tmp_file_len = (*io_info->ops.readvv)(io_info,
+ file_nseq, &curr_file_seq, file_len, file_off,
+ mem_nseq, &curr_mem_seq, mem_len, mem_off,
+ addr, chunk, io_buf->u.rbuf)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
} /* end if */
-
- /* Check if more memory sequences are needed */
- if(curr_mem_seq>=mem_nseq) {
- /* Get sequences for memory selection */
- if(H5S_SELECT_GET_SEQ_LIST(mem_space,0,&mem_iter,io_info->dxpl_cache->vec_size,nelmts,&mem_nseq,&mem_nelem,mem_off,mem_len)<0)
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
-
- /* Start at the beginning of the sequences again */
- curr_mem_seq=0;
- } /* end if */
-
- /* Read file sequences into current memory sequence */
- if ((tmp_file_len=(*io_info->ops.readvv)(io_info,
- file_nseq, &curr_file_seq, file_len, file_off,
- mem_nseq, &curr_mem_seq, mem_len, mem_off,
- addr, chunk, buf))<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
+ else {
+ HDassert(io_buf->op_type == H5S_SELECT_WRITE);
+ if((tmp_file_len = (*io_info->ops.writevv)(io_info,
+ file_nseq, &curr_file_seq, file_len, file_off,
+ mem_nseq, &curr_mem_seq, mem_len, mem_off,
+ addr, chunk, io_buf->u.wbuf)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
+ } /* end else */
/* Decrement number of elements left to process */
- assert((tmp_file_len%elmt_size)==0);
- nelmts-=(tmp_file_len/elmt_size);
- } /* end while */
+ HDassert((tmp_file_len % elmt_size) == 0);
+ } /* end if */
+ else {
+ size_t mem_nelem; /* Number of elements used in memory sequences */
+ size_t file_nelem; /* Number of elements used in file sequences */
+
+ /* Initialize file iterator */
+ if(H5S_select_iter_init(&file_iter, file_space, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ file_iter_init = 1; /* File selection iteration info has been initialized */
+
+ /* Initialize memory iterator */
+ if(H5S_select_iter_init(&mem_iter, mem_space, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ mem_iter_init = 1; /* Memory selection iteration info has been initialized */
+
+ /* Initialize sequence counts */
+ curr_mem_seq = curr_file_seq = 0;
+ mem_nseq = file_nseq = 0;
+
+ /* Loop, until all bytes are processed */
+ while(nelmts > 0) {
+ /* Check if more file sequences are needed */
+ if(curr_file_seq >= file_nseq) {
+ /* Get sequences for file selection */
+ if(H5S_SELECT_GET_SEQ_LIST(file_space, H5S_GET_SEQ_LIST_SORTED, &file_iter, io_info->dxpl_cache->vec_size, nelmts, &file_nseq, &file_nelem, file_off, file_len) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
+
+ /* Start at the beginning of the sequences again */
+ curr_file_seq = 0;
+ } /* end if */
+
+ /* Check if more memory sequences are needed */
+ if(curr_mem_seq >= mem_nseq) {
+ /* Get sequences for memory selection */
+ if(H5S_SELECT_GET_SEQ_LIST(mem_space, 0, &mem_iter, io_info->dxpl_cache->vec_size, nelmts, &mem_nseq, &mem_nelem, mem_off, mem_len) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
+
+ /* Start at the beginning of the sequences again */
+ curr_mem_seq = 0;
+ } /* end if */
+
+ /* Perform I/O on memory and file sequences */
+ if(io_buf->op_type == H5S_SELECT_READ) {
+ if((tmp_file_len = (*io_info->ops.readvv)(io_info,
+ file_nseq, &curr_file_seq, file_len, file_off,
+ mem_nseq, &curr_mem_seq, mem_len, mem_off,
+ addr, chunk, io_buf->u.rbuf)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
+ } /* end if */
+ else {
+ HDassert(io_buf->op_type == H5S_SELECT_WRITE);
+ if((tmp_file_len = (*io_info->ops.writevv)(io_info,
+ file_nseq, &curr_file_seq, file_len, file_off,
+ mem_nseq, &curr_mem_seq, mem_len, mem_off,
+ addr, chunk, io_buf->u.wbuf)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
+ } /* end else */
+
+ /* Decrement number of elements left to process */
+ HDassert((tmp_file_len % elmt_size) == 0);
+ nelmts -= (tmp_file_len / elmt_size);
+ } /* end while */
+ } /* end else */
done:
/* Release file selection iterator */
- if(file_iter_init) {
- if (H5S_SELECT_ITER_RELEASE(&file_iter)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- } /* end if */
+ if(file_iter_init)
+ if(H5S_SELECT_ITER_RELEASE(&file_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
/* Release memory selection iterator */
- if(mem_iter_init) {
- if (H5S_SELECT_ITER_RELEASE(&mem_iter)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- } /* end if */
+ if(mem_iter_init)
+ if(H5S_SELECT_ITER_RELEASE(&mem_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
/* Free vector arrays */
if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
- if(file_len!=NULL)
- H5FL_SEQ_FREE(size_t,file_len);
- if(file_off!=NULL)
- H5FL_SEQ_FREE(hsize_t,file_off);
- if(mem_len!=NULL)
- H5FL_SEQ_FREE(size_t,mem_len);
- if(mem_off!=NULL)
- H5FL_SEQ_FREE(hsize_t,mem_off);
+ if(file_len != NULL)
+ H5FL_SEQ_FREE(size_t, file_len);
+ if(file_off != NULL)
+ H5FL_SEQ_FREE(hsize_t, file_off);
+ if(mem_len != NULL)
+ H5FL_SEQ_FREE(size_t, mem_len);
+ if(mem_off != NULL)
+ H5FL_SEQ_FREE(hsize_t, mem_off);
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5D_select_read() */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_select_io() */
/*-------------------------------------------------------------------------
- * Function: H5D_select_write
+ * Function: H5D_select_read
*
- * Purpose: Writes directly from application memory into a file
+ * Purpose: Reads directly from file into application memory.
*
* Return: Non-negative on success/Negative on failure
*
@@ -575,133 +633,63 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_select_write(H5D_io_info_t *io_info,
+H5D_select_read(H5D_io_info_t *io_info,
size_t nelmts, size_t elmt_size,
const H5S_t *file_space, const H5S_t *mem_space,
haddr_t addr, void *chunk/*in*/,
- const void *buf/*out*/)
+ void *buf/*out*/)
{
- H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
- hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
- H5S_sel_iter_t file_iter; /* File selection iteration info */
- hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
- hsize_t _mem_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */
- hsize_t *mem_off=NULL; /* Pointer to sequence offsets in memory */
- hsize_t _file_off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in the file */
- hsize_t *file_off=NULL; /* Pointer to sequence offsets in the file */
- size_t _mem_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */
- size_t *mem_len=NULL; /* Pointer to sequence lengths in memory */
- size_t _file_len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in the file */
- size_t *file_len=NULL; /* Pointer to sequence lengths in the file */
- size_t mem_nseq; /* Number of sequences generated in the file */
- size_t file_nseq; /* Number of sequences generated in memory */
- size_t mem_nelem; /* Number of elements used in memory sequences */
- size_t file_nelem; /* Number of elements used in file sequences */
- size_t curr_mem_seq; /* Current memory sequence to operate on */
- size_t curr_file_seq; /* Current file sequence to operate on */
- ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5D_select_buf_t io_buf; /* Selection I/O operation to perform */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5D_select_write, FAIL);
+ FUNC_ENTER_NOAPI(H5D_select_read, FAIL)
- /* Check args */
- assert(io_info);
- assert(io_info->dset);
- assert(io_info->store);
- assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));
- assert(buf);
-
- /* Allocate the vector I/O arrays */
- if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
- if((mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- if((file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
- if((file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- } /* end if */
- else {
- mem_len=_mem_len;
- mem_off=_mem_off;
- file_len=_file_len;
- file_off=_file_off;
- } /* end else */
-
- /* Initialize file iterator */
- if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- file_iter_init=1; /* File selection iteration info has been initialized */
-
- /* Initialize memory iterator */
- if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- mem_iter_init=1; /* Memory selection iteration info has been initialized */
+ /* Construct proper I/O operation */
+ io_buf.op_type = H5S_SELECT_READ;
+ io_buf.u.rbuf = buf;
- /* Initialize sequence counts */
- curr_mem_seq=curr_file_seq=0;
- mem_nseq=file_nseq=0;
+ /* Call generic selection operation */
+ if(H5D_select_io(io_info, nelmts, elmt_size, file_space, mem_space, addr, chunk, &io_buf) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
- /* Loop, until all bytes are processed */
- while(nelmts>0) {
- /* Check if more file sequences are needed */
- if(curr_file_seq>=file_nseq) {
- /* Get sequences for file selection */
- if(H5S_SELECT_GET_SEQ_LIST(file_space,H5S_GET_SEQ_LIST_SORTED,&file_iter,io_info->dxpl_cache->vec_size,nelmts,&file_nseq,&file_nelem,file_off,file_len)<0)
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
-
- /* Start at the beginning of the sequences again */
- curr_file_seq=0;
- } /* end if */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_select_read() */
- /* Check if more memory sequences are needed */
- if(curr_mem_seq>=mem_nseq) {
- /* Get sequences for memory selection */
- if(H5S_SELECT_GET_SEQ_LIST(mem_space,0,&mem_iter,io_info->dxpl_cache->vec_size,nelmts,&mem_nseq,&mem_nelem,mem_off,mem_len)<0)
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_select_write
+ *
+ * Purpose: Writes directly from application memory into a file
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 23, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_select_write(H5D_io_info_t *io_info,
+ size_t nelmts, size_t elmt_size,
+ const H5S_t *file_space, const H5S_t *mem_space,
+ haddr_t addr, void *chunk/*in*/,
+ const void *buf/*out*/)
+{
+ H5D_select_buf_t io_buf; /* Selection I/O operation to perform */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Start at the beginning of the sequences again */
- curr_mem_seq=0;
- } /* end if */
+ FUNC_ENTER_NOAPI(H5D_select_write, FAIL)
- /* Write memory sequences into file sequences */
- if ((tmp_file_len=(*io_info->ops.writevv)(io_info,
- file_nseq, &curr_file_seq, file_len, file_off,
- mem_nseq, &curr_mem_seq, mem_len, mem_off,
- addr, chunk, buf))<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
+ /* Construct proper I/O operation */
+ io_buf.op_type = H5S_SELECT_WRITE;
+ io_buf.u.wbuf = buf;
- /* Decrement number of elements left to process */
- assert((tmp_file_len%elmt_size)==0);
- nelmts-=(tmp_file_len/elmt_size);
- } /* end while */
+ /* Call generic selection operation */
+ if(H5D_select_io(io_info, nelmts, elmt_size, file_space, mem_space, addr, chunk, &io_buf) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
done:
- /* Release file selection iterator */
- if(file_iter_init) {
- if (H5S_SELECT_ITER_RELEASE(&file_iter)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- } /* end if */
-
- /* Release memory selection iterator */
- if(mem_iter_init) {
- if (H5S_SELECT_ITER_RELEASE(&mem_iter)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- } /* end if */
-
- /* Free vector arrays */
- if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
- if(file_len!=NULL)
- H5FL_SEQ_FREE(size_t,file_len);
- if(file_off!=NULL)
- H5FL_SEQ_FREE(hsize_t,file_off);
- if(mem_len!=NULL)
- H5FL_SEQ_FREE(size_t,mem_len);
- if(mem_off!=NULL)
- H5FL_SEQ_FREE(hsize_t,mem_off);
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_select_write() */
diff --git a/src/H5F.c b/src/H5F.c
index 8a4b019..b1171bd 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -308,7 +308,7 @@ H5F_get_access_plist(H5F_t *f)
/* Copy properties of the file access property list */
if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial meta data cache resize config.")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache element size")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
@@ -321,11 +321,11 @@ H5F_get_access_plist(H5F_t *f)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment")
if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference")
- if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->lf->def_meta_block_size)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set meta data cache size")
+ if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->lf->meta_aggr.alloc_size)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache size")
if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size")
- if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->lf->def_sdata_block_size)) < 0)
+ if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->lf->sdata_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size")
if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag")
@@ -882,7 +882,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial meta data cache resize config")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache element size")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
@@ -900,6 +900,11 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag")
+ /* Get the VFD values to cache */
+ f->shared->maxaddr = H5FD_get_maxaddr(lf);
+ if(!H5F_addr_defined(f->shared->maxaddr))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD")
+
/* Bump superblock version if we are to use the latest version of the format */
if(f->shared->latest_format)
super_vers = HDF5_SUPERBLOCK_VERSION_LATEST;
@@ -924,12 +929,12 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
} /* end if */
/*
- * Create a meta data cache with the specified number of elements.
+ * Create a metadata cache with the specified number of elements.
* The cache might be created with a different number of elements and
* the access property list should be updated to reflect that.
*/
if(SUCCEED != H5AC_create(f, &(f->shared->mdc_initCacheCfg)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create meta data cache")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create metadata cache")
/* Create a metadata cache with modified API along side the regular
* version. For now, this is just for testing. Once we get it
@@ -1728,7 +1733,7 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
if(H5D_flush(f, dxpl_id, flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache")
- /* flush (and invalidate, if requested) the entire meta data cache */
+ /* flush (and invalidate, if requested) the entire metadata cache */
H5AC_flags = 0;
if((flags & H5F_FLUSH_INVALIDATE) != 0 )
H5AC_flags |= H5AC__FLUSH_INVALIDATE_FLAG;
@@ -1743,29 +1748,11 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
* "small data" blocks back to the free lists in the file.
*/
if(flags & H5F_FLUSH_INVALIDATE) {
- if(f->shared->lf->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- /* Return the unused portion of the metadata block to a free list */
- if(f->shared->lf->eoma != 0)
- if(H5FD_free(f->shared->lf, H5FD_MEM_DEFAULT, dxpl_id,
- f->shared->lf->eoma, f->shared->lf->cur_meta_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free metadata block")
-
- /* Reset metadata block information, just in case */
- f->shared->lf->eoma = 0;
- f->shared->lf->cur_meta_block_size = 0;
- } /* end if */
-
- if(f->shared->lf->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- /* Return the unused portion of the "small data" block to a free list */
- if(f->shared->lf->eosda != 0)
- if(H5FD_free(f->shared->lf, H5FD_MEM_DRAW, dxpl_id,
- f->shared->lf->eosda, f->shared->lf->cur_sdata_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free 'small data' block")
+ if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->meta_aggr), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset metadata block")
- /* Reset "small data" block information, just in case */
- f->shared->lf->eosda = 0;
- f->shared->lf->cur_sdata_block_size = 0;
- } /* end if */
+ if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->sdata_aggr), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset 'small data' block")
} /* end if */
/* Write the superblock to disk */
@@ -2479,8 +2466,6 @@ H5F_get_driver_id(const H5F_t *f)
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* March 27, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -2490,13 +2475,13 @@ H5F_get_fileno(const H5F_t *f, unsigned long *filenum)
FUNC_ENTER_NOAPI(H5F_get_fileno, FAIL)
- assert(f);
- assert(f->shared);
- assert(f->shared->lf);
- assert(filenum);
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+ HDassert(filenum);
/* Retrieve the file's serial number */
- if(H5FD_get_fileno(f->shared->lf,filenum) < 0)
+ if(H5FD_get_fileno(f->shared->lf, filenum) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "can't retrieve fileno")
done:
diff --git a/src/H5FD.c b/src/H5FD.c
index 096509e..3ae6d8e 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -24,18 +24,25 @@
* file driver layer.
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5FD_PACKAGE /*suppress error about including H5FDpkg */
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5FD_init_interface
-/* Packages needed by this file */
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
-#include "H5FDprivate.h" /* File drivers */
+#include "H5FDpkg.h" /* File Drivers */
#include "H5FDcore.h" /* Files stored entirely in memory */
#include "H5FDfamily.h" /* File families */
#include "H5FDlog.h" /* sec2 driver with I/O logging (for debugging) */
@@ -47,41 +54,50 @@
#include "H5FDwindows.h" /* Windows buffered I/O */
#endif
#include "H5FDdirect.h" /* Direct file I/O */
-#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
-/* static prototypes */
+/****************/
+/* Local Macros */
+/****************/
+
+/* Metadata accumulator controls */
+#define H5FD_ACCUM_THROTTLE 8
+#define H5FD_ACCUM_THRESHOLD 2048
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
static herr_t H5FD_pl_copy(void *(*copy_func)(const void *), size_t pl_size,
const void *old_pl, void **copied_pl);
static herr_t H5FD_pl_close(hid_t driver_id, herr_t (*free_func)(void *),
void *pl);
static herr_t H5FD_free_cls(H5FD_class_t *cls);
-static haddr_t H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type,
- hsize_t size);
-static haddr_t H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
- hsize_t size);
-static haddr_t H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
- hsize_t size);
-static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
-static herr_t H5FD_free_freelist(H5FD_t *file);
-static haddr_t H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
-
-/* Declare a free list to manage the H5FD_free_t struct */
-H5FL_DEFINE(H5FD_free_t);
-
-/* Declare a PQ free list to manage the metadata accumulator buffer */
-H5FL_BLK_DEFINE_STATIC(meta_accum);
-
-/* Local macro definitions */
-#define H5FD_ACCUM_THROTTLE 8
-#define H5FD_ACCUM_THRESHOLD 2048
-/* Define this to display information about file allocations */
-/* #define H5FD_ALLOC_DEBUG */
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
-/* Static local variables */
+/*******************/
+/* Local Variables */
+/*******************/
/*
* Global count of the number of H5FD_t's handed out. This is used as a
@@ -99,6 +115,32 @@ static unsigned long file_serial_no;
/*-------------------------------------------------------------------------
+ * Function: H5FD_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 3, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_init(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_init, FAIL)
+ /* FUNC_ENTER() does all the work */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_init() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5FD_init_interface
*
* Purpose: Initialize the virtual file layer.
@@ -1055,10 +1097,12 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
HDmemset(file->fl, 0, sizeof(file->fl));
if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(meta_block_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get meta data block size")
- file->def_meta_block_size = meta_block_size;
+ file->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA;
+ file->meta_aggr.alloc_size = meta_block_size;
if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(sdata_block_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' block size")
- file->def_sdata_block_size = sdata_block_size;
+ file->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA;
+ file->sdata_aggr.alloc_size = sdata_block_size;
file->accum_loc = HADDR_UNDEF;
if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(file->threshold)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold")
@@ -1182,74 +1226,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_free_freelist
- * Purpose: Split off from H5FD_close(). Free the elements in the
- * free list for this file driver.
- * Return: Success: SUCCEED
- * Failure: Never fails
- * Programmer: Bill Wendling
- * 17. February 2003
- * Modifications:
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_free_freelist(H5FD_t *file)
-{
- H5FD_mem_t i;
-#ifdef H5F_DEBUG
- unsigned nblocks = 0;
- hsize_t nbytes = 0;
-#endif /* H5F_DEBUG */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_free_freelist)
-
- /* check args */
- HDassert(file && file->cls);
-
- /*
- * Free all free-lists, leaking any memory thus described. Also leaks
- * file space allocated but not used when metadata aggregation is
- * turned on.
- */
- for(i = H5FD_MEM_DEFAULT; i < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, i)) {
- H5FD_free_t *cur, *next;
-
- for( cur = file->fl[i]; cur; cur = next) {
-#ifdef H5F_DEBUG
- ++nblocks;
- nbytes += cur->size;
-#endif /* H5F_DEBUG */
- next = cur->next;
- H5FL_FREE(H5FD_free_t, cur);
- } /* end for */
-
- file->fl[i] = NULL;
- } /* end for */
-
-#ifdef H5F_DEBUG
- if(nblocks && H5DEBUG(F))
- HDfprintf(H5DEBUG(F),
- "H5F: leaked %Hu bytes of file memory in %u blocks\n",
- nbytes, nblocks);
-#endif /* H5F_DEBUG */
-
- /* Check if we need to reset the metadata accumulator information */
- if(file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) {
- /* Free the buffer */
- if(file->meta_accum)
- file->meta_accum = H5FL_BLK_FREE(meta_accum, file->meta_accum);
-
- /* Reset the buffer sizes & location */
- file->accum_buf_size = file->accum_size = 0;
- file->accum_loc = HADDR_UNDEF;
- file->accum_dirty = 0;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5FD_free_freelist() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FDcmp
*
* Purpose: Compare the keys of two files using the file driver callback
@@ -1481,719 +1457,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_alloc
- * Purpose: Private version of H5FDalloc().
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- * Modifications:
- * Albert Cheng, 2001/05/01
- * Implement the allocation by alignment/threshold.
- *
- * Bill Wendling, 2002/12/02
- * Split apart into subfunctions for each separate task.
- *
- * Bill Wendling, 2003/02/19
- * Added support for FPHDF5.
- *
- * John Mainzer, 2004/04/13
- * Moved much of the FPHDF5 specific code into H5FP_client_alloc(),
- * and re-worked it to get rid of a race condition on the eoa.
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
-{
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI(H5FD_alloc, HADDR_UNDEF)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* check args */
- assert(file);
- assert(file->cls);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
-#ifdef H5F_DEBUG
- if(H5DEBUG(F))
- HDfprintf(H5DEBUG(F), "%s: alignment=%Hd, threshold=%Hd, size=%Hd\n",
- FUNC, file->alignment, file->threshold, size);
-#endif /* H5F_DEBUG */
-
- /* Try to allocate from the free list first */
- if((ret_value = H5FD_alloc_from_free_list(file, type, size)) != HADDR_UNDEF)
- HGOTO_DONE(ret_value)
-
-#ifdef H5F_DEBUG
- if(H5DEBUG(F))
- HDfprintf(H5DEBUG(F), "%s: Could not allocate from freelists\n", FUNC);
-#endif /* H5F_DEBUG */
-
- if(type != H5FD_MEM_DRAW) {
- /* Handle metadata differently from "raw" data */
- if((ret_value = H5FD_alloc_metadata(file, type, dxpl_id, size)) == HADDR_UNDEF)
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate for metadata")
- } else {
- /* Allocate "raw" data */
- if((ret_value = H5FD_alloc_raw(file, type, dxpl_id, size)) == HADDR_UNDEF)
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate for raw data")
- }
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_alloc_from_free_list
- * Purpose: Try to allocate SIZE bytes of memory from the free list
- * if possible.
- *
- * This is split from H5FD_alloc().
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- * Programmer: Bill Wendling
- * 02. December, 2002
- * Modifications:
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, hsize_t size)
-{
- H5FD_mem_t mapped_type;
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI(H5FD_alloc_from_free_list, HADDR_UNDEF)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- assert(file);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- /* Map the allocation request to a free list */
- if(H5FD_MEM_DEFAULT == file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
-
- /*
- * Try to satisfy the request from the free list. Only perform the
- * search if the free list has the potential of satisfying the
- * request.
- *
- * Here, aligned requests are requests that are >= threshold and
- * alignment > 1.
- *
- * For non-aligned request, first try to find an exact match,
- * otherwise use the best match which is the smallest size that meets
- * the requested size.
- *
- * For aligned address request, find a block in the following order
- * of preferences:
- *
- * 1. block address is aligned and exact match in size;
- * 2. block address is aligned with smallest size > requested size;
- * 3. block address is not aligned with smallest size >= requested size.
- */
- if(mapped_type >= H5FD_MEM_DEFAULT && (file->maxsize == 0 || size <= file->maxsize)) {
- H5FD_free_t *prev = NULL, *best = NULL;
- H5FD_free_t *cur = file->fl[mapped_type];
- hbool_t found_aligned = FALSE;
- hbool_t need_aligned;
- hsize_t head;
-
- need_aligned = file->alignment > 1 && size >= file->threshold;
-
- while(cur) {
- if(cur->size > file->maxsize)
- file->maxsize = cur->size;
-
- if(need_aligned) {
- if((head = cur->addr % file->alignment) == 0) {
- /*
- * Aligned address
- */
- if(cur->size >= size) {
- if(cur->size == size) {
- /* exact match */
- ret_value = cur->addr;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size,
- file->accum_loc, file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- if(prev)
- prev->next = cur->next;
- else
- file->fl[mapped_type] = cur->next;
-
- H5FL_FREE(H5FD_free_t, cur);
-
- if(size == file->maxsize)
- file->maxsize = 0; /*unknown*/
-
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Exact size match (aligned)\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- HGOTO_DONE(ret_value)
- }
- }
- else
- /* Favor smallest block, that's closest to the beginning of the file */
- if(!best || !found_aligned || cur->size < best->size ||
- (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr))) {
- best = cur;
- found_aligned = TRUE;
- }
- } /* end if */
- } else {
- /*
- * Non-aligned address
- *
- * Check to see if this block is big enough to skip
- * to the next aligned address and is still big
- * enough for the requested size. The extra
- * (cur->size > head) is for preventing unsigned
- * underflow. (This could be improved by checking for
- * an exact match after excluding the head. Such
- * match is as good as the found_aligned case above.)
- */
- head = file->alignment - head; /* actual head size */
-
- if(!found_aligned && cur->size > head && cur->size-head >= size) {
- /* Favor smallest block, that's closest to the beginning of the file */
- if(!best || cur->size < best->size ||
- (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr)))
- best = cur;
- } /* end if */
- } /* end else */
- } else {
- /* !need_aligned */
- if(cur->size >= size) {
- if(cur->size == size) {
- /* exact match */
- ret_value = cur->addr;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size, file->accum_loc,
- file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- if(prev)
- prev->next = cur->next;
- else
- file->fl[mapped_type] = cur->next;
-
- H5FL_FREE(H5FD_free_t, cur);
-
- if(size == file->maxsize)
- file->maxsize = 0; /*unknown*/
-
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Exact size match (unaligned)\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- HGOTO_DONE(ret_value)
- }
- } /* end if */
- else {
- /* Favor smallest block, that's closest to the beginning of the file */
- if(!best || cur->size < best->size ||
- (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr)))
- best = cur;
- } /* end else */
- } /* end if */
- } /* end else */
-
- prev = cur;
- cur = cur->next;
- } /* end while */
-
- /* Couldn't find exact match, use best fitting piece found */
- if(best) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Splitting %Hu byte sized block\n", FUNC, best->size);
-#endif /* H5FD_ALLOC_DEBUG */
- if(best->size == file->maxsize)
- file->maxsize = 0; /*unknown*/
-
- if(!need_aligned || found_aligned) {
- /* free only tail */
- ret_value = best->addr;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size, file->accum_loc,
- file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- best->addr += size; /* Reduce size of block on free list */
- best->size -= size;
- HGOTO_DONE(ret_value)
- }
- } else {
- /*
- * Split into 3 pieces. Keep the the head and tail in the
- * freelist.
- */
- H5FD_free_t *tmp = NULL;
-
- head = file->alignment - (best->addr % file->alignment);
- ret_value = best->addr + head;
-
- /*
- * Make certain we don't hand out a block of raw data
- * from the free list which overlaps with the metadata
- * aggregation buffer (if it's turned on)
- */
- if(type == H5FD_MEM_DRAW &&
- (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
- H5F_addr_overlap(ret_value, size, file->accum_loc, file->accum_size)) {
- ret_value = HADDR_UNDEF;
- } else {
- /* Attempt to allocate memory for temporary node */
- if((tmp = H5FL_MALLOC(H5FD_free_t))==NULL)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "free block allocation failed")
-
- if((tmp->size = (best->size - (head + size)))!=0) {
- tmp->addr = best->addr + (head + size);
- tmp->next = best->next;
- best->next = tmp;
- } else {
- /* no tail piece */
- H5FL_FREE(H5FD_free_t,tmp);
- }
-
- best->size = head;
- HGOTO_DONE(ret_value)
- } /* end else */
- } /* end else */
- } /* end if */
- } /* end if */
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc_from_free_list() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_alloc_metadata
- * Purpose: Try to allocate SIZE bytes of memory from the metadata
- * block if possible.
- *
- * This is split from H5FD_alloc().
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- * Programmer: Bill Wendling
- * 2. December, 2002
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
-{
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI(H5FD_alloc_metadata, HADDR_UNDEF)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* check args */
- assert(file);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- /*
- * If the metadata aggregation feature is enabled for this VFL
- * driver, allocate "generic" metadata space and sub-allocate out of
- * that, if possible. Otherwise just allocate through
- * H5FD_real_alloc()
- */
-
- /*
- * Allocate all types of metadata out of the metadata block
- */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- /*
- * Check if the space requested is larger than the space left in
- * the block
- */
- if(size > file->cur_meta_block_size) {
- haddr_t new_meta; /* Address for new metadata */
-
- /*
- * Check if the block asked for is too large for a metadata
- * block
- */
- if(size >= file->def_meta_block_size) {
- /* Allocate more room for this new block the regular way */
- if(HADDR_UNDEF==(new_meta = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block")
-
- /*
- * Check if the new metadata is at the end of the current
- * metadata block
- */
- if(file->eoma + file->cur_meta_block_size == new_meta) {
- /*
- * Treat the allocation request as if the current
- * metadata block grew by the amount allocated and
- * just update the eoma address. Don't bother
- * updating the cur_meta_block_size since it will
- * just grow and shrink by the same amount.
- */
- ret_value = file->eoma;
- file->eoma += size;
- } else {
- /* Use the new metadata block for the space allocated */
- ret_value = new_meta;
- }
- } else {
- /* Allocate another metadata block */
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Allocating 'metadata' block\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- if(HADDR_UNDEF==(new_meta = H5FD_real_alloc(file, H5FD_MEM_DEFAULT, dxpl_id,
- file->def_meta_block_size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block")
-
- /*
- * Check if the new metadata is at the end of the current
- * metadata block
- */
- if(file->eoma + file->cur_meta_block_size == new_meta) {
- file->cur_meta_block_size += file->def_meta_block_size;
- } else {
- /*
- * Return the unused portion of the metadata block to
- * a free list
- */
- if(file->eoma != 0)
- if(H5FD_free(file, H5FD_MEM_DEFAULT, dxpl_id, file->eoma,
- file->cur_meta_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free metadata block")
-
- /* Point the metadata block at the newly allocated block */
- file->eoma = new_meta;
- file->cur_meta_block_size = file->def_meta_block_size;
- }
-
- /* Allocate space out of the metadata block */
- ret_value = file->eoma;
- file->cur_meta_block_size -= size;
- file->eoma += size;
- }
- } else {
- /* Allocate space out of the metadata block */
- ret_value = file->eoma;
- file->cur_meta_block_size -= size;
- file->eoma += size;
- }
- } else {
- /* Allocate data the regular way */
- if(HADDR_UNDEF==(ret_value = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block")
- }
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc_metadata() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_alloc_raw
- * Purpose: Try to allocate SIZE bytes of raw data.
- *
- * This is split from H5FD_alloc().
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- * Programmer: Bill Wendling
- * 2. December, 2002
- * Modifications:
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
-{
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI(H5FD_alloc_raw, HADDR_UNDEF)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* check args */
- assert(file);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- /*
- * If the "small data" aggregation feature is enabled for this VFL driver,
- * allocate "small data" space and sub-allocate out of that, if
- * possible. Otherwise just allocate through H5FD_real_alloc()
- */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- /*
- * Check if the space requested is larger than the space left in
- * the block
- */
- if(size > file->cur_sdata_block_size) {
- haddr_t new_data; /* Address for new raw data block */
-
- /* Check if the block asked for is too large for the "small data" block */
- if(size >= file->def_sdata_block_size) {
- /* Allocate more room for this new block the regular way */
- if(HADDR_UNDEF==(new_data = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block")
-
- /*
- * Check if the new raw data is at the end of the current
- * "small data" block
- */
- if(file->eosda + file->cur_sdata_block_size == new_data) {
- /*
- * Treat the allocation request as if the current
- * "small data" block grew by the amount allocated
- * and just update the eosda address. Don't bother
- * updating the cur_sdata_block_size since it will
- * just grow and shrink by the same amount.
- */
- ret_value = file->eosda;
- file->eosda += size;
- } else {
- /* Use the new "small data" block for the space allocated */
- ret_value = new_data;
- }
- } else {
- /* Allocate another "small data" block */
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Allocating 'small data' block\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- if(HADDR_UNDEF==(new_data = H5FD_real_alloc(file, type, dxpl_id,
- file->def_sdata_block_size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block")
-
- /*
- * Check if the new raw data is at the end of the current
- * "small data" block
- */
- if(file->eosda + file->cur_sdata_block_size == new_data) {
- file->cur_sdata_block_size += file->def_sdata_block_size;
- } else {
- /*
- * Return the unused portion of the "small data"
- * block to a free list
- */
- if(file->eosda != 0)
- if(H5FD_free(file, H5FD_MEM_DRAW, dxpl_id, file->eosda,
- file->cur_sdata_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free 'small data' block")
-
- /*
- * Point the "small data" block at the newly
- * allocated block
- */
- file->eosda = new_data;
- file->cur_sdata_block_size = file->def_sdata_block_size;
- }
-
- /* Allocate space out of the "small data" block */
- ret_value = file->eosda;
- file->cur_sdata_block_size -= size;
- file->eosda += size;
- }
- } else {
- /* Allocate space out of the "small data" block */
- ret_value = file->eosda;
- file->cur_sdata_block_size -= size;
- file->eosda += size;
- }
- } else {
- /* Allocate data the regular way */
- if(HADDR_UNDEF==(ret_value = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block")
- }
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc_raw() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_real_alloc
- *
- * Purpose: Double private version of H5FDalloc() :-)
- *
- * Return: Success: The format address of the new file memory.
- *
- * Failure: The undefined address HADDR_UNDEF
- *
- * Programmer: Quincey Koziol
- * Friday, August 25, 2000
- *
- * Modifications:
- * Albert Cheng, 2001/05/01
- * Implement the allocation by alignment/threshold.
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
-{
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI_NOINIT(H5FD_real_alloc)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* check args */
- assert(file);
- assert(file->cls);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- /*
- * Dispatch to driver `alloc' callback or extend the end-of-address
- * marker
- */
- if(file->cls->alloc) {
- if((ret_value = (file->cls->alloc)(file, type, dxpl_id, size)) == HADDR_UNDEF)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver allocation request failed")
- } else {
- if((ret_value = H5FD_update_eoa(file, type, dxpl_id, size)) == HADDR_UNDEF)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver eoa update request failed")
- }
-
-done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_real_alloc() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_update_eoa
- * Purpose: Update the EOA field of the file's memory.
- *
- * This was split off from the H5FD_real_alloc function to
- * make life easier for all.
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- * Programmer: Bill Wendling
- * Wednesday, 04. December, 2002
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
-{
- haddr_t eoa, oldeoa = 0;
- hsize_t wasted;
- haddr_t ret_value = HADDR_UNDEF;
-
- FUNC_ENTER_NOAPI_NOINIT(H5FD_update_eoa)
-
- /* check args */
- assert(file);
- assert(file->cls);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
-
- eoa = file->cls->get_eoa(file, type);
-
-#ifdef H5F_DEBUG
- if(file->alignment * file->threshold != 1 && H5DEBUG(F))
- HDfprintf(H5DEBUG(F),
- "%s: alignment=%Hd, threshold=%Hd, size=%Hd, Begin eoa=%a\n",
- FUNC, file->alignment, file->threshold, size, eoa);
-#endif /* H5F_DEBUG */
-
- /* Wasted is 0 if not exceeding threshold or eoa happens to be aligned */
- wasted = (size >= file->threshold) ? (eoa % file->alignment) : 0;
- if(wasted) {
- wasted = file->alignment - wasted; /* actual waste */
- oldeoa = eoa; /* save it for later freeing */
-
- /* Advance eoa to the next alignment by allocating the wasted */
- if(H5F_addr_overflow(eoa, size) || (eoa + wasted) > file->maxaddr)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
-
- eoa += wasted;
-
- if(file->cls->set_eoa(file, type, eoa) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
- } /* end if */
-
- /* allocate the aligned memory */
- if(H5F_addr_overflow(eoa, size) || eoa + size > file->maxaddr)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
-
- ret_value = eoa;
- eoa += size;
-
- if(file->cls->set_eoa(file, type, eoa) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
-
- /* Free the wasted memory */
- if(wasted) {
- if(H5FD_free(file, type, dxpl_id, oldeoa, wasted) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- } /* end if */
-
-#ifdef H5F_DEBUG
- if(file->alignment * file->threshold != 1 && H5DEBUG(F))
- HDfprintf(H5DEBUG(F),
- "%s: ret_value=%a, wasted=%Hd, Ended eoa=%a\n",
- FUNC, ret_value, wasted, eoa);
-#endif /* H5F_DEBUG */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_update_eoa() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FDfree
*
* Purpose: Frees format addresses starting with ADDR and continuing for
@@ -2243,305 +1506,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_free
- *
- * Purpose: Private version of H5FDfree()
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- * Modifications:
- * Bill Wendling, February 20, 2003
- * Added support for Flexible PHDF5. If the process is the
- * Set-Aside-Process, then we execute this function. Clients
- * don't.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
-{
- H5FD_mem_t mapped_type;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_free, FAIL)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* Check args */
- HDassert(file);
- HDassert(file->cls);
- HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
-
- if(!H5F_addr_defined(addr) || addr > file->maxaddr ||
- H5F_addr_overflow(addr, size) || (addr + size) > file->maxaddr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid region")
-
- /* Allow 0-sized free's to occur without penalty */
- if(0 == size)
- HGOTO_DONE(SUCCEED)
-
- /* Map request type to free list */
- if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
-
- /*
- * If the request maps to a free list then add memory to the free list
- * without ever telling the driver that it was freed. Otherwise let the
- * driver deallocate the memory.
- */
- if(mapped_type >= H5FD_MEM_DEFAULT) {
- H5FD_free_t *last; /* Last merged node */
- H5FD_free_t *last_prev = NULL;/* Pointer to node before merged node */
- H5FD_free_t *curr; /* Current free block being inspected */
- H5FD_free_t *prev; /* Previous free block being inspected */
-
- /* Adjust the metadata accumulator to remove the freed block, if it overlaps */
- if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA)
- && H5F_addr_overlap(addr, size, file->accum_loc, file->accum_size)) {
- size_t overlap_size; /* Size of overlap with accumulator */
-
- /* Check for overlapping the beginning of the accumulator */
- if(H5F_addr_le(addr, file->accum_loc)) {
- /* Check for completely overlapping the accumulator */
- if(H5F_addr_ge(addr + size, file->accum_loc + file->accum_size)) {
- /* Reset the entire accumulator */
- file->accum_loc=HADDR_UNDEF;
- file->accum_size=FALSE;
- file->accum_dirty=FALSE;
- } /* end if */
- /* Block to free must end within the accumulator */
- else {
- size_t new_accum_size; /* Size of new accumulator buffer */
-
- /* Calculate the size of the overlap with the accumulator, etc. */
- H5_ASSIGN_OVERFLOW(overlap_size,(addr+size)-file->accum_loc,haddr_t,size_t);
- new_accum_size=file->accum_size-overlap_size;
-
- /* Move the accumulator buffer information to eliminate the freed block */
- HDmemmove(file->meta_accum,file->meta_accum+overlap_size,new_accum_size);
-
- /* Adjust the accumulator information */
- file->accum_loc+=overlap_size;
- file->accum_size=new_accum_size;
- } /* end else */
- } /* end if */
- /* Block to free must start within the accumulator */
- else {
- /* Calculate the size of the overlap with the accumulator */
- H5_ASSIGN_OVERFLOW(overlap_size,(file->accum_loc+file->accum_size)-addr,haddr_t,size_t);
-
- /* Block to free is in the middle of the accumulator */
- if(H5F_addr_lt((addr + size), file->accum_loc + file->accum_size)) {
- haddr_t tail_addr;
- size_t tail_size;
-
- /* Calculate the address & size of the tail to write */
- tail_addr=addr+size;
- H5_ASSIGN_OVERFLOW(tail_size,(file->accum_loc+file->accum_size)-tail_addr,haddr_t,size_t);
-
- /* Write out the part of the accumulator after the block to free */
- /* (Use the driver's write call directly - to avoid looping back and writing to metadata accumulator) */
- if((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc)) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed")
- } /* end if */
-
- /* Adjust the accumulator information */
- file->accum_size=file->accum_size-overlap_size;
- } /* end else */
- } /* end if */
-
- /* Scan through the existing blocks for the mapped type to see if we can extend one */
- curr = file->fl[mapped_type];
- last = prev = NULL;
- while(curr != NULL) {
- /* Check if the block to free adjoins the start of the current block */
- if((addr + size) == curr->addr) {
- /* If we previously found & merged a node, eliminate it from the list & free it */
- if(last != NULL) {
- /* Check if there was a previous block in the list */
- if(last_prev != NULL)
- /* Eliminate the merged block from the list */
- last_prev->next = last->next;
- /* No previous block, this must be the head of the list */
- else
- /* Eliminate the merged block from the list */
- file->fl[mapped_type] = last->next;
-
- /* Check for eliminating the block before the 'current' one */
- if(last == prev)
- prev = last_prev;
-
- /* Free the memory for the merged block */
- H5FL_FREE(H5FD_free_t, last);
- } /* end if */
-
- /* Adjust the address and size of the block found */
- curr->addr = addr;
- curr->size += size;
-
- /* Adjust the information about to memory block to include the merged block */
- addr = curr->addr;
- size = curr->size;
-
- /* Update the information about the merged node */
- last = curr;
- last_prev = prev;
- } /* end if */
- else {
- /* Check if the block to free adjoins the end of the current block */
- if((curr->addr + curr->size) == addr) {
- /* If we previously found & merged a node, eliminate it from the list & free it */
- if(last != NULL) {
- /* Check if there was a previous block in the list */
- if(last_prev != NULL)
- /* Eliminate the merged block from the list */
- last_prev->next = last->next;
- /* No previous block, this must be the head of the list */
- else
- /* Eliminate the merged block from the list */
- file->fl[mapped_type] = last->next;
-
- /* Check for eliminating the block before the 'current' one */
- if(last == prev)
- prev = last_prev;
-
- /* Free the memory for the merged block */
- H5FL_FREE(H5FD_free_t, last);
- } /* end if */
-
- /* Adjust the size of the block found */
- curr->size += size;
-
- /* Adjust the information about to memory block to include the merged block */
- addr = curr->addr;
- size = curr->size;
-
- /* Update the information about the merged node */
- last = curr;
- last_prev = prev;
- } /* end if */
- } /* end else */
-
- /* Advance to next node in list */
- prev = curr;
- curr = curr->next;
- } /* end while */
-
- /* Check if we adjusted an existing block */
- if(last != NULL) {
- /* Move the node found to the front, if it wasn't already there */
- if(last_prev != NULL) {
- last_prev->next = last->next;
- last->next = file->fl[mapped_type];
- file->fl[mapped_type] = last;
- } /* end if */
- } /* end if */
- else {
- /* Allocate a new node to hold the free block's information */
- if(NULL == (last = H5FL_MALLOC(H5FD_free_t)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate node for free space info")
-
- last->addr = addr;
- last->size = size;
- last->next = file->fl[mapped_type];
- file->fl[mapped_type] = last;
- } /* end else */
-
- /* Check if we increased the size of the largest block on the list */
- file->maxsize = MAX(file->maxsize, last->size);
-
- /* Check if this free block adjoins the "metadata aggregator" */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA && file->eoma != 0) {
- hbool_t adjoins = FALSE; /* Whether the block adjoined the metadata aggregator */
-
- /* Does the new block adjoin the end of the metadata aggregator */
- if((file->eoma + file->cur_meta_block_size) == last->addr) {
- last->addr = file->eoma;
- adjoins = TRUE;
- } /* end if */
- /* Does the new block adjoin the beginning of the metadata aggregator */
- else if((last->addr + last->size) == file->eoma)
- adjoins = TRUE;
-
- /* Reset metadata aggregator information, if adjoined */
- if(adjoins) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Adjoined metadata aggregator\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- last->size += file->cur_meta_block_size;
- file->eoma = 0;
- file->cur_meta_block_size = 0;
- } /* end if */
- } /* end if */
-
- /* Check if this free block adjoins the "small data aggregator" */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA && file->eosda != 0) {
- hbool_t adjoins = FALSE; /* Whether the block adjoined the small-data aggregator */
-
- /* Does the new block adjoin the end of the small-data aggregator */
- if((file->eosda + file->cur_sdata_block_size) == last->addr) {
- last->addr = file->eosda;
- adjoins = TRUE;
- } /* end if */
- /* Does the new block adjoin the beginning of the small-data aggregator */
- else if((last->addr + last->size) == file->eosda)
- adjoins = TRUE;
-
- /* Reset small-data aggregator information, if adjoined */
- if(adjoins) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Adjoined small data aggregator\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- last->size += file->cur_sdata_block_size;
- file->eosda = 0;
- file->cur_sdata_block_size = 0;
- } /* end if */
- } /* end if */
-
- /* Check if this free block is at the end of file allocated space.
- * Truncate it if this is true. */
- if(file->cls->get_eoa) {
- haddr_t eoa;
-
- eoa = file->cls->get_eoa(file, type);
- if(eoa == (last->addr + last->size)) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, last->addr);
-#endif /* H5FD_ALLOC_DEBUG */
- if(file->cls->set_eoa(file, type, last->addr) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
-
- /* Remove this free block from the list */
- file->fl[mapped_type] = last->next;
- if(file->maxsize == last->size)
- file->maxsize = 0; /*unknown*/
- H5FL_FREE(H5FD_free_t, last);
- } /* end if */
- } /* end if */
- } else if(file->cls->free) {
- if((file->cls->free)(file, type, dxpl_id, addr, size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed")
- } else {
- /* leak memory */
-#ifdef H5F_DEBUG
-HDfprintf(stderr, "%s: LEAKED MEMORY!!! type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
-#endif /* H5F_DEBUG */
- } /* end else */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_free() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FDrealloc
*
* Purpose: Changes the size of an allocated chunk of memory, possibly
@@ -2584,318 +1548,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_realloc
- *
- * Purpose: Private version of H5FDrealloc()
- *
- * Return: Success: New address of the block of memory, not
- * necessarily the same as the original address.
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Robb Matzke
- * Wednesday, August 4, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size,
- hsize_t new_size)
-{
- haddr_t new_addr=old_addr;
- uint8_t _buf[8192];
- uint8_t *buf=_buf;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_realloc, HADDR_UNDEF)
-
- if(new_size == old_size) {
- /*nothing to do*/
- } else if(0 == old_size) {
- /* allocate memory */
- HDassert(!H5F_addr_defined(old_addr));
- if(HADDR_UNDEF == (new_addr = H5FD_alloc(file, type, dxpl_id, new_size)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
- } else if(0==new_size) {
- /* free memory */
- HDassert(H5F_addr_defined(old_addr));
- if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- new_addr = HADDR_UNDEF;
- } else if(new_size<old_size) {
- /* free the end of the block */
- if(H5FD_free(file, type, dxpl_id, old_addr+old_size, old_size-new_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- } else {
- /* move memory to new location */
- /* Note! This may fail if sizeof(hsize_t)>sizeof(size_t) and the
- * object on disk is too large to read into a memory buffer all at one
- * time. This chunk of code would have to be re-written using a loop
- * to move pieces of the realloced data through a fixed size buffer, etc.
- * -QAK, 6/20/01
- */
- if(HADDR_UNDEF == (new_addr = H5FD_alloc(file, type, dxpl_id, new_size)))
- HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
- H5_CHECK_OVERFLOW(old_size,hsize_t,size_t);
- if(old_size > sizeof(_buf) && NULL == (buf = H5MM_malloc((size_t)old_size))) {
- (void)H5FD_free(file, type, dxpl_id, new_addr, new_size);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed")
- } /* end if */
- if(H5FD_read(file, type, dxpl_id, old_addr, (size_t)old_size, buf) < 0 ||
- H5FD_write(file, type, dxpl_id, new_addr, (size_t)old_size, buf) < 0) {
- (void)H5FD_free(file, type, dxpl_id, new_addr, new_size);
- if(buf != _buf)
- H5MM_xfree(buf);
- HGOTO_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, "unable to move file block")
- } /* end if */
-
- if(buf != _buf)
- H5MM_xfree(buf);
- if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
- } /* end else */
-
- /* Set return value */
- ret_value = new_addr;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_realloc() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_can_extend
- *
- * Purpose: Check if a block in the file can be extended.
- *
- * Return: Success: TRUE(1)/FALSE(0)
- *
- * Failure: FAIL
- *
- * Programmer: Quincey Koziol
- * Friday, June 11, 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-htri_t
-H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
-{
- haddr_t eoa; /* End of address space in the file */
- htri_t ret_value=FALSE; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_can_extend, FAIL)
-
- /* Retrieve the end of the address space */
- if(HADDR_UNDEF==(eoa=H5FD_get_eoa(file, type)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
-
- /* Check if the block is exactly at the end of the file */
- if((addr+size)==eoa)
- HGOTO_DONE(TRUE)
- else {
- H5FD_free_t *curr; /* Current free block being inspected */
- H5FD_mem_t mapped_type; /* Memory type, after mapping */
- haddr_t end; /* End of block in file */
-
- /* Map request type to free list */
- if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
-
- /* Check if block is inside the metadata or small data accumulator */
- if(mapped_type!=H5FD_MEM_DRAW) {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- /* If the metadata block is at the end of the file, and
- * the block to test adjoins the beginning of the metadata
- * block, then it's extendable
- */
- if(file->eoma + file->cur_meta_block_size == eoa &&
- (addr+size)==file->eoma)
- HGOTO_DONE(TRUE)
- } /* end if */
- } /* end if */
- else {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- /* If the small data block is at the end of the file, and
- * the block to test adjoins the beginning of the small data
- * block, then it's extendable
- */
- if(file->eosda + file->cur_sdata_block_size == eoa &&
- (addr+size)==file->eosda)
- HGOTO_DONE(TRUE)
- } /* end if */
- } /* end else */
-
- /* Scan through the existing blocks for the mapped type to see if we can extend one */
- if(mapped_type >= H5FD_MEM_DEFAULT) {
- curr = file->fl[mapped_type];
- end = addr + size;
- while(curr != NULL) {
- if(end == curr->addr) {
- if(extra_requested <= curr->size)
- HGOTO_DONE(TRUE)
- else
- HGOTO_DONE(FALSE)
- } /* end if */
-
- /* Advance to next node in list */
- curr=curr->next;
- } /* end while */
- } /* end if */
- } /* end else */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_can_extend() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_extend
- *
- * Purpose: Extend a block in the file.
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Saturday, June 12, 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
-{
- haddr_t eoa; /* End of address space in the file */
- haddr_t end; /* End of block in file */
- hbool_t update_eoma=FALSE; /* Whether we need to update the eoma */
- hbool_t update_eosda=FALSE; /* Whether we need to update the eosda */
- hbool_t at_end=FALSE; /* Block is at end of file */
- H5FD_mem_t mapped_type; /* Memory type, after mapping */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_extend, FAIL)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n", FUNC, (unsigned)type, addr, size, extra_requested);
-#endif /* H5FD_ALLOC_DEBUG */
-
- /* Retrieve the end of the address space */
- if(HADDR_UNDEF==(eoa=H5FD_get_eoa(file, type)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
-
- /* Map request type to free list */
- if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
- mapped_type = type;
- else
- mapped_type = file->cls->fl_map[type];
-
- /* Compute end of block */
- end = addr + size;
-
- /* Check if the block is exactly at the end of the file */
- if(end == eoa)
- at_end = TRUE;
- else {
- /* (Check if block is inside the metadata or small data accumulator) */
- if(mapped_type!=H5FD_MEM_DRAW) {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA)
- /* If the metadata block is at the end of the file, and
- * the block to test adjoins the beginning of the metadata
- * block, then it's extendable
- */
- if((file->eoma + file->cur_meta_block_size) == eoa &&
- end == file->eoma)
- update_eoma=TRUE;
- } /* end if */
- else {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA)
- /* If the small data block is at the end of the file, and
- * the block to test adjoins the beginning of the small data
- * block, then it's extendable
- */
- if((file->eosda + file->cur_sdata_block_size) == eoa &&
- end == file->eosda)
- update_eosda=TRUE;
- } /* end else */
- } /* end else */
-
- /* Block is at end of file, we are extending the eoma or eosda */
- if(update_eoma || update_eosda || at_end) {
- /* Check for overflowing the file */
- if(H5F_addr_overflow(eoa, extra_requested) || eoa + extra_requested > file->maxaddr)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed")
-
- /* Extend the file */
- eoa += extra_requested;
- if(file->cls->set_eoa(file, type, eoa) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed")
-
- /* Update the metadata and/or small data block */
- assert(!(update_eoma && update_eosda));
- if(update_eoma)
- file->eoma+=extra_requested;
- if(update_eosda)
- file->eosda+=extra_requested;
- } /* end if */
- /* If the block we are extending isn't at the end of the file, find a free block to extend into */
- else {
- H5FD_free_t *curr; /* Current free block being inspected */
- H5FD_free_t *prev; /* Current free block being inspected */
-
- /* Walk through free list, looking for block to merge with */
- curr = file->fl[mapped_type];
- prev = NULL;
- while(curr!=NULL) {
- /* Found block that ajoins end of block to extend */
- if(end == curr->addr) {
- /* Check if free space is large enough */
- if(extra_requested <= curr->size) {
- /* Check for exact match */
- if(extra_requested == curr->size) {
- /* Unlink node from free list */
- if(prev == NULL)
- file->fl[mapped_type] = curr->next;
- else
- prev->next = curr->next;
-
- /* Free the memory for the used block */
- H5FL_FREE(H5FD_free_t, curr);
- } /* end if */
- else {
- curr->addr += extra_requested;
- curr->size -= extra_requested;
- } /* end else */
-
- /* Leave now */
- break;
- } /* end if */
- else
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block")
- } /* end if */
-
- /* Advance to next node in list */
- prev = curr;
- curr = curr->next;
- } /* end while */
-
- /* Couldn't find block to extend */
- if(curr == NULL)
- HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block")
- } /* end else */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_extend() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5FDget_eoa
*
* Purpose: Returns the address of the first byte after the last
@@ -3154,6 +1806,36 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5FD_get_maxaddr
+ *
+ * Purpose: Private version of H5FDget_eof()
+ *
+ * Return: Success: The maximum address allowed in the file.
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, January 3, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5FD_get_maxaddr(const H5FD_t *file)
+{
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_get_maxaddr, HADDR_UNDEF)
+
+ HDassert(file);
+
+ /* Set return value */
+ ret_value = file->maxaddr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_maxaddr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5FDread
*
* Purpose: Reads SIZE bytes from FILE beginning at address ADDR
@@ -3795,22 +2477,20 @@ done:
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* March 27, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_get_fileno, FAIL)
- assert(file);
- assert(filenum);
+ HDassert(file);
+ HDassert(filenum);
/* Retrieve the file's serial number */
- HDmemcpy(filenum,&file->fileno,sizeof(file->fileno));
+ *filenum = file->fileno;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -3883,103 +2563,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_get_vfd_handle() */
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_get_freespace
- *
- * Purpose: Retrieve the amount of free space in a file.
- *
- * Return: Success: Amount of free space in file
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Monday, October 6, 2003
- *
- * Modifications:
- * Raymond Lu
- * 5 January 2007
- * Due to the complexity EOA for Multi driver, this function
- * is made failed for now.
- *
- *-------------------------------------------------------------------------
- */
-hssize_t
-H5FD_get_freespace(const H5FD_t *file)
-{
- H5FD_free_t *free_node; /* Pointer to node on free list */
- H5FD_mem_t type; /* Type of memory */
- haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
- hsize_t ma_size = 0; /* Size of "metadata aggregator" */
- haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
- hsize_t sda_size = 0; /* Size of "small data aggregator" */
- haddr_t eoa = 0; /* End of allocated space in the file */
- hssize_t ret_value = 0; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_get_freespace, FAIL)
-
- /* check args */
- HDassert(file);
- HDassert(file->cls);
-
- /* Multi driver doesn't support this function because of the complexity.
- * It doesn't have eoa for the whole file. */
- if(file->driver_id == H5FD_MULTI)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "Multi driver doesn't support this function")
-
- /* Retrieve the 'eoa' for the file */
- eoa = file->cls->get_eoa(file, H5FD_MEM_DEFAULT);
-
- /* Check for aggregating metadata allocations */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- ma_addr = file->eoma;
- ma_size = file->cur_meta_block_size;
- } /* end if */
-
- /* Check for aggregating small data allocations */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- sda_addr = file->eosda;
- sda_size = file->cur_sdata_block_size;
- } /* end if */
-
- /* Iterate over all the types of memory, to retrieve amount of free space for each */
- for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,type)) {
- /* Iterate through the free list, accumulating the amount of free space for this type */
- free_node = file->fl[type];
- while(free_node) {
- /* Check for current node adjoining the metadata & small data aggregators */
- if(H5F_addr_eq(free_node->addr + free_node->size, ma_addr)) {
- ma_addr -= free_node->size;
- ma_size += free_node->size;
- } else if(H5F_addr_eq(free_node->addr + free_node->size, sda_addr)) {
- sda_addr -= free_node->size;
- sda_size += free_node->size;
- } else if(H5F_addr_eq(ma_addr + ma_size, free_node->addr))
- ma_size += free_node->size;
- else if(H5F_addr_eq(sda_addr + sda_size, free_node->addr))
- sda_size += free_node->size;
- else
- ret_value += (hssize_t)free_node->size;
- free_node = free_node->next;
- } /* end while */
- } /* end for */
-
- /* Check for aggregating metadata allocations */
- if(H5F_addr_defined(ma_addr)) {
- /* Add in the reserved space for metadata to the available free space */
- /* (if it's not at the tail of the file) */
- if(H5F_addr_ne(ma_addr + ma_size, eoa))
- ret_value += ma_size;
- } /* end if */
-
- /* Check for aggregating small data allocations */
- if(H5F_addr_defined(sda_addr)) {
- /* Add in the reserved space for metadata to the available free space */
- /* (if it's not at the tail of the file) */
- if(H5F_addr_ne(sda_addr + sda_size, eoa))
- ret_value += sda_size;
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_get_freespace() */
-
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index 3109e09..df07c0a 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -234,7 +234,11 @@ static const H5FD_class_t H5FD_log_g = {
H5FD_log_flush, /*flush */
NULL, /*lock */
NULL, /*unlock */
+#ifdef OLD_WAY
H5FD_FLMAP_NOLIST /*fl_map */
+#else /* OLD_WAY */
+ H5FD_FLMAP_SINGLE /*fl_map */
+#endif /* OLD_WAY */
};
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 5d5f092..c8087bb 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -322,13 +322,13 @@ H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
FUNC_ENTER_API(H5Pset_fapl_mpio, FAIL)
H5TRACE3("e", "iMcMi", fapl_id, comm, info);
- if(fapl_id==H5P_DEFAULT)
+ if(fapl_id == H5P_DEFAULT)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access list")
- if (MPI_COMM_NULL == comm)
+ if(MPI_COMM_NULL == comm)
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a valid communicator")
/* Initialize driver specific properties */
@@ -393,11 +393,11 @@ H5Pget_fapl_mpio(hid_t fapl_id, MPI_Comm *comm/*out*/, MPI_Info *info/*out*/)
FUNC_ENTER_API(H5Pget_fapl_mpio, FAIL)
H5TRACE3("e", "ixx", fapl_id, comm, info);
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access list")
- if (H5FD_MPIO!=H5P_get_driver(plist))
+ if(H5FD_MPIO != H5P_get_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
- if (NULL==(fa=H5P_get_driver_info(plist)))
+ if(NULL == (fa = (H5FD_mpio_fapl_t *)H5P_get_driver_info(plist)))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
/* Store the duplicated communicator in a temporary variable for error */
@@ -471,9 +471,9 @@ H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
- if (H5FD_MPIO_INDEPENDENT!=xfer_mode && H5FD_MPIO_COLLECTIVE!=xfer_mode)
+ if(H5FD_MPIO_INDEPENDENT != xfer_mode && H5FD_MPIO_COLLECTIVE != xfer_mode)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "incorrect xfer_mode")
/* Set the transfer mode */
@@ -517,9 +517,9 @@ H5Pget_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t *xfer_mode/*out*/)
FUNC_ENTER_API(H5Pget_dxpl_mpio, FAIL)
H5TRACE2("e", "ix", dxpl_id, xfer_mode);
- if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
- if (H5FD_MPIO!=H5P_get_driver(plist))
+ if(H5FD_MPIO != H5P_get_driver(plist))
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
/* Get the transfer mode */
@@ -563,13 +563,12 @@ H5Pset_dxpl_mpio_collective_opt(hid_t dxpl_id, H5FD_mpio_collective_opt_t opt_mo
FUNC_ENTER_API(H5Pset_dxpl_mpio_collective_opt, FAIL)
H5TRACE2("e", "iDc", dxpl_id, opt_mode);
-/* H5TRACE2("e","iDt",dxpl_id,xfer_mode);*/
- if(dxpl_id==H5P_DEFAULT)
+ if(dxpl_id == H5P_DEFAULT)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -616,13 +615,12 @@ H5Pset_dxpl_mpio_chunk_opt(hid_t dxpl_id, H5FD_mpio_chunk_opt_t opt_mode)
FUNC_ENTER_API(H5Pset_dxpl_mpio_chunk_opt, FAIL)
H5TRACE2("e", "iDh", dxpl_id, opt_mode);
-/* H5TRACE2("e","iDt",dxpl_id,xfer_mode);*/
- if(dxpl_id==H5P_DEFAULT)
+ if(dxpl_id == H5P_DEFAULT)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -666,11 +664,11 @@ H5Pset_dxpl_mpio_chunk_opt_num(hid_t dxpl_id, unsigned num_chunk_per_proc)
FUNC_ENTER_API(H5Pset_dxpl_mpio_chunk_opt_num, FAIL)
H5TRACE2("e", "iIu", dxpl_id, num_chunk_per_proc);
- if(dxpl_id==H5P_DEFAULT)
+ if(dxpl_id == H5P_DEFAULT)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -713,11 +711,11 @@ H5Pset_dxpl_mpio_chunk_opt_ratio(hid_t dxpl_id, unsigned percent_num_proc_per_ch
FUNC_ENTER_API(H5Pset_dxpl_mpio_chunk_opt_ratio, FAIL)
H5TRACE2("e", "iIu", dxpl_id, percent_num_proc_per_chunk);
- if(dxpl_id==H5P_DEFAULT)
+ if(dxpl_id == H5P_DEFAULT)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
/* Check arguments */
- if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
/* Set the transfer mode */
@@ -761,19 +759,18 @@ H5FD_mpio_fapl_get(H5FD_t *_file)
FUNC_ENTER_NOAPI(H5FD_mpio_fapl_get, NULL)
- assert(file);
- assert(H5FD_MPIO==file->pub.driver_id);
+ HDassert(file);
+ HDassert(H5FD_MPIO == file->pub.driver_id);
- if (NULL==(fa=H5MM_calloc(sizeof(H5FD_mpio_fapl_t))))
+ if(NULL == (fa = (H5FD_mpio_fapl_t *)H5MM_calloc(sizeof(H5FD_mpio_fapl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Duplicate communicator and Info object. */
- if (FAIL==H5FD_mpi_comm_info_dup(file->comm, file->info,
- &fa->comm, &fa->info))
+ if(FAIL == H5FD_mpi_comm_info_dup(file->comm, file->info, &fa->comm, &fa->info))
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "Communicator/Info duplicate failed")
/* Set return value */
- ret_value=fa;
+ ret_value = fa;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -809,15 +806,14 @@ if (H5FD_mpio_Debug[(int)'t'])
fprintf(stderr, "enter H5FD_mpio_fapl_copy\n");
#endif
- if (NULL==(new_fa=H5MM_malloc(sizeof(H5FD_mpio_fapl_t))))
+ if(NULL == (new_fa = (H5FD_mpio_fapl_t *)H5MM_malloc(sizeof(H5FD_mpio_fapl_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Copy the general information */
HDmemcpy(new_fa, old_fa, sizeof(H5FD_mpio_fapl_t));
/* Duplicate communicator and Info object. */
- if (FAIL==H5FD_mpi_comm_info_dup(old_fa->comm, old_fa->info,
- &new_fa->comm, &new_fa->info))
+ if(FAIL == H5FD_mpi_comm_info_dup(old_fa->comm, old_fa->info, &new_fa->comm, &new_fa->info))
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "Communicator/Info duplicate failed")
ret_value = new_fa;
@@ -956,14 +952,14 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
#endif
/* Obtain a pointer to mpio-specific file access properties */
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = (H5P_genplist_t *)H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
- if (H5P_FILE_ACCESS_DEFAULT==fapl_id || H5FD_MPIO!=H5P_get_driver(plist)) {
+ if(H5P_FILE_ACCESS_DEFAULT == fapl_id || H5FD_MPIO != H5P_get_driver(plist)) {
_fa.comm = MPI_COMM_SELF; /*default*/
_fa.info = MPI_INFO_NULL; /*default*/
fa = &_fa;
} else {
- fa = H5P_get_driver_info(plist);
+ fa = (const H5FD_mpio_fapl_t *)H5P_get_driver_info(plist);
assert(fa);
}
@@ -998,7 +994,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
#endif
/*OKAY: CAST DISCARDS CONST*/
- if (MPI_SUCCESS != (mpi_code=MPI_File_open(comm_dup, (char*)name, mpi_amode, info_dup, &fh)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_open(comm_dup, (char*)name, mpi_amode, info_dup, &fh)))
HMPI_GOTO_ERROR(NULL, "MPI_File_open failed", mpi_code)
file_opened=1;
@@ -1009,7 +1005,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
HMPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code)
/* Build the return value and initialize it */
- if (NULL==(file=H5MM_calloc(sizeof(H5FD_mpio_t))))
+ if(NULL == (file = (H5FD_mpio_t *)H5MM_calloc(sizeof(H5FD_mpio_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
file->f = fh;
file->comm = comm_dup;
@@ -1034,7 +1030,7 @@ H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
} /* end if */
/* Broadcast file size */
- if (MPI_SUCCESS != (mpi_code=MPI_Bcast(&size, sizeof(MPI_Offset), MPI_BYTE, 0, comm_dup)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Bcast(&size, (int)sizeof(MPI_Offset), MPI_BYTE, 0, comm_dup)))
HMPI_GOTO_ERROR(NULL, "MPI_Bcast failed", mpi_code)
/* Determine if the file should be truncated */
@@ -1454,9 +1450,9 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add
H5FD_mpio_xfer_t xfer_mode; /* I/O tranfer mode */
/* Obtain the data transfer properties */
- if(NULL == (plist = H5I_object(dxpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- xfer_mode=(H5FD_mpio_xfer_t)H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_MODE_NAME);
+ xfer_mode = (H5FD_mpio_xfer_t)H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_MODE_NAME);
/*
* Set up for a fancy xfer using complex types, or single byte block. We
@@ -1499,10 +1495,10 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add
fprintf(stdout, "H5FD_mpio_read: using MPIO collective mode\n");
#endif
/* Peek the collective_opt property to check whether the application wants to do IO individually. */
- coll_opt_mode=(H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist,H5D_XFER_MPIO_COLLECTIVE_OPT_NAME);
+ coll_opt_mode = (H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME);
/* Peek the xfer_opt_mode property to check whether the application wants to do IO individually. */
- xfer_opt_mode=(H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist,H5D_XFER_IO_XFER_OPT_MODE_NAME);
+ xfer_opt_mode = (H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_OPT_MODE_NAME);
if(coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO && xfer_opt_mode == H5FD_MPIO_COLLECTIVE_IO) {
#ifdef H5FDmpio_DEBUG
@@ -1528,10 +1524,10 @@ H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t dxpl_id, haddr_t add
* Reset the file view when we used MPI derived types
*/
/*OKAY: CAST DISCARDS CONST QUALIFIER*/
- if (MPI_SUCCESS != (mpi_code=MPI_File_set_view(file->f, 0, MPI_BYTE, MPI_BYTE, H5FD_mpi_native_g, file->info)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, H5FD_mpi_native_g, file->info)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code)
} else {
- if (MPI_SUCCESS!= (mpi_code=MPI_File_read_at(file->f, mpi_off, buf, size_i, buf_type, &mpi_stat)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_read_at(file->f, mpi_off, buf, size_i, buf_type, &mpi_stat)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at failed", mpi_code)
}
@@ -1738,7 +1734,7 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
#endif
/* Obtain the data transfer properties */
- if(NULL == (plist = H5I_object(dxpl_id)))
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
if(type==H5FD_MEM_DRAW) {
@@ -1830,15 +1826,12 @@ H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
fprintf(stdout, "H5FD_mpio_write: using MPIO collective mode\n");
#endif
/* Peek the collective_opt property to check whether the application wants to do IO individually. */
- coll_opt_mode=(H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist,H5D_XFER_MPIO_COLLECTIVE_OPT_NAME);
+ coll_opt_mode = (H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist,H5D_XFER_MPIO_COLLECTIVE_OPT_NAME);
/* Peek the xfer_opt_mode property to check whether the application wants to do IO individually. */
- xfer_opt_mode=(H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist,H5D_XFER_IO_XFER_OPT_MODE_NAME);
-
-
+ xfer_opt_mode = (H5FD_mpio_collective_opt_t)H5P_peek_unsigned(plist,H5D_XFER_IO_XFER_OPT_MODE_NAME);
/*OKAY: CAST DISCARDS CONST QUALIFIER*/
-
if(coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO && xfer_opt_mode == H5FD_MPIO_COLLECTIVE_IO ) {
#ifdef H5FDmpio_DEBUG
if (H5FD_mpio_Debug[(int)'t'])
@@ -1865,11 +1858,11 @@ if (MPI_SUCCESS != (mpi_code=MPI_File_write_at_all(file->f, mpi_off, (void*)buf,
* Reset the file view when we used MPI derived types
*/
/*OKAY: CAST DISCARDS CONST QUALIFIER*/
- if (MPI_SUCCESS != (mpi_code=MPI_File_set_view(file->f, 0, MPI_BYTE, MPI_BYTE, H5FD_mpi_native_g, file->info)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, H5FD_mpi_native_g, file->info)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code)
} else {
/*OKAY: CAST DISCARDS CONST QUALIFIER*/
- if (MPI_SUCCESS != (mpi_code=MPI_File_write_at(file->f, mpi_off, (void*)buf, size_i, buf_type, &mpi_stat)))
+ if(MPI_SUCCESS != (mpi_code = MPI_File_write_at(file->f, mpi_off, (void*)buf, size_i, buf_type, &mpi_stat)))
HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at failed", mpi_code)
}
@@ -1908,8 +1901,8 @@ done:
/* if only one process writes, need to broadcast the ret_value to
* other processes
*/
- if (type!=H5FD_MEM_DRAW) {
- if (MPI_SUCCESS != (mpi_code=MPI_Bcast(&ret_value, sizeof(ret_value), MPI_BYTE, H5_PAR_META_WRITE, file->comm)))
+ if(type != H5FD_MEM_DRAW) {
+ if(MPI_SUCCESS != (mpi_code = MPI_Bcast(&ret_value, (int)sizeof(ret_value), MPI_BYTE, H5_PAR_META_WRITE, file->comm)))
HMPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code)
} /* end if */
#endif /* JRM */
diff --git a/src/H5FDpkg.h b/src/H5FDpkg.h
new file mode 100644
index 0000000..700ec1d
--- /dev/null
+++ b/src/H5FDpkg.h
@@ -0,0 +1,67 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * Thursday, January 3, 2008
+ *
+ * Purpose: This file contains declarations which are visible only within
+ * the H5FD package. Source files outside the H5FD package should
+ * include H5FDprivate.h instead.
+ */
+#ifndef H5FD_PACKAGE
+#error "Do not include this file outside the H5FD package!"
+#endif
+
+#ifndef _H5FDpkg_H
+#define _H5FDpkg_H
+
+/* Get package's private header */
+#include "H5FDprivate.h" /* File drivers */
+
+/* Other private headers needed by this file */
+#include "H5FLprivate.h" /* Free lists */
+
+/**************************/
+/* Package Private Macros */
+/**************************/
+
+
+/****************************/
+/* Package Private Typedefs */
+/****************************/
+
+
+/*****************************/
+/* Package Private Variables */
+/*****************************/
+
+/* Declare a PQ free list to manage the metadata accumulator buffer */
+H5FL_BLK_EXTERN(meta_accum);
+
+
+/******************************/
+/* Package Private Prototypes */
+/******************************/
+H5_DLL herr_t H5FD_init(void);
+H5_DLL herr_t H5FD_free_freelist(H5FD_t *file);
+
+
+/* Testing routines */
+#ifdef H5FD_TESTING
+#endif /* H5FD_TESTING */
+
+#endif /* _H5FDpkg_H */
+
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 202b7d1..4c8c28e 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -62,6 +62,7 @@ H5_DLL haddr_t H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_
H5_DLL haddr_t H5FD_get_eoa(const H5FD_t *file, H5FD_mem_t type);
H5_DLL herr_t H5FD_set_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t addr);
H5_DLL haddr_t H5FD_get_eof(const H5FD_t *file);
+H5_DLL haddr_t H5FD_get_maxaddr(const H5FD_t *file);
H5_DLL herr_t H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
void *buf/*out*/);
H5_DLL herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
@@ -74,5 +75,7 @@ H5_DLL htri_t H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr,
hsize_t size, hsize_t extra_requested);
H5_DLL herr_t H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr,
hsize_t size, hsize_t extra_requested);
+H5_DLL herr_t H5FD_aggr_reset(H5FD_t *file, H5FD_blk_aggr_t *aggr, hid_t dxpl_id);
#endif /* !_H5FDprivate_H */
+
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index b68f141..839c8a3 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -229,6 +229,15 @@ typedef struct H5FD_free_t {
struct H5FD_free_t *next;
} H5FD_free_t;
+/* Structure for metadata & "small [raw] data" block aggregation fields */
+typedef struct H5FD_blk_aggr_t {
+ unsigned long feature_flag; /* Feature flag type */
+ hsize_t alloc_size; /* Size for allocating new blocks */
+ hsize_t tot_size; /* Total amount of bytes aggregated into block */
+ hsize_t size; /* Current size of block left */
+ haddr_t addr; /* Location of block left */
+} H5FD_blk_aggr_t;
+
/*
* The main datatype for each driver. Public fields common to all drivers
* are declared here and the driver appends private fields in memory.
@@ -241,27 +250,11 @@ struct H5FD_t {
hsize_t threshold; /* Threshold for alignment */
hsize_t alignment; /* Allocation alignment */
- /* Metadata aggregation fields */
- hsize_t def_meta_block_size; /* Metadata allocation
- * block size (if
- * aggregating metadata) */
- hsize_t cur_meta_block_size; /* Current size of metadata
- * allocation region left */
- haddr_t eoma; /* End of metadata
- * allocated region */
- /* (ie. beginning of space available) */
-
- /* "Small data" aggregation fields */
- hsize_t def_sdata_block_size; /* "Small data"
- * allocation block size
- * (if aggregating "small
- * data") */
- hsize_t cur_sdata_block_size; /* Current size of "small
- * data" allocation
- * region left */
- haddr_t eosda; /* End of "small data"
- * allocated region */
- /* (ie. beginning of space available) */
+ /* Block aggregation info */
+ H5FD_blk_aggr_t meta_aggr; /* Metadata aggregation info */
+ /* (if aggregating metadata allocations) */
+ H5FD_blk_aggr_t sdata_aggr; /* "Small data" aggregation info */
+ /* (if aggregating "small data" allocations) */
/* Metadata accumulator fields */
unsigned char *meta_accum; /* Buffer to hold the accumulated metadata */
@@ -311,3 +304,4 @@ H5_DLL herr_t H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing);
}
#endif
#endif
+
diff --git a/src/H5FDspace.c b/src/H5FDspace.c
new file mode 100644
index 0000000..7bd72cc
--- /dev/null
+++ b/src/H5FDspace.c
@@ -0,0 +1,1738 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5FDspace.c
+ * Jan 3 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Space allocation routines for the file.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5FD_PACKAGE /*suppress error about including H5FDpkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5FD_space_init_interface
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File access */
+#include "H5FDpkg.h" /* File Drivers */
+#include "H5FDmulti.h" /* Usage-partitioned file family */
+#include "H5MMprivate.h" /* Memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Define this to display information about file allocations */
+/* #define H5FD_ALLOC_DEBUG */
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+static haddr_t H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type,
+ hsize_t size);
+static haddr_t H5FD_aggr_alloc(H5FD_t *file, H5FD_blk_aggr_t *aggr,
+ H5FD_blk_aggr_t *other_aggr, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
+static herr_t H5FD_aggr_adjoin(const H5FD_t *file, H5FD_blk_aggr_t *aggr,
+ H5FD_free_t *last);
+static htri_t H5FD_aggr_can_extend(const H5FD_t *file, const H5FD_blk_aggr_t *aggr,
+ haddr_t eoa, haddr_t end);
+static herr_t H5FD_aggr_shift(H5FD_blk_aggr_t *aggr, hsize_t extra);
+static herr_t H5FD_aggr_query(const H5FD_t *file, const H5FD_blk_aggr_t *aggr,
+ haddr_t *addr, hsize_t *size);
+static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
+static haddr_t H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5FD_free_t struct */
+H5FL_DEFINE(H5FD_free_t);
+
+/* Declare a PQ free list to manage the metadata accumulator buffer */
+H5FL_BLK_DEFINE(meta_accum);
+
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5FD_space_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5FD_space_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines. (Just calls
+ H5FD_init_iterface currently).
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5FD_space_init_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_space_init_interface)
+
+ FUNC_LEAVE_NOAPI(H5FD_init())
+} /* H5FD_space_init_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_free_freelist
+ *
+ * Purpose: Split off from H5FD_close(). Free the elements in the
+ * free list for this file driver.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Never fails
+ *
+ * Programmer: Bill Wendling
+ * 17. February 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_free_freelist(H5FD_t *file)
+{
+ H5FD_mem_t i;
+#ifdef H5FD_ALLOC_DEBUG
+ unsigned nblocks = 0;
+ hsize_t nbytes = 0;
+#endif /* H5FD_ALLOC_DEBUG */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_free_freelist)
+
+ /* check args */
+ HDassert(file && file->cls);
+
+ /*
+ * Free all free-lists, leaking any memory thus described. Also leaks
+ * file space allocated but not used when metadata aggregation is
+ * turned on.
+ */
+ for(i = H5FD_MEM_DEFAULT; i < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, i)) {
+ H5FD_free_t *cur, *next;
+
+ for( cur = file->fl[i]; cur; cur = next) {
+#ifdef H5FD_ALLOC_DEBUG
+ ++nblocks;
+ nbytes += cur->size;
+#endif /* H5FD_ALLOC_DEBUG */
+ next = cur->next;
+ H5FL_FREE(H5FD_free_t, cur);
+ } /* end for */
+
+ file->fl[i] = NULL;
+ } /* end for */
+
+#ifdef H5FD_ALLOC_DEBUG
+ if(nblocks)
+ HDfprintf(stderr, "%s: leaked %Hu bytes of file memory in %u blocks\n",
+ "H5FD_free_freelist", nbytes, nblocks);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ /* Check if we need to reset the metadata accumulator information */
+ if(file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) {
+ /* Free the buffer */
+ if(file->meta_accum)
+ file->meta_accum = H5FL_BLK_FREE(meta_accum, file->meta_accum);
+
+ /* Reset the buffer sizes & location */
+ file->accum_buf_size = file->accum_size = 0;
+ file->accum_loc = HADDR_UNDEF;
+ file->accum_dirty = 0;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_free_freelist() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_alloc
+ *
+ * Purpose: Private version of H5FDalloc().
+ *
+ * Return: Success: The format address of the new file memory.
+ * Failure: The undefined address HADDR_UNDEF
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+{
+ haddr_t ret_value = HADDR_UNDEF;
+
+ FUNC_ENTER_NOAPI(H5FD_alloc, HADDR_UNDEF)
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ /* check args */
+ assert(file);
+ assert(file->cls);
+ assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ assert(size > 0);
+
+#ifdef H5F_DEBUG
+ if(H5DEBUG(F))
+ HDfprintf(H5DEBUG(F), "%s: alignment=%Hd, threshold=%Hd, size=%Hd\n",
+ FUNC, file->alignment, file->threshold, size);
+#endif /* H5F_DEBUG */
+
+ /* Try to allocate from the free list first */
+ if((ret_value = H5FD_alloc_from_free_list(file, type, size)) != HADDR_UNDEF)
+ HGOTO_DONE(ret_value)
+
+#ifdef H5F_DEBUG
+ if(H5DEBUG(F))
+ HDfprintf(H5DEBUG(F), "%s: Could not allocate from freelists\n", FUNC);
+#endif /* H5F_DEBUG */
+
+ if(type != H5FD_MEM_DRAW) {
+ /* Handle metadata differently from "raw" data */
+ if(HADDR_UNDEF == (ret_value = H5FD_aggr_alloc(file, &(file->meta_aggr), &(file->sdata_aggr), type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata")
+ } /* end if */
+ else {
+ /* Allocate "raw" data */
+ if(HADDR_UNDEF == (ret_value = H5FD_aggr_alloc(file, &(file->sdata_aggr), &(file->meta_aggr), type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data")
+ } /* end else */
+
+done:
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
+#endif /* H5FD_ALLOC_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_alloc_from_free_list
+ *
+ * Purpose: Try to allocate SIZE bytes of memory from the free list
+ * if possible.
+ *
+ * This is split from H5FD_alloc().
+ *
+ * Return: Success: The format address of the new file memory.
+ * Failure: The undefined address HADDR_UNDEF
+ *
+ * Programmer: Bill Wendling
+ * 02. December, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type, hsize_t size)
+{
+ H5FD_mem_t mapped_type;
+ haddr_t ret_value = HADDR_UNDEF;
+
+ FUNC_ENTER_NOAPI(H5FD_alloc_from_free_list, HADDR_UNDEF)
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ assert(file);
+ assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ assert(size > 0);
+
+ /* Map the allocation request to a free list */
+ if(H5FD_MEM_DEFAULT == file->cls->fl_map[type])
+ mapped_type = type;
+ else
+ mapped_type = file->cls->fl_map[type];
+
+ /*
+ * Try to satisfy the request from the free list. Only perform the
+ * search if the free list has the potential of satisfying the
+ * request.
+ *
+ * Here, aligned requests are requests that are >= threshold and
+ * alignment > 1.
+ *
+ * For non-aligned request, first try to find an exact match,
+ * otherwise use the best match which is the smallest size that meets
+ * the requested size.
+ *
+ * For aligned address request, find a block in the following order
+ * of preferences:
+ *
+ * 1. block address is aligned and exact match in size;
+ * 2. block address is aligned with smallest size > requested size;
+ * 3. block address is not aligned with smallest size >= requested size.
+ */
+ if(mapped_type >= H5FD_MEM_DEFAULT && (file->maxsize == 0 || size <= file->maxsize)) {
+ H5FD_free_t *prev = NULL, *best = NULL;
+ H5FD_free_t *cur = file->fl[mapped_type];
+ hbool_t found_aligned = FALSE;
+ hbool_t need_aligned;
+ hsize_t head;
+
+ need_aligned = file->alignment > 1 && size >= file->threshold;
+
+ while(cur) {
+ if(cur->size > file->maxsize)
+ file->maxsize = cur->size;
+
+ if(need_aligned) {
+ if((head = cur->addr % file->alignment) == 0) {
+ /*
+ * Aligned address
+ */
+ if(cur->size >= size) {
+ if(cur->size == size) {
+ /* exact match */
+ ret_value = cur->addr;
+
+ /*
+ * Make certain we don't hand out a block of raw data
+ * from the free list which overlaps with the metadata
+ * aggregation buffer (if it's turned on)
+ */
+ if(type == H5FD_MEM_DRAW &&
+ (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
+ H5F_addr_overlap(ret_value, size,
+ file->accum_loc, file->accum_size)) {
+ ret_value = HADDR_UNDEF;
+ } else {
+ if(prev)
+ prev->next = cur->next;
+ else
+ file->fl[mapped_type] = cur->next;
+
+ H5FL_FREE(H5FD_free_t, cur);
+
+ if(size == file->maxsize)
+ file->maxsize = 0; /*unknown*/
+
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Exact size match (aligned)\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ HGOTO_DONE(ret_value)
+ }
+ }
+ else
+ /* Favor smallest block, that's closest to the beginning of the file */
+ if(!best || !found_aligned || cur->size < best->size ||
+ (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr))) {
+ best = cur;
+ found_aligned = TRUE;
+ }
+ } /* end if */
+ } else {
+ /*
+ * Non-aligned address
+ *
+ * Check to see if this block is big enough to skip
+ * to the next aligned address and is still big
+ * enough for the requested size. The extra
+ * (cur->size > head) is for preventing unsigned
+ * underflow. (This could be improved by checking for
+ * an exact match after excluding the head. Such
+ * match is as good as the found_aligned case above.)
+ */
+ head = file->alignment - head; /* actual head size */
+
+ if(!found_aligned && cur->size > head && cur->size-head >= size) {
+ /* Favor smallest block, that's closest to the beginning of the file */
+ if(!best || cur->size < best->size ||
+ (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr)))
+ best = cur;
+ } /* end if */
+ } /* end else */
+ } else {
+ /* !need_aligned */
+ if(cur->size >= size) {
+ if(cur->size == size) {
+ /* exact match */
+ ret_value = cur->addr;
+
+ /*
+ * Make certain we don't hand out a block of raw data
+ * from the free list which overlaps with the metadata
+ * aggregation buffer (if it's turned on)
+ */
+ if(type == H5FD_MEM_DRAW &&
+ (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
+ H5F_addr_overlap(ret_value, size, file->accum_loc,
+ file->accum_size)) {
+ ret_value = HADDR_UNDEF;
+ } else {
+ if(prev)
+ prev->next = cur->next;
+ else
+ file->fl[mapped_type] = cur->next;
+
+ H5FL_FREE(H5FD_free_t, cur);
+
+ if(size == file->maxsize)
+ file->maxsize = 0; /*unknown*/
+
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Exact size match (unaligned)\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ HGOTO_DONE(ret_value)
+ }
+ } /* end if */
+ else {
+ /* Favor smallest block, that's closest to the beginning of the file */
+ if(!best || cur->size < best->size ||
+ (cur->size == best->size && H5F_addr_lt(cur->addr, best->addr)))
+ best = cur;
+ } /* end else */
+ } /* end if */
+ } /* end else */
+
+ prev = cur;
+ cur = cur->next;
+ } /* end while */
+
+ /* Couldn't find exact match, use best fitting piece found */
+ if(best) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Splitting %Hu byte sized block\n", FUNC, best->size);
+#endif /* H5FD_ALLOC_DEBUG */
+ if(best->size == file->maxsize)
+ file->maxsize = 0; /*unknown*/
+
+ if(!need_aligned || found_aligned) {
+ /* free only tail */
+ ret_value = best->addr;
+
+ /*
+ * Make certain we don't hand out a block of raw data
+ * from the free list which overlaps with the metadata
+ * aggregation buffer (if it's turned on)
+ */
+ if(type == H5FD_MEM_DRAW &&
+ (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
+ H5F_addr_overlap(ret_value, size, file->accum_loc,
+ file->accum_size)) {
+ ret_value = HADDR_UNDEF;
+ } else {
+ best->addr += size; /* Reduce size of block on free list */
+ best->size -= size;
+ HGOTO_DONE(ret_value)
+ }
+ } else {
+ /*
+ * Split into 3 pieces. Keep the the head and tail in the
+ * freelist.
+ */
+ H5FD_free_t *tmp = NULL;
+
+ head = file->alignment - (best->addr % file->alignment);
+ ret_value = best->addr + head;
+
+ /*
+ * Make certain we don't hand out a block of raw data
+ * from the free list which overlaps with the metadata
+ * aggregation buffer (if it's turned on)
+ */
+ if(type == H5FD_MEM_DRAW &&
+ (file->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) &&
+ H5F_addr_overlap(ret_value, size, file->accum_loc, file->accum_size)) {
+ ret_value = HADDR_UNDEF;
+ } else {
+ /* Attempt to allocate memory for temporary node */
+ if((tmp = H5FL_MALLOC(H5FD_free_t))==NULL)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "free block allocation failed")
+
+ if((tmp->size = (best->size - (head + size)))!=0) {
+ tmp->addr = best->addr + (head + size);
+ tmp->next = best->next;
+ best->next = tmp;
+ } else {
+ /* no tail piece */
+ H5FL_FREE(H5FD_free_t,tmp);
+ }
+
+ best->size = head;
+ HGOTO_DONE(ret_value)
+ } /* end else */
+ } /* end else */
+ } /* end if */
+ } /* end if */
+
+done:
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
+#endif /* H5FD_ALLOC_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_alloc_from_free_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_alloc
+ *
+ * Purpose: Try to allocate SIZE bytes of memory from an aggregator
+ * block if possible.
+ *
+ * This is split from H5FD_alloc().
+ *
+ * Return: Success: The format address of the new file memory.
+ * Failure: The undefined address HADDR_UNDEF
+ *
+ * Programmer: Bill Wendling
+ * 2. December, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_aggr_alloc(H5FD_t *file, H5FD_blk_aggr_t *aggr, H5FD_blk_aggr_t *other_aggr,
+ H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+{
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FD_aggr_alloc)
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ /* check args */
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(other_aggr);
+ HDassert(other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(other_aggr->feature_flag != aggr->feature_flag);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(size > 0);
+
+ /*
+ * If the aggregation feature is enabled for this VFL
+ * driver, allocate "generic" space and sub-allocate out of
+ * that, if possible. Otherwise just allocate through
+ * H5FD_real_alloc()
+ */
+ if(file->feature_flags & aggr->feature_flag) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_size, aggr->size);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Check if the space requested is larger than the space left in the block */
+ if(size > aggr->size) {
+ haddr_t new_space; /* Address for newly allocated space */
+
+ /* Check if the block asked for is too large for 'normal' aggregator block */
+ if(size >= aggr->alloc_size) {
+ /* Allocate more room for this new block the regular way */
+ if(HADDR_UNDEF == (new_space = H5FD_real_alloc(file, type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
+
+ /* Check if the new space is at the end of the current block */
+ if((aggr->addr + aggr->size) == new_space) {
+ /*
+ * Treat the allocation request as if the current block
+ * grew by the amount allocated and just update the address.
+ *
+ * Don't bother updating the block's size since it will
+ * just grow and shrink by the same amount.
+ *
+ * _Do_ add to the total size aggregated.
+ *
+ */
+ ret_value = aggr->addr;
+ aggr->addr += size;
+ aggr->tot_size += size;
+ } /* end if */
+ else {
+ /* Check if the new space is at the end of the _other_ block */
+ if(other_aggr->size > 0 && (other_aggr->addr + other_aggr->size) == new_space) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: New block is at end of 'other' block: other_aggr = {%a, %Hu, %Hu}\n", FUNC, other_aggr->addr, other_aggr->tot_size, other_aggr->size);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* If the other block has used at least the
+ * 'allocation' amount for that block, shift the
+ * newly allocated space down over the remainder
+ * in the 'other block', shift the 'other block'
+ * up by the same amount and free it. (Which
+ * should amount to "bubbling" the remainder in
+ * the 'other block' to the end of the file and
+ * then "popping" the bubble by shrinking the
+ * file)
+ */
+ if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
+ H5FD_mem_t alloc_type = (other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+ haddr_t free_addr = (new_space + size) - other_aggr->size; /* Address of free space in 'other block' shifted toward end of the file */
+ hsize_t free_size = other_aggr->size; /* Size of the free space in 'other block' */
+
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Freeing 'other' block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Reset 'other' block's info */
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+
+ /* Shift newly allocated space down */
+ new_space -= free_size;
+
+ /* Return the unused portion of the 'other' block to a free list */
+ if(H5FD_free(file, alloc_type, dxpl_id, free_addr, free_size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+ } /* end if */
+ } /* end if */
+
+ /* Use the new space allocated, leaving the old block */
+ ret_value = new_space;
+ } /* end else */
+ } /* end if */
+ else {
+ H5FD_mem_t alloc_type = (aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+
+ /* Allocate another block */
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Allocating block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ if(HADDR_UNDEF == (new_space = H5FD_real_alloc(file, alloc_type, dxpl_id, aggr->alloc_size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
+
+ /* Check if the new space is at the end of the current block */
+ if(aggr->addr + aggr->size == new_space) {
+ aggr->size += aggr->alloc_size;
+ aggr->tot_size += aggr->alloc_size;
+ } /* end if */
+ else {
+ hsize_t new_size; /* Size of new aggregator block */
+
+ /* Return the unused portion of the block to a free list */
+ if(aggr->size > 0)
+ if(H5FD_free(file, alloc_type, dxpl_id, aggr->addr, aggr->size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+
+ /* Check if the new space is at the end of the _other_ block */
+ if(other_aggr->size > 0 && (other_aggr->addr + other_aggr->size) == new_space) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: New block is at end of 'other' block: other_aggr = {%a, %Hu, %Hu}\n", FUNC, other_aggr->addr, other_aggr->tot_size, other_aggr->size);
+#endif /* H5FD_ALLOC_DEBUG */
+#ifdef QAK
+ /* If the other block has used at least the
+ * 'allocation' amount for that block, give the
+ * remaining free space in the 'other' block to
+ * the new space allocated for 'this' block.
+ */
+ if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Absorbing 'other' block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Absorb the remaining free space into newly allocated block */
+ new_space -= other_aggr->size;
+ new_size = aggr->alloc_size + other_aggr->size;
+
+ /* Reset the info for the 'other' block */
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+ } /* end if */
+ else
+ new_size = aggr->alloc_size;
+#else /* QAK */
+ /* If the other block has used at least the
+ * 'allocation' amount for that block, shift the
+ * newly allocated space down over the remainder
+ * in the 'other block', shift the 'other block'
+ * up by the same amount and free it. (Which
+ * should amount to "bubbling" the remainder in
+ * the 'other block' to the end of the file and
+ * then "popping" the bubble by shrinking the
+ * file)
+ */
+ if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
+ H5FD_mem_t other_type = (other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+ haddr_t free_addr = (new_space + aggr->alloc_size) - other_aggr->size; /* Address of free space in 'other block' shifted toward end of the file */
+ hsize_t free_size = other_aggr->size; /* Size of the free space in 'other block' */
+
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Freeing 'other' block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Reset 'other' block's info */
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+
+ /* Shift newly allocated space down */
+ new_space -= free_size;
+
+ /* Return the unused portion of the 'other' block to a free list */
+ if(H5FD_free(file, other_type, dxpl_id, free_addr, free_size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+ } /* end if */
+ new_size = aggr->alloc_size;
+#endif /* QAK */
+ } /* end if */
+ else
+ new_size = aggr->alloc_size;
+
+ /* Point the aggregator at the newly allocated block */
+ aggr->addr = new_space;
+ aggr->size = new_size;
+ aggr->tot_size = new_size;
+ } /* end else */
+
+ /* Allocate space out of the metadata block */
+ ret_value = aggr->addr;
+ aggr->size -= size;
+ aggr->addr += size;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Allocate space out of the block */
+ ret_value = aggr->addr;
+ aggr->size -= size;
+ aggr->addr += size;
+ }
+ } /* end if */
+ else {
+ /* Allocate data the regular way */
+ if(HADDR_UNDEF == (ret_value = H5FD_real_alloc(file, type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space")
+ } /* end else */
+
+done:
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
+#endif /* H5FD_ALLOC_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_aggr_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_adjoin
+ *
+ * Purpose: Check if a newly freed block of space in the file adjoins an
+ * aggregator block
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_aggr_adjoin(const H5FD_t *file, H5FD_blk_aggr_t *aggr, H5FD_free_t *last)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_adjoin)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(file->cls);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(last);
+
+ /* Check if this free block adjoins the aggregator */
+ if((file->feature_flags & aggr->feature_flag) && aggr->size > 0) {
+ hbool_t adjoins = FALSE; /* Whether the block adjoined the aggregator */
+
+ /* Does the newly freed space adjoin the end of the aggregator */
+ if((aggr->addr + aggr->size) == last->addr) {
+ last->addr = aggr->addr;
+ adjoins = TRUE;
+ } /* end if */
+ /* Does the newly freed space adjoin the beginning of the aggregator */
+ else if((last->addr + last->size) == aggr->addr)
+ adjoins = TRUE;
+
+ /* Reset aggregator information, if adjoined */
+ if(adjoins) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Adjoined flag = %lx aggregator\n", "H5FD_aggr_adjoin", aggr->feature_flag);
+#endif /* H5FD_ALLOC_DEBUG */
+ last->size += aggr->size;
+ aggr->addr = 0;
+ aggr->size = 0;
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_aggr_adjoin() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_can_extend
+ *
+ * Purpose: Check is an aggregator block can be extended
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5FD_aggr_can_extend(const H5FD_t *file, const H5FD_blk_aggr_t *aggr, haddr_t eoa,
+ haddr_t end)
+{
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_can_extend)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Check if this aggregator is active */
+ if(file->feature_flags & aggr->feature_flag) {
+ /* If the aggregator block is at the end of the file, and the block to
+ * test adjoins the beginning of the aggregator block, then it's
+ * extendable
+ */
+ if((aggr->addr + aggr->size) == eoa && end == aggr->addr)
+ HGOTO_DONE(TRUE)
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_aggr_can_extend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_extend
+ *
+ * Purpose: Shift an aggregator block in the file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_aggr_shift(H5FD_blk_aggr_t *aggr, hsize_t extra)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_shift)
+
+ /* Check args */
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Shift the aggregator block by the extra amount */
+ aggr->addr += extra;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_aggr_shift() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_query
+ *
+ * Purpose: Query a block aggregator's current address & size info
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_aggr_query(const H5FD_t *file, const H5FD_blk_aggr_t *aggr, haddr_t *addr,
+ hsize_t *size)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_query)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Check if this aggregator is active */
+ if(file->feature_flags & aggr->feature_flag) {
+ *addr = aggr->addr;
+ *size = aggr->size;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_aggr_query() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_reset
+ *
+ * Purpose: Reset a block aggregator, returning any space back to file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_aggr_reset(H5FD_t *file, H5FD_blk_aggr_t *aggr, hid_t dxpl_id)
+{
+ H5FD_mem_t alloc_type; /* Type of file memory to work with */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_aggr_reset, FAIL)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Set the type of memory in the file */
+ alloc_type = (aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+
+ /* Check if this aggregator is active */
+ if(file->feature_flags & aggr->feature_flag) {
+ /* Return the unused portion of the metadata block to a free list */
+ if(aggr->size > 0)
+ if(H5FD_free(file, alloc_type, dxpl_id, aggr->addr, aggr->size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free aggregator block")
+
+ /* Reset aggregator block information */
+ aggr->tot_size = 0;
+ aggr->addr = 0;
+ aggr->size = 0;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_aggr_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_real_alloc
+ *
+ * Purpose: Double private version of H5FDalloc() :-)
+ *
+ * Return: Success: The format address of the new file memory.
+ * Failure: The undefined address HADDR_UNDEF
+ *
+ * Programmer: Quincey Koziol
+ * Friday, August 25, 2000
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+{
+ haddr_t ret_value = HADDR_UNDEF;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FD_real_alloc)
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ /* check args */
+ assert(file);
+ assert(file->cls);
+ assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ assert(size > 0);
+
+ /*
+ * Dispatch to driver `alloc' callback or extend the end-of-address
+ * marker
+ */
+ if(file->cls->alloc) {
+ if((ret_value = (file->cls->alloc)(file, type, dxpl_id, size)) == HADDR_UNDEF)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver allocation request failed")
+ } else {
+ if((ret_value = H5FD_update_eoa(file, type, dxpl_id, size)) == HADDR_UNDEF)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "driver eoa update request failed")
+ }
+
+done:
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
+#endif /* H5FD_ALLOC_DEBUG */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_real_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_update_eoa
+ *
+ * Purpose: Update the EOA field of the file's memory.
+ *
+ * This was split off from the H5FD_real_alloc function to
+ * make life easier for all.
+ *
+ * Return: Success: The format address of the new file memory.
+ * Failure: The undefined address HADDR_UNDEF
+ *
+ * Programmer: Bill Wendling
+ * Wednesday, 04. December, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+{
+ haddr_t eoa, oldeoa = 0;
+ hsize_t wasted;
+ haddr_t ret_value = HADDR_UNDEF;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FD_update_eoa)
+
+ /* check args */
+ assert(file);
+ assert(file->cls);
+ assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ assert(size > 0);
+
+ eoa = file->cls->get_eoa(file, type);
+
+#ifdef H5F_DEBUG
+ if(file->alignment * file->threshold != 1 && H5DEBUG(F))
+ HDfprintf(H5DEBUG(F),
+ "%s: alignment=%Hd, threshold=%Hd, size=%Hd, Begin eoa=%a\n",
+ FUNC, file->alignment, file->threshold, size, eoa);
+#endif /* H5F_DEBUG */
+
+ /* Wasted is 0 if not exceeding threshold or eoa happens to be aligned */
+ wasted = (size >= file->threshold) ? (eoa % file->alignment) : 0;
+ if(wasted) {
+ wasted = file->alignment - wasted; /* actual waste */
+ oldeoa = eoa; /* save it for later freeing */
+
+ /* Advance eoa to the next alignment by allocating the wasted */
+ if(H5F_addr_overflow(eoa, size) || (eoa + wasted) > file->maxaddr)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
+
+ eoa += wasted;
+
+ if(file->cls->set_eoa(file, type, eoa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
+ } /* end if */
+
+ /* allocate the aligned memory */
+ if(H5F_addr_overflow(eoa, size) || eoa + size > file->maxaddr)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
+
+ ret_value = eoa;
+ eoa += size;
+
+ if(file->cls->set_eoa(file, type, eoa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, "file allocation request failed")
+
+ /* Free the wasted memory */
+ if(wasted) {
+ if(H5FD_free(file, type, dxpl_id, oldeoa, wasted) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
+ } /* end if */
+
+#ifdef H5F_DEBUG
+ if(file->alignment * file->threshold != 1 && H5DEBUG(F))
+ HDfprintf(H5DEBUG(F),
+ "%s: ret_value=%a, wasted=%Hd, Ended eoa=%a\n",
+ FUNC, ret_value, wasted, eoa);
+#endif /* H5F_DEBUG */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_update_eoa() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_free
+ *
+ * Purpose: Private version of H5FDfree()
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
+{
+ H5FD_mem_t mapped_type;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_free, FAIL)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(file->cls);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ if(!H5F_addr_defined(addr) || addr > file->maxaddr ||
+ H5F_addr_overflow(addr, size) || (addr + size) > file->maxaddr)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid region")
+
+ /* Allow 0-sized free's to occur without penalty */
+ if(0 == size)
+ HGOTO_DONE(SUCCEED)
+
+ /* Map request type to free list */
+ if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
+ mapped_type = type;
+ else
+ mapped_type = file->cls->fl_map[type];
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: mapped_type = %u\n", FUNC, (unsigned)mapped_type);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ /*
+ * If the request maps to a free list then add memory to the free list
+ * without ever telling the driver that it was freed. Otherwise let the
+ * driver deallocate the memory.
+ */
+ if(mapped_type >= H5FD_MEM_DEFAULT) {
+ H5FD_free_t *last; /* Last merged node */
+ H5FD_free_t *last_prev = NULL;/* Pointer to node before merged node */
+ H5FD_free_t *curr; /* Current free block being inspected */
+ H5FD_free_t *prev; /* Previous free block being inspected */
+
+ /* Adjust the metadata accumulator to remove the freed block, if it overlaps */
+ if((file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA)
+ && H5F_addr_overlap(addr, size, file->accum_loc, file->accum_size)) {
+ size_t overlap_size; /* Size of overlap with accumulator */
+
+ /* Check for overlapping the beginning of the accumulator */
+ if(H5F_addr_le(addr, file->accum_loc)) {
+ /* Check for completely overlapping the accumulator */
+ if(H5F_addr_ge(addr + size, file->accum_loc + file->accum_size)) {
+ /* Reset the entire accumulator */
+ file->accum_loc=HADDR_UNDEF;
+ file->accum_size=FALSE;
+ file->accum_dirty=FALSE;
+ } /* end if */
+ /* Block to free must end within the accumulator */
+ else {
+ size_t new_accum_size; /* Size of new accumulator buffer */
+
+ /* Calculate the size of the overlap with the accumulator, etc. */
+ H5_ASSIGN_OVERFLOW(overlap_size,(addr+size)-file->accum_loc,haddr_t,size_t);
+ new_accum_size=file->accum_size-overlap_size;
+
+ /* Move the accumulator buffer information to eliminate the freed block */
+ HDmemmove(file->meta_accum,file->meta_accum+overlap_size,new_accum_size);
+
+ /* Adjust the accumulator information */
+ file->accum_loc+=overlap_size;
+ file->accum_size=new_accum_size;
+ } /* end else */
+ } /* end if */
+ /* Block to free must start within the accumulator */
+ else {
+ /* Calculate the size of the overlap with the accumulator */
+ H5_ASSIGN_OVERFLOW(overlap_size,(file->accum_loc+file->accum_size)-addr,haddr_t,size_t);
+
+ /* Block to free is in the middle of the accumulator */
+ if(H5F_addr_lt((addr + size), file->accum_loc + file->accum_size)) {
+ haddr_t tail_addr;
+ size_t tail_size;
+
+ /* Calculate the address & size of the tail to write */
+ tail_addr=addr+size;
+ H5_ASSIGN_OVERFLOW(tail_size,(file->accum_loc+file->accum_size)-tail_addr,haddr_t,size_t);
+
+ /* Write out the part of the accumulator after the block to free */
+ /* (Use the driver's write call directly - to avoid looping back and writing to metadata accumulator) */
+ if((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, tail_addr, tail_size, file->meta_accum+(tail_addr-file->accum_loc)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed")
+ } /* end if */
+
+ /* Adjust the accumulator information */
+ file->accum_size=file->accum_size-overlap_size;
+ } /* end else */
+ } /* end if */
+
+ /* Scan through the existing blocks for the mapped type to see if we can extend one */
+ curr = file->fl[mapped_type];
+ last = prev = NULL;
+ while(curr != NULL) {
+ /* Check if the block to free adjoins the start of the current block */
+ if((addr + size) == curr->addr) {
+ /* If we previously found & merged a node, eliminate it from the list & free it */
+ if(last != NULL) {
+ /* Check if there was a previous block in the list */
+ if(last_prev != NULL)
+ /* Eliminate the merged block from the list */
+ last_prev->next = last->next;
+ /* No previous block, this must be the head of the list */
+ else
+ /* Eliminate the merged block from the list */
+ file->fl[mapped_type] = last->next;
+
+ /* Check for eliminating the block before the 'current' one */
+ if(last == prev)
+ prev = last_prev;
+
+ /* Free the memory for the merged block */
+ H5FL_FREE(H5FD_free_t, last);
+ } /* end if */
+
+ /* Adjust the address and size of the block found */
+ curr->addr = addr;
+ curr->size += size;
+
+ /* Adjust the information about to memory block to include the merged block */
+ addr = curr->addr;
+ size = curr->size;
+
+ /* Update the information about the merged node */
+ last = curr;
+ last_prev = prev;
+ } /* end if */
+ else {
+ /* Check if the block to free adjoins the end of the current block */
+ if((curr->addr + curr->size) == addr) {
+ /* If we previously found & merged a node, eliminate it from the list & free it */
+ if(last != NULL) {
+ /* Check if there was a previous block in the list */
+ if(last_prev != NULL)
+ /* Eliminate the merged block from the list */
+ last_prev->next = last->next;
+ /* No previous block, this must be the head of the list */
+ else
+ /* Eliminate the merged block from the list */
+ file->fl[mapped_type] = last->next;
+
+ /* Check for eliminating the block before the 'current' one */
+ if(last == prev)
+ prev = last_prev;
+
+ /* Free the memory for the merged block */
+ H5FL_FREE(H5FD_free_t, last);
+ } /* end if */
+
+ /* Adjust the size of the block found */
+ curr->size += size;
+
+ /* Adjust the information about to memory block to include the merged block */
+ addr = curr->addr;
+ size = curr->size;
+
+ /* Update the information about the merged node */
+ last = curr;
+ last_prev = prev;
+ } /* end if */
+ } /* end else */
+
+ /* Advance to next node in list */
+ prev = curr;
+ curr = curr->next;
+ } /* end while */
+
+ /* Check if we adjusted an existing block */
+ if(last != NULL) {
+ /* Move the node found to the front, if it wasn't already there */
+ if(last_prev != NULL) {
+ last_prev->next = last->next;
+ last->next = file->fl[mapped_type];
+ file->fl[mapped_type] = last;
+ } /* end if */
+ } /* end if */
+ else {
+ /* Allocate a new node to hold the free block's information */
+ if(NULL == (last = H5FL_MALLOC(H5FD_free_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate node for free space info")
+
+ last->addr = addr;
+ last->size = size;
+ last->next = file->fl[mapped_type];
+ file->fl[mapped_type] = last;
+ } /* end else */
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: mapped_type = %u, last = {%a, %Hu}\n", FUNC, (unsigned)mapped_type, last->addr, last->size);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ /* Check if we increased the size of the largest block on the list */
+ file->maxsize = MAX(file->maxsize, last->size);
+
+ /* Check if this free block adjoins the "metadata aggregator" */
+ if(H5FD_aggr_adjoin(file, &(file->meta_aggr), last) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "aggregator deallocation request failed")
+
+ /* Check if this free block adjoins the "small data aggregator" */
+ if(H5FD_aggr_adjoin(file, &(file->sdata_aggr), last) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "aggregator deallocation request failed")
+
+ /* Check if this free block is at the end of file allocated space.
+ * Truncate it if this is true. */
+ if(file->cls->get_eoa) {
+ haddr_t eoa;
+
+ eoa = file->cls->get_eoa(file, type);
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: eoa = %a\n", FUNC, eoa);
+#endif /* H5FD_ALLOC_DEBUG */
+ if(eoa == (last->addr + last->size)) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, last->addr);
+#endif /* H5FD_ALLOC_DEBUG */
+ if(file->cls->set_eoa(file, type, last->addr) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
+
+ /* Remove this free block from the list */
+ file->fl[mapped_type] = last->next;
+ if(file->maxsize == last->size)
+ file->maxsize = 0; /*unknown*/
+ H5FL_FREE(H5FD_free_t, last);
+ } /* end if */
+ } /* end if */
+ } else if(file->cls->free) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Letting VFD free space\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ if((file->cls->free)(file, type, dxpl_id, addr, size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed")
+ } else {
+ /* leak memory */
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: LEAKED MEMORY!!! type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
+#endif /* H5FD_ALLOC_DEBUG */
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_realloc
+ *
+ * Purpose: Private version of H5FDrealloc()
+ *
+ * Return: Success: New address of the block of memory, not
+ * necessarily the same as the original address.
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5FD_realloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t old_size,
+ hsize_t new_size)
+{
+ haddr_t new_addr=old_addr;
+ uint8_t _buf[8192];
+ uint8_t *buf=_buf;
+ haddr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_realloc, HADDR_UNDEF)
+
+ if(new_size == old_size) {
+ /*nothing to do*/
+ } else if(0 == old_size) {
+ /* allocate memory */
+ HDassert(!H5F_addr_defined(old_addr));
+ if(HADDR_UNDEF == (new_addr = H5FD_alloc(file, type, dxpl_id, new_size)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
+ } else if(0==new_size) {
+ /* free memory */
+ HDassert(H5F_addr_defined(old_addr));
+ if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
+ new_addr = HADDR_UNDEF;
+ } else if(new_size<old_size) {
+ /* free the end of the block */
+ if(H5FD_free(file, type, dxpl_id, old_addr+old_size, old_size-new_size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
+ } else {
+ /* move memory to new location */
+ /* Note! This may fail if sizeof(hsize_t)>sizeof(size_t) and the
+ * object on disk is too large to read into a memory buffer all at one
+ * time. This chunk of code would have to be re-written using a loop
+ * to move pieces of the realloced data through a fixed size buffer, etc.
+ * -QAK, 6/20/01
+ */
+ if(HADDR_UNDEF == (new_addr = H5FD_alloc(file, type, dxpl_id, new_size)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
+ H5_CHECK_OVERFLOW(old_size,hsize_t,size_t);
+ if(old_size > sizeof(_buf) && NULL == (buf = H5MM_malloc((size_t)old_size))) {
+ (void)H5FD_free(file, type, dxpl_id, new_addr, new_size);
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed")
+ } /* end if */
+ if(H5FD_read(file, type, dxpl_id, old_addr, (size_t)old_size, buf) < 0 ||
+ H5FD_write(file, type, dxpl_id, new_addr, (size_t)old_size, buf) < 0) {
+ (void)H5FD_free(file, type, dxpl_id, new_addr, new_size);
+ if(buf != _buf)
+ H5MM_xfree(buf);
+ HGOTO_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, "unable to move file block")
+ } /* end if */
+
+ if(buf != _buf)
+ H5MM_xfree(buf);
+ if(H5FD_free(file, type, dxpl_id, old_addr, old_size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "file deallocation request failed")
+ } /* end else */
+
+ /* Set return value */
+ ret_value = new_addr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_realloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_can_extend
+ *
+ * Purpose: Check if a block in the file can be extended.
+ *
+ * Return: Success: TRUE(1)/FALSE(0)
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, June 11, 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
+{
+ haddr_t end; /* End of block in file */
+ haddr_t eoa; /* End of address space in the file */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_can_extend, FAIL)
+
+ /* Retrieve the end of the address space */
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file, type)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
+
+ /* Compute end of block */
+ end = addr + size;
+
+ /* Check if the block is exactly at the end of the file */
+ if(end == eoa)
+ HGOTO_DONE(TRUE)
+ else {
+ H5FD_free_t *curr; /* Current free block being inspected */
+ H5FD_mem_t mapped_type; /* Memory type, after mapping */
+
+ /* Map request type to free list */
+ if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
+ mapped_type = type;
+ else
+ mapped_type = file->cls->fl_map[type];
+
+ /* Check if block is inside the metadata or small data aggregator */
+ if(mapped_type!=H5FD_MEM_DRAW) {
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->meta_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
+ else if(ret_value > 0)
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ else {
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->sdata_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if 'small data' aggregation block can be extended")
+ else if(ret_value > 0)
+ HGOTO_DONE(TRUE)
+ } /* end else */
+
+ /* Scan through the existing blocks for the mapped type to see if we can extend one */
+ if(mapped_type >= H5FD_MEM_DEFAULT) {
+ curr = file->fl[mapped_type];
+ while(curr != NULL) {
+ if(end == curr->addr) {
+ if(extra_requested <= curr->size)
+ HGOTO_DONE(TRUE)
+ else
+ HGOTO_DONE(FALSE)
+ } /* end if */
+
+ /* Advance to next node in list */
+ curr=curr->next;
+ } /* end while */
+ } /* end if */
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_can_extend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_extend
+ *
+ * Purpose: Extend a block in the file.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, June 12, 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
+{
+ haddr_t eoa; /* End of address space in the file */
+ haddr_t end; /* End of block in file */
+ hbool_t update_eoma=FALSE; /* Whether we need to update the eoma */
+ hbool_t update_eosda=FALSE; /* Whether we need to update the eosda */
+ hbool_t at_end=FALSE; /* Block is at end of file */
+ H5FD_mem_t mapped_type; /* Memory type, after mapping */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_extend, FAIL)
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n", FUNC, (unsigned)type, addr, size, extra_requested);
+#endif /* H5FD_ALLOC_DEBUG */
+
+ /* Retrieve the end of the address space */
+ if(HADDR_UNDEF==(eoa=H5FD_get_eoa(file, type)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
+
+ /* Map request type to free list */
+ if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
+ mapped_type = type;
+ else
+ mapped_type = file->cls->fl_map[type];
+
+ /* Compute end of block */
+ end = addr + size;
+
+ /* Check if the block is exactly at the end of the file */
+ if(end == eoa)
+ at_end = TRUE;
+ else {
+ /* (Check if block is inside the metadata or small data accumulator) */
+ if(mapped_type!=H5FD_MEM_DRAW) {
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->meta_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
+ else if(ret_value > 0)
+ update_eoma = TRUE;
+ } /* end if */
+ else {
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->sdata_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
+ else if(ret_value > 0)
+ update_eosda = TRUE;
+ } /* end else */
+ } /* end else */
+
+ /* Block is at end of file, we are extending the eoma or eosda */
+ if(update_eoma || update_eosda || at_end) {
+ /* Check for overflowing the file */
+ if(H5F_addr_overflow(eoa, extra_requested) || eoa + extra_requested > file->maxaddr)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed")
+
+ /* Extend the file */
+ eoa += extra_requested;
+ if(file->cls->set_eoa(file, type, eoa) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed")
+
+ /* Update the metadata and/or small data block */
+ HDassert(!(update_eoma && update_eosda));
+ if(update_eoma)
+ H5FD_aggr_shift(&(file->meta_aggr), extra_requested);
+ if(update_eosda)
+ H5FD_aggr_shift(&(file->sdata_aggr), extra_requested);
+ } /* end if */
+ /* If the block we are extending isn't at the end of the file, find a free block to extend into */
+ else {
+ H5FD_free_t *curr; /* Current free block being inspected */
+ H5FD_free_t *prev; /* Current free block being inspected */
+
+ /* Walk through free list, looking for block to merge with */
+ curr = file->fl[mapped_type];
+ prev = NULL;
+ while(curr!=NULL) {
+ /* Found block that ajoins end of block to extend */
+ if(end == curr->addr) {
+ /* Check if free space is large enough */
+ if(extra_requested <= curr->size) {
+ /* Check for exact match */
+ if(extra_requested == curr->size) {
+ /* Unlink node from free list */
+ if(prev == NULL)
+ file->fl[mapped_type] = curr->next;
+ else
+ prev->next = curr->next;
+
+ /* Free the memory for the used block */
+ H5FL_FREE(H5FD_free_t, curr);
+ } /* end if */
+ else {
+ curr->addr += extra_requested;
+ curr->size -= extra_requested;
+ } /* end else */
+
+ /* Leave now */
+ break;
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block")
+ } /* end if */
+
+ /* Advance to next node in list */
+ prev = curr;
+ curr = curr->next;
+ } /* end while */
+
+ /* Couldn't find block to extend */
+ if(curr == NULL)
+ HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "can't extend block")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_extend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_get_freespace
+ *
+ * Purpose: Retrieve the amount of free space in a file.
+ *
+ * Return: Success: Amount of free space in file
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 6, 2003
+ *
+ * Note:
+ * Raymond Lu
+ * 5 January 2007
+ * Due to the complexity EOA for Multi driver, this function
+ * is made failed for now.
+ *
+ *-------------------------------------------------------------------------
+ */
+hssize_t
+H5FD_get_freespace(const H5FD_t *file)
+{
+ H5FD_free_t *free_node; /* Pointer to node on free list */
+ H5FD_mem_t type; /* Type of memory */
+ haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
+ hsize_t ma_size = 0; /* Size of "metadata aggregator" */
+ haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
+ hsize_t sda_size = 0; /* Size of "small data aggregator" */
+ haddr_t eoa = 0; /* End of allocated space in the file */
+ hssize_t ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_get_freespace, FAIL)
+
+ /* check args */
+ HDassert(file);
+ HDassert(file->cls);
+
+ /* Multi driver doesn't support this function because of the complexity.
+ * It doesn't have eoa for the whole file. */
+ if(file->driver_id == H5FD_MULTI)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "Multi driver doesn't support this function")
+
+ /* Retrieve the 'eoa' for the file */
+ eoa = file->cls->get_eoa(file, H5FD_MEM_DEFAULT);
+
+ /* Retrieve metadata aggregator info, if available */
+ H5FD_aggr_query(file, &(file->meta_aggr), &ma_addr, &ma_size);
+
+ /* Retrieve 'small data' aggregator info, if available */
+ H5FD_aggr_query(file, &(file->sdata_aggr), &sda_addr, &sda_size);
+
+ /* Iterate over all the types of memory, to retrieve amount of free space for each */
+ for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,type)) {
+ /* Iterate through the free list, accumulating the amount of free space for this type */
+ free_node = file->fl[type];
+ while(free_node) {
+ /* Check for current node adjoining the metadata & small data aggregators */
+ if(H5F_addr_eq(free_node->addr + free_node->size, ma_addr)) {
+ ma_addr -= free_node->size;
+ ma_size += free_node->size;
+ } else if(H5F_addr_eq(free_node->addr + free_node->size, sda_addr)) {
+ sda_addr -= free_node->size;
+ sda_size += free_node->size;
+ } else if(H5F_addr_eq(ma_addr + ma_size, free_node->addr))
+ ma_size += free_node->size;
+ else if(H5F_addr_eq(sda_addr + sda_size, free_node->addr))
+ sda_size += free_node->size;
+ else
+ ret_value += (hssize_t)free_node->size;
+ free_node = free_node->next;
+ } /* end while */
+ } /* end for */
+
+ /* Check for aggregating metadata allocations */
+ if(ma_size > 0) {
+ /* Add in the reserved space for metadata to the available free space */
+ /* (if it's not at the tail of the file) */
+ if(H5F_addr_ne(ma_addr + ma_size, eoa))
+ ret_value += ma_size;
+ } /* end if */
+
+ /* Check for aggregating small data allocations */
+ if(sda_size > 0) {
+ /* Add in the reserved space for metadata to the available free space */
+ /* (if it's not at the tail of the file) */
+ if(H5F_addr_ne(sda_addr + sda_size, eoa))
+ ret_value += sda_size;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_get_freespace() */
+
diff --git a/src/H5FS.c b/src/H5FS.c
index f1907b2..2dd2833 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -101,6 +101,9 @@ H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr, const H5FS_create_t *fs_c
H5FS_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FS_create, NULL)
+#ifdef QAK
+HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, nclasses);
+#endif /* QAK */
/* Check arguments. */
HDassert(fs_addr);
@@ -373,13 +376,13 @@ HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_c
else {
unsigned sect_status = 0; /* Free space section's status in the metadata cache */
- /* Check the free space section's status in the metadata cache */
- if(H5AC_get_entry_status(f, fspace->sect_addr, &sect_status) < 0)
+ /* Check if we've allocated any section info in the file & if it's still in the cache */
+ if(H5F_addr_defined(fspace->sect_addr) && H5AC_get_entry_status(f, fspace->sect_addr, &sect_status) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space header")
- /* If this free list header's section info is still in the cache, don't
- * unpin the header - let the section info do it, when the section
- * into is evicted from the cache. -QAK
+ /* If this free list header's section info exists and is still in the
+ * cache, don't unpin the header - let the section info do it,
+ * when the section info is evicted from the cache. -QAK
*/
if(!(sect_status & H5AC_ES__IN_CACHE)) {
/* Unpin the free space header in the cache */
diff --git a/src/H5FSsection.c b/src/H5FSsection.c
index 505223a..c589aa0 100644
--- a/src/H5FSsection.c
+++ b/src/H5FSsection.c
@@ -187,6 +187,9 @@ H5FS_sinfo_pin(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
H5FS_sinfo_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_pin)
+#ifdef QAK
+HDfprintf(stderr, "%s: Called, fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
+#endif /* QAK */
/* Check arguments. */
HDassert(f);
@@ -194,6 +197,9 @@ H5FS_sinfo_pin(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
/* Create new section info, if it doesn't exist yet */
if(!H5F_addr_defined(fspace->sect_addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Allocating new section info\n", FUNC);
+#endif /* QAK */
/* Sanity check */
HDassert(fspace->tot_sect_count == 0);
HDassert(fspace->serial_sect_count == 0);
@@ -208,6 +214,9 @@ H5FS_sinfo_pin(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
fspace->alloc_sect_size = (size_t)fspace->sect_size;
if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->alloc_sect_size)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, NULL, "file allocation failed for free space sections")
+#ifdef QAK
+HDfprintf(stderr, "%s: New section info, addr = %a, size = %Hu\n", FUNC, fspace->sect_addr, fspace->alloc_sect_size);
+#endif /* QAK */
/* Cache the new free space section info (pinned) */
if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, sinfo, H5AC__PIN_ENTRY_FLAG) < 0)
@@ -1209,12 +1218,6 @@ HDfprintf(stderr, "%s: request = %Hu\n", FUNC, request);
HDassert(request);
HDassert(node);
- /* Check if we need to go get the sections */
- if(fspace->sinfo == NULL) {
- if(NULL == (fspace->sinfo = H5FS_sinfo_pin(f, dxpl_id, fspace)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't pin sections")
- } /* end if */
-
/* Check for any sections on free space list */
#ifdef QAK
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
@@ -1222,6 +1225,12 @@ HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", FUNC, fspace->serial_
HDfprintf(stderr, "%s: fspace->ghost_sect_count = %Hu\n", FUNC, fspace->ghost_sect_count);
#endif /* QAK */
if(fspace->tot_sect_count > 0) {
+ /* Check if we need to go get the sections */
+ if(fspace->sinfo == NULL) {
+ if(NULL == (fspace->sinfo = H5FS_sinfo_pin(f, dxpl_id, fspace)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't pin sections")
+ } /* end if */
+
/* Look for node in bins */
if((ret_value = H5FS_sect_find_node(fspace, request, node)) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't remove section from bins")
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 9df85bb..bea0579 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -90,7 +90,7 @@ typedef struct H5F_file_t {
unsigned sohm_vers; /* Version of shared message table on disk */
unsigned sohm_nindexes; /* Number of shared messages indexes in the table */
haddr_t driver_addr; /* File driver information block address*/
- hbool_t fam_to_sec2; /* Is h5repart changing driver from family to sec2 */
+ haddr_t maxaddr; /* Maximum address for file */
H5AC_t *cache; /* The object cache */
H5AC2_t *cache2; /* test cache */
@@ -109,7 +109,8 @@ typedef struct H5F_file_t {
hsize_t alignment; /* Alignment */
unsigned gc_ref; /* Garbage-collect references? */
hbool_t latest_format; /* Always use the latest format? */
- hbool_t store_msg_crt_idx; /* Store creation index for object header messages? */
+ hbool_t store_msg_crt_idx; /* Store creation index for object header messages? */
+ hbool_t fam_to_sec2; /* Is h5repart changing driver from family to sec2? */
int ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
struct H5G_t *root_grp; /* Open root group */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 903f56d..b61773a 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -267,6 +267,7 @@ typedef struct H5F_t H5F_t;
#define H5F_INTENT(F) ((F)->intent)
#define H5F_GET_FC_DEGREE(F) ((F)->shared->fc_degree)
#define H5F_STORE_MSG_CRT_IDX(F) ((F)->shared->store_msg_crt_idx)
+#define H5F_GET_FILENO(F,FILENUM) ((FILENUM) = (F)->shared->lf->fileno)
#else /* H5F_PACKAGE */
#define H5F_FCPL(F) (H5F_get_fcpl(F))
#define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F))
@@ -285,6 +286,7 @@ typedef struct H5F_t H5F_t;
#define H5F_INTENT(F) (H5F_get_intent(F))
#define H5F_GET_FC_DEGREE(F) (H5F_get_fc_degree(F))
#define H5F_STORE_MSG_CRT_IDX(F) (H5F_store_msg_crt_idx(F))
+#define H5F_GET_FILENO(F,FILENUM) (H5F_get_filenum((F), &(FILENUM)))
#endif /* H5F_PACKAGE */
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 1d98330..a055d46 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -107,6 +107,12 @@ typedef struct H5F_info_t {
} sohm;
} H5F_info_t;
+/* Library's file format versions */
+typedef enum H5F_libver_t {
+ H5F_LIBVER_EARLIEST, /* Use the earliest possible format for storing objects */
+ H5F_LIBVER_LATEST /* Use the latest possible format available for storing objects*/
+} H5F_libver_t;
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/src/H5G.c b/src/H5G.c
index 256edc3..303564d 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -88,6 +88,7 @@
#include "H5Gpkg.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
#include "H5Lprivate.h" /* Links */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5AC2private.h" /* Metadata cache */
@@ -101,14 +102,43 @@ typedef struct {
H5G_loc_t *loc; /* Pointer to the location for insertion */
} H5G_trav_ins_t;
+/* User data for application-style iteration over links in a group */
+typedef struct {
+ hid_t gid; /* The group ID for the application callback */
+ H5G_link_iterate_t lnk_op; /* Application callback */
+ void *op_data; /* Application's op data */
+} H5G_iter_appcall_ud_t;
+
+/* User data for recursive traversal over links from a group */
+typedef struct {
+ hid_t gid; /* The group ID for the starting group */
+ H5G_loc_t *curr_loc; /* Location of starting group */
+ hid_t lapl_id; /* LAPL for walking across links */
+ hid_t dxpl_id; /* DXPL for operations */
+ H5_index_t idx_type; /* Index to use */
+ H5_iter_order_t order; /* Iteration order within index */
+ H5SL_t *visited; /* Skip list for tracking visited nodes */
+ char *path; /* Path name of the link */
+ size_t curr_path_len; /* Current length of the path in the buffer */
+ size_t path_buf_size; /* Size of path buffer */
+ H5L_iterate_t op; /* Application callback */
+ void *op_data; /* Application's op data */
+} H5G_iter_visit_ud_t;
+
+
/* Package variables */
+
/* Local variables */
/* Declare a free list to manage the H5G_t struct */
H5FL_DEFINE(H5G_t);
H5FL_DEFINE(H5G_shared_t);
+/* Declare the free list to manage H5_obj_t's */
+H5FL_DEFINE(H5_obj_t);
+
+
/* Private prototypes */
static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id);
@@ -367,7 +397,7 @@ H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id)
if((grp = H5G_open_name(&loc, name, gapl_id, H5AC_dxpl_id)) == NULL)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
- /* Register an atom for the group */
+ /* Register an ID for the group */
if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
@@ -1021,8 +1051,8 @@ H5G_open_name(const H5G_loc_t *loc, const char *name, hid_t gapl_id,
H5G_loc_t grp_loc; /* Location used to open group */
H5G_name_t grp_path; /* Opened object group hier. path */
H5O_loc_t grp_oloc; /* Opened object object location */
- H5O_type_t obj_type; /* Type of object at location */
hbool_t loc_found = FALSE; /* Location at 'name' found */
+ H5O_type_t obj_type; /* Type of object at location */
H5G_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_open_name, NULL)
@@ -1147,7 +1177,7 @@ H5G_open(const H5G_loc_t *loc, hid_t dxpl_id)
ret_value = grp;
done:
- if (!ret_value && grp) {
+ if(!ret_value && grp) {
H5O_loc_free(&(grp->oloc));
H5G_name_free(&(grp->path));
H5FL_FREE(H5G_t,grp);
@@ -1524,3 +1554,453 @@ H5G_unmount(H5G_t *grp)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5G_unmount() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_iterate_cb
+ *
+ * Purpose: Callback function for iterating over links in a group
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Oct 3, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_iterate_cb(const H5O_link_t *lnk, void *_udata)
+{
+ H5G_iter_appcall_ud_t *udata = (H5G_iter_appcall_ud_t *)_udata; /* User data for callback */
+ herr_t ret_value = H5_ITER_ERROR; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_iterate_cb)
+
+ /* Sanity check */
+ HDassert(lnk);
+ HDassert(udata);
+
+ switch(udata->lnk_op.op_type) {
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+ case H5G_LINK_OP_OLD:
+ /* Make the old-type application callback */
+ ret_value = (udata->lnk_op.op_func.op_old)(udata->gid, lnk->name, udata->op_data);
+ break;
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+
+ case H5G_LINK_OP_NEW:
+ {
+ H5L_info_t info; /* Link info */
+
+ /* Retrieve the info for the link */
+ if(H5G_link_to_info(lnk, &info) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for link")
+
+ /* Make the application callback */
+ ret_value = (udata->lnk_op.op_func.op_new)(udata->gid, lnk->name, &info, udata->op_data);
+ }
+ break;
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_iterate_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_iterate
+ *
+ * Purpose: Private function for iterating over links in a group
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Oct 3, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_iterate(hid_t loc_id, const char *group_name,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
+ const H5G_link_iterate_t *lnk_op, void *op_data, hid_t lapl_id, hid_t dxpl_id)
+{
+ H5G_loc_t loc; /* Location of parent for group */
+ hid_t gid = -1; /* ID of group to iterate over */
+ H5G_t *grp; /* Pointer to group data structure to iterate over */
+ H5G_iter_appcall_ud_t udata; /* User data for callback */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_iterate, FAIL)
+
+ /* Sanity check */
+ HDassert(group_name);
+ HDassert(last_lnk);
+ HDassert(lnk_op && lnk_op->op_func.op_new);
+
+ /*
+ * Open the group on which to operate. We also create a group ID which
+ * we can pass to the application-defined operator.
+ */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(NULL == (grp = H5G_open_name(&loc, group_name, lapl_id, dxpl_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ if((gid = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+
+ /* Set up user data for callback */
+ udata.gid = gid;
+ udata.lnk_op = *lnk_op;
+ udata.op_data = op_data;
+
+ /* Call the real group iteration routine */
+ if((ret_value = H5G_obj_iterate(&(grp->oloc), idx_type, order, skip, last_lnk, H5G_iterate_cb, &udata, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "error iterating over links")
+
+done:
+ /* Release the group opened */
+ if(gid > 0) {
+ if(H5I_dec_ref(gid) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
+ } /* end if */
+ else if(grp && H5G_close(grp) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_iterate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_free_visit_visited
+ *
+ * Purpose: Free the key for an object visited during a group traversal
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Nov 4, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_free_visit_visited(void *item, void UNUSED *key, void UNUSED *operator_data/*in,out*/)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_free_visit_visited)
+
+ H5FL_FREE(H5_obj_t, item);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_free_visit_visited() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_visit_cb
+ *
+ * Purpose: Callback function for recursively visiting links from a group
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Nov 4, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_visit_cb(const H5O_link_t *lnk, void *_udata)
+{
+ H5G_iter_visit_ud_t *udata = (H5G_iter_visit_ud_t *)_udata; /* User data for callback */
+ H5L_info_t info; /* Link info */
+ H5G_loc_t obj_loc; /* Location of object */
+ H5G_name_t obj_path; /* Object's group hier. path */
+ H5O_loc_t obj_oloc; /* Object's object location */
+ hbool_t obj_found = FALSE; /* Object at 'name' found */
+ size_t old_path_len = udata->curr_path_len; /* Length of path before appending this link's name */
+ size_t link_name_len; /* Length of link's name */
+ size_t len_needed; /* Length of path string needed */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_visit_cb)
+
+ /* Sanity check */
+ HDassert(lnk);
+ HDassert(udata);
+
+ /* Check if we will need more space to store this link's relative path */
+ /* ("+2" is for string terminator and possible '/' for group separator later) */
+ link_name_len = HDstrlen(lnk->name);
+ len_needed = udata->curr_path_len + link_name_len + 2;
+ if(len_needed > udata->path_buf_size) {
+ void *new_path; /* Pointer to new path buffer */
+
+ /* Attempt to allocate larger buffer for path */
+ if(NULL == (new_path = H5MM_realloc(udata->path, len_needed)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string")
+ udata->path = new_path;
+ udata->path_buf_size = len_needed;
+ } /* end if */
+
+ /* Build the link's relative path name */
+ HDassert(udata->path[old_path_len] == '\0');
+ HDstrcpy(&(udata->path[old_path_len]), lnk->name);
+ udata->curr_path_len += link_name_len;
+
+ /* Construct the link info from the link message */
+ if(H5G_link_to_info(lnk, &info) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for link")
+
+ /* Make the application callback */
+ ret_value = (udata->op)(udata->gid, udata->path, &info, udata->op_data);
+
+ /* Check for doing more work */
+ if(ret_value == H5_ITER_CONT && lnk->type == H5L_TYPE_HARD) {
+ H5_obj_t obj_pos; /* Object "position" for this object */
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Find the object using the LAPL passed in */
+ /* (Correctly handles mounted files) */
+ if(H5G_loc_find(udata->curr_loc, lnk->name, &obj_loc/*out*/, udata->lapl_id, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5_ITER_ERROR, "object not found")
+ obj_found = TRUE;
+
+ /* Construct unique "position" for this object */
+ H5F_GET_FILENO(obj_oloc.file, obj_pos.fileno);
+ obj_pos.addr = obj_oloc.addr;
+
+ /* Check if we've seen the object the link references before */
+ if(NULL == H5SL_search(udata->visited, &obj_pos)) {
+ H5O_type_t otype; /* Basic object type (group, dataset, etc.) */
+ unsigned rc; /* Reference count of object */
+
+ /* Get the object's reference count and type */
+ if(H5O_get_rc_and_type(&obj_oloc, udata->dxpl_id, &rc, &otype) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get object info")
+
+ /* If its ref count is > 1, we add it to the list of visited objects */
+ /* (because it could come up again during traversal) */
+ if(rc > 1) {
+ H5_obj_t *new_node; /* New object node for visited list */
+
+ /* Allocate new object "position" node */
+ if((new_node = H5FL_MALLOC(H5_obj_t)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate object node")
+
+ /* Set node information */
+ *new_node = obj_pos;
+
+ /* Add to list of visited objects */
+ if(H5SL_insert(udata->visited, new_node, new_node) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert object node into visited list")
+ } /* end if */
+
+ /* If it's a group, we recurse into it */
+ if(otype == H5O_TYPE_GROUP) {
+ H5G_loc_t *old_loc = udata->curr_loc; /* Pointer to previous group location info */
+ H5_index_t idx_type = udata->idx_type; /* Type of index to use */
+ H5O_linfo_t linfo; /* Link info message */
+
+ /* Add the path separator to the current path */
+ HDassert(udata->path[udata->curr_path_len] == '\0');
+ HDstrcpy(&(udata->path[udata->curr_path_len]), "/");
+ udata->curr_path_len++;
+
+ /* Attempt to get the link info for this group */
+ if(H5G_obj_get_linfo(&obj_oloc, &linfo, udata->dxpl_id)) {
+ /* Check for creation order tracking, if creation order index lookup requested */
+ if(idx_type == H5_INDEX_CRT_ORDER) {
+ /* Check if creation order is tracked */
+ if(!linfo.track_corder)
+ /* Switch to name order for this group */
+ idx_type = H5_INDEX_NAME;
+ } /* end if */
+ else
+ HDassert(idx_type == H5_INDEX_NAME);
+ } /* end if */
+ else {
+ /* Clear error stack from not finding the link info message */
+ H5E_clear_stack(NULL);
+
+ /* Can only perform name lookups on groups with symbol tables */
+ if(idx_type != H5_INDEX_NAME)
+ /* Switch to name order for this group */
+ idx_type = H5_INDEX_NAME;
+ } /* end if */
+
+ /* Point to this group's location info */
+ udata->curr_loc = &obj_loc;
+
+ /* Iterate over links in group */
+ ret_value = H5G_obj_iterate(&obj_oloc, idx_type, udata->order, (hsize_t)0, NULL, H5G_visit_cb, udata, udata->dxpl_id);
+
+ /* Restore location */
+ udata->curr_loc = old_loc;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+done:
+ /* Reset path back to incoming path */
+ udata->path[old_path_len] = '\0';
+ udata->curr_path_len = old_path_len;
+
+ /* Release resources */
+ if(obj_found && H5G_loc_free(&obj_loc) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_visit_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_visit
+ *
+ * Purpose: Recursively visit all the links in a group and all
+ * the groups that are linked to from that group. Links within
+ * each group are visited according to the order within the
+ * specified index (unless the specified index does not exist for
+ * a particular group, then the "name" index is used).
+ *
+ * NOTE: Each _link_ reachable from the initial group will only be
+ * visited once. However, because an object may be reached from
+ * more than one link, the visitation may call the application's
+ * callback with more than one link that points to a particular
+ * _object_.
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ *
+ *
+ * Programmer: Quincey Koziol
+ * November 4 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, H5L_iterate_t op, void *op_data, hid_t lapl_id,
+ hid_t dxpl_id)
+{
+ H5G_iter_visit_ud_t udata; /* User data for callback */
+ H5O_linfo_t linfo; /* Link info message */
+ hid_t gid = (-1); /* Group ID */
+ H5G_t *grp = NULL; /* Group opened */
+ H5G_loc_t loc; /* Location of group passed in */
+ H5G_loc_t start_loc; /* Location of starting group */
+ H5O_type_t otype; /* Basic object type (group, dataset, etc.) */
+ unsigned rc; /* Reference count of object */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_visit, FAIL)
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+
+ /* Open the group to begin visiting within */
+ if((grp = H5G_open_name(&loc, group_name, lapl_id, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+
+ /* Register an ID for the starting group */
+ if((gid = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+
+ /* Get the location of the starting group */
+ if(H5G_loc(gid, &start_loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+
+ /* Set up user data */
+ udata.gid = gid;
+ udata.curr_loc = &start_loc;
+ udata.lapl_id = lapl_id;
+ udata.dxpl_id = dxpl_id;
+ udata.idx_type = idx_type;
+ udata.order = order;
+ udata.op = op;
+ udata.op_data = op_data;
+
+ /* Allocate space for the path name */
+ if(NULL == (udata.path = H5MM_strdup("")))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate path name buffer")
+ udata.path_buf_size = 1;
+ udata.curr_path_len = 0;
+
+ /* Create skip list to store visited object information */
+ if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, 0.5, (size_t)16)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
+
+ /* Get the group's reference count and type */
+ if(H5O_get_rc_and_type(&grp->oloc, dxpl_id, &rc, &otype) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object info")
+
+ /* If its ref count is > 1, we add it to the list of visited objects */
+ /* (because it could come up again during traversal) */
+ if(rc > 1) {
+ H5_obj_t *obj_pos; /* New object node for visited list */
+
+ /* Allocate new object "position" node */
+ if((obj_pos = H5FL_MALLOC(H5_obj_t)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate object node")
+
+ /* Construct unique "position" for this object */
+ H5F_GET_FILENO(grp->oloc.file, obj_pos->fileno);
+ obj_pos->addr = grp->oloc.addr;
+
+ /* Add to list of visited objects */
+ if(H5SL_insert(udata.visited, obj_pos, obj_pos) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert object node into visited list")
+ } /* end if */
+
+ /* Attempt to get the link info for this group */
+ if(H5G_obj_get_linfo(&(grp->oloc), &linfo, dxpl_id)) {
+ /* Check for creation order tracking, if creation order index lookup requested */
+ if(idx_type == H5_INDEX_CRT_ORDER) {
+ /* Check if creation order is tracked */
+ if(!linfo.track_corder)
+ /* Switch to name order for this group */
+ idx_type = H5_INDEX_NAME;
+ } /* end if */
+ else
+ HDassert(idx_type == H5_INDEX_NAME);
+ } /* end if */
+ else {
+ /* Clear error stack from not finding the link info message */
+ H5E_clear_stack(NULL);
+
+ /* Can only perform name lookups on groups with symbol tables */
+ if(idx_type != H5_INDEX_NAME)
+ /* Switch to name order for this group */
+ idx_type = H5_INDEX_NAME;
+ } /* end if */
+
+ /* Call the link iteration routine */
+ if((ret_value = H5G_obj_iterate(&(grp->oloc), idx_type, order, (hsize_t)0, NULL, H5G_visit_cb, &udata, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't visit links")
+
+done:
+ /* Release user data resources */
+ H5MM_xfree(udata.path);
+ if(udata.visited)
+ H5SL_destroy(udata.visited, H5G_free_visit_visited, NULL);
+
+ /* Release the group opened */
+ if(gid > 0) {
+ if(H5I_dec_ref(gid) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
+ } /* end if */
+ else if(grp && H5G_close(grp) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_visit() */
+
diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c
index 042d29a..b0340a7 100644
--- a/src/H5Gcompact.c
+++ b/src/H5Gcompact.c
@@ -406,9 +406,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_compact_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo,
+H5G_compact_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
- hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data)
+ H5G_lib_iterate_t op, void *op_data)
{
H5G_link_table_t ltable = {0, NULL}; /* Link table */
herr_t ret_value; /* Return value */
@@ -418,14 +418,14 @@ H5G_compact_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Sanity check */
HDassert(oloc);
HDassert(linfo);
- HDassert(lnk_op && lnk_op->u.lib_op);
+ HDassert(op);
/* Build table of all link messages */
if(H5G_compact_build_table(oloc, dxpl_id, linfo, idx_type, order, &ltable) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table")
/* Iterate over links in table */
- if((ret_value = H5G_link_iterate_table(&ltable, skip, last_lnk, gid, lnk_op, op_data)) < 0)
+ if((ret_value = H5G_link_iterate_table(&ltable, skip, last_lnk, op, op_data)) < 0)
HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
done:
diff --git a/src/H5Gdense.c b/src/H5Gdense.c
index 2b7493b..ed53a47 100644
--- a/src/H5Gdense.c
+++ b/src/H5Gdense.c
@@ -90,9 +90,8 @@ typedef struct {
hsize_t count; /* # of links examined */
/* downward (from application) */
- hid_t gid; /* Group ID for application callback */
hsize_t skip; /* Number of links to skip */
- const H5G_link_iterate_t *lnk_op; /* Callback for each link */
+ H5G_lib_iterate_t op; /* Callback for each link */
void *op_data; /* Callback data for each link */
/* upward */
@@ -799,7 +798,6 @@ H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Allocate space for the table entries */
if(ltable->nlinks > 0) {
H5G_dense_bt_ud_t udata; /* User data for iteration callback */
- H5G_link_iterate_t lnk_op; /* Link operator */
/* Allocate the table to store the links */
if((ltable->lnks = H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
@@ -809,12 +807,8 @@ H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
udata.ltable = ltable;
udata.curr_lnk = 0;
- /* Build iterator operator */
- lnk_op.op_type = H5G_LINK_OP_LIB;
- lnk_op.u.lib_op = H5G_dense_build_table_cb;
-
/* Iterate over the links in the group, building a table of the link messages */
- if(H5G_dense_iterate(f, dxpl_id, linfo, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, (hid_t)0, &lnk_op, &udata) < 0)
+ if(H5G_dense_iterate(f, dxpl_id, linfo, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, H5G_dense_build_table_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links")
/* Sort link table in correct iteration order */
@@ -904,32 +898,8 @@ H5G_dense_iterate_bt2_cb(const void *_record, void *_bt2_udata)
H5G_dense_iterate_fh_cb, &fh_udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPERATE, H5_ITER_ERROR, "heap op callback failed")
- /* Check which type of callback to make */
- switch(bt2_udata->lnk_op->op_type) {
-#ifndef H5_NO_DEPRECATED_SYMBOLS
- case H5G_LINK_OP_OLD:
- /* Make the old-type application callback */
- ret_value = (bt2_udata->lnk_op->u.old_op)(bt2_udata->gid, fh_udata.lnk->name, bt2_udata->op_data);
- break;
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
-
- case H5G_LINK_OP_APP:
- {
- H5L_info_t info; /* Link info */
-
- /* Retrieve the info for the link */
- if(H5G_link_to_info(fh_udata.lnk, &info) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for link")
-
- /* Make the application callback */
- ret_value = (bt2_udata->lnk_op->u.app_op)(bt2_udata->gid, fh_udata.lnk->name, &info, bt2_udata->op_data);
- }
- break;
-
- case H5G_LINK_OP_LIB:
- /* Call the library's callback */
- ret_value = (bt2_udata->lnk_op->u.lib_op)(fh_udata.lnk, bt2_udata->op_data);
- } /* end switch */
+ /* Make the callback */
+ ret_value = (bt2_udata->op)(fh_udata.lnk, bt2_udata->op_data);
/* Release the space allocated for the link */
H5O_msg_free(H5O_LINK_ID, fh_udata.lnk);
@@ -964,7 +934,7 @@ done:
herr_t
H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
- hid_t gid, const H5G_link_iterate_t *lnk_op, void *op_data)
+ H5G_lib_iterate_t op, void *op_data)
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5G_link_table_t ltable = {0, NULL}; /* Table of links */
@@ -979,7 +949,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
*/
HDassert(f);
HDassert(linfo);
- HDassert(lnk_op && lnk_op->u.lib_op);
+ HDassert(op);
/* Determine the address of the index to use */
if(idx_type == H5_INDEX_NAME) {
@@ -1018,10 +988,9 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
udata.f = f;
udata.dxpl_id = dxpl_id;
udata.fheap = fheap;
- udata.gid = gid;
udata.skip = skip;
udata.count = 0;
- udata.lnk_op = lnk_op;
+ udata.op = op;
udata.op_data = op_data;
/* Iterate over the records in the v2 B-tree's "native" order */
@@ -1039,7 +1008,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "error building table of links")
/* Iterate over links in table */
- if((ret_value = H5G_link_iterate_table(&ltable, skip, last_lnk, gid, lnk_op, op_data)) < 0)
+ if((ret_value = H5G_link_iterate_table(&ltable, skip, last_lnk, op, op_data)) < 0)
HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
} /* end else */
diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c
index bc635be..ffcc0e5 100644
--- a/src/H5Gdeprec.c
+++ b/src/H5Gdeprec.c
@@ -771,10 +771,10 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op,
/* Build link operator info */
lnk_op.op_type = H5G_LINK_OP_OLD;
- lnk_op.u.old_op = op;
+ lnk_op.op_func.op_old = op;
/* Call private function. */
- if((ret_value = H5G_obj_iterate(loc_id, name, H5_INDEX_NAME, H5_ITER_INC, idx, &last_obj, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
+ if((ret_value = H5G_iterate(loc_id, name, H5_INDEX_NAME, H5_ITER_INC, idx, &last_obj, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed")
/* Set the index we stopped at */
diff --git a/src/H5Glink.c b/src/H5Glink.c
index 7292245..75a3e83 100644
--- a/src/H5Glink.c
+++ b/src/H5Glink.c
@@ -603,7 +603,7 @@ H5G_link_sort_table(H5G_link_table_t *ltable, H5_index_t idx_type,
*/
herr_t
H5G_link_iterate_table(const H5G_link_table_t *ltable, hsize_t skip,
- hsize_t *last_lnk, hid_t gid, const H5G_link_iterate_t *lnk_op, void *op_data)
+ hsize_t *last_lnk, const H5G_lib_iterate_t op, void *op_data)
{
size_t u; /* Local index variable */
herr_t ret_value = H5_ITER_CONT; /* Return value */
@@ -612,7 +612,7 @@ H5G_link_iterate_table(const H5G_link_table_t *ltable, hsize_t skip,
/* Sanity check */
HDassert(ltable);
- HDassert(lnk_op);
+ HDassert(op);
/* Skip over links, if requested */
if(last_lnk)
@@ -621,32 +621,8 @@ H5G_link_iterate_table(const H5G_link_table_t *ltable, hsize_t skip,
/* Iterate over link messages */
H5_ASSIGN_OVERFLOW(/* To: */ u, /* From: */ skip, /* From: */ hsize_t, /* To: */ size_t)
for(; u < ltable->nlinks && !ret_value; u++) {
- /* Check which kind of callback to make */
- switch(lnk_op->op_type) {
-#ifndef H5_NO_DEPRECATED_SYMBOLS
- case H5G_LINK_OP_OLD:
- /* Make the old-type application callback */
- ret_value = (lnk_op->u.old_op)(gid, ltable->lnks[u].name, op_data);
- break;
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
-
- case H5G_LINK_OP_APP:
- {
- H5L_info_t info; /* Link info */
-
- /* Retrieve the info for the link */
- if(H5G_link_to_info(&(ltable->lnks[u]), &info) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for link")
-
- /* Make the application callback */
- ret_value = (lnk_op->u.app_op)(gid, ltable->lnks[u].name, &info, op_data);
- }
- break;
-
- case H5G_LINK_OP_LIB:
- /* Call the library's callback */
- ret_value = (lnk_op->u.lib_op)(&(ltable->lnks[u]), op_data);
- } /* end switch */
+ /* Make the callback */
+ ret_value = (op)(&(ltable->lnks[u]), op_data);
/* Increment the number of entries passed through */
if(last_lnk)
@@ -657,7 +633,6 @@ H5G_link_iterate_table(const H5G_link_table_t *ltable, hsize_t skip,
if(ret_value < 0)
HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_link_iterate_table() */
diff --git a/src/H5Gname.c b/src/H5Gname.c
index e341ee7..bde9e23 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -50,21 +50,15 @@ typedef struct H5G_names_t {
} H5G_names_t;
/* Info to pass to the iteration function when building name */
-typedef struct H5G_ref_path_iter_t {
+typedef struct H5G_gnba_iter_t {
/* In */
- hid_t file; /* File id where it came from */
+ const H5O_loc_t *loc; /* The location of the object we're looking for */
hid_t lapl_id; /* LAPL for operations */
hid_t dxpl_id; /* DXPL for operations */
- hbool_t is_root_group; /* Flag to indicate that the root group is being looked at */
- const H5O_loc_t *loc; /* The location of the object we're looking for */
-
- /* In/Out */
- H5SL_t *ref_path_table; /* Skip list for tracking visited nodes */
- size_t max_container_len; /* Maximum size of container */
/* Out */
- char *container; /* full name of the container object */
-} H5G_ref_path_iter_t;
+ char *path; /* Name of the object */
+} H5G_gnba_iter_t;
/* Private macros */
@@ -85,9 +79,6 @@ static H5RS_str_t *H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r,
static herr_t H5G_name_move_path(H5RS_str_t **path_r_ptr,
const char *full_suffix, const char *src_path, const char *dst_path);
static int H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key);
-static herr_t H5G_refname_iterator(hid_t group, const char *name,
- const H5L_info_t *link_info, void *_udata);
-static herr_t H5G_free_ref_path_node(void *item, void *key, void *operator_data/*in,out*/);
/*-------------------------------------------------------------------------
@@ -468,7 +459,7 @@ H5G_get_name(hid_t id, char *name/*out*/, size_t size, hid_t lapl_id,
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve file ID")
/* Search for name of object */
- if((len = H5G_get_refobj_name(file, lapl_id, dxpl_id, loc.oloc, name, size)) < 0) {
+ if((len = H5G_get_name_by_addr(file, lapl_id, dxpl_id, loc.oloc, name, size)) < 0) {
H5I_dec_ref(file);
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name")
} /* end if */
@@ -1039,222 +1030,139 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_refname_iterator
+ * Function: H5G_get_name_by_addr_cb
*
- * Purpose: The iterator which traverses all objects in a file looking for
- * one that matches the object that is being looked for.
+ * Purpose: Callback for retrieving object's name by address
*
- * Return: 1 on success, 0 to continue searching, negative on failure.
- *
- * Programmer: Leon Arber, Nov 1, 2006.
+ * Return: Positive if path is for object desired
+ * 0 if not correct object
+ * negative on failure.
*
- * Modifications:
- * Quincey Koziol, Nov. 3, 2006
- * Cleaned up code.
+ * Programmer: Quincey Koziol
+ * November 4 2007
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_refname_iterator(hid_t group, const char *name, const H5L_info_t *link_info,
+H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info_t *linfo,
void *_udata)
{
- H5G_ref_path_iter_t *udata = (H5G_ref_path_iter_t*)_udata;
- herr_t ret_value = H5_ITER_CONT; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_refname_iterator)
-
- /* We only care about hard links */
- if(link_info->type == H5L_TYPE_HARD) {
- H5G_loc_t loc; /* Group location of parent */
-
- /* Look up group's location */
- if(H5G_loc(group, &loc) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "not a location")
-
- /* Check for finding the object */
- /* (checks against the file in the location as well, to make certain that
- * the correct object is found in a mounted file hierarchy)
- */
- if(udata->loc->addr == link_info->u.address && udata->loc->file == loc.oloc->file) {
- size_t len_needed; /* Length of container string needed */
-
- /* Build the object's full name */
- len_needed = HDstrlen(udata->container) + HDstrlen(name) + 2;
- if(len_needed > udata->max_container_len) {
- void *new_container; /* Pointer to new container */
-
- if(NULL == (new_container = H5MM_realloc(udata->container, len_needed)))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string")
- udata->container = new_container;
- udata->max_container_len = len_needed;
- } /* end if */
- HDstrcat(udata->container, name);
+ H5G_gnba_iter_t *udata = (H5G_gnba_iter_t *)_udata; /* User data for iteration */
+ H5G_loc_t obj_loc; /* Location of object */
+ H5G_name_t obj_path; /* Object's group hier. path */
+ H5O_loc_t obj_oloc; /* Object's object location */
+ hbool_t obj_found = FALSE; /* Object at 'path' found */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
- /* We found a match so we return immediately */
- HGOTO_DONE(H5_ITER_STOP)
- } /* end if */
- else {
- H5O_info_t oinfo; /* Object information */
- H5O_loc_t tmp_oloc; /* Temporary object location */
+ FUNC_ENTER_NOAPI_NOINIT(H5G_get_name_by_addr_cb)
- /* Check if we've seen this object before */
- if(H5SL_search(udata->ref_path_table, &link_info->u.address))
- HGOTO_DONE(H5_ITER_CONT)
+ /* Sanity check */
+ HDassert(path);
+ HDassert(linfo);
+ HDassert(udata->loc);
+ HDassert(udata->path == NULL);
- /* Go retrieve the object information */
- tmp_oloc.file = loc.oloc->file;
- tmp_oloc.addr = link_info->u.address;
- if(H5O_get_info(&tmp_oloc, udata->dxpl_id, FALSE, &oinfo) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "unable to get object info")
+ /* Check for hard link with correct address */
+ if(linfo->type == H5L_TYPE_HARD && udata->loc->addr == linfo->u.address) {
+ H5G_loc_t grp_loc; /* Location of group */
- /* If its ref count is > 1, we add it to the list of visited objects */
- if(oinfo.rc > 1) {
- haddr_t *new_node; /* New path node for table */
+ /* Get group's location */
+ if(H5G_loc(gid, &grp_loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "bad group location")
- /* Allocate new path node */
- if((new_node = H5FL_MALLOC(haddr_t)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path node")
+ /* Set up opened object location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
- /* Set node information */
- *new_node = link_info->u.address;
+ /* Find the object */
+ if(H5G_loc_find(&grp_loc, path, &obj_loc/*out*/, udata->lapl_id, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5_ITER_ERROR, "object not found")
+ obj_found = TRUE;
- /* Insert into skip list */
- if(H5SL_insert(udata->ref_path_table, new_node, new_node) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert path node into table")
- } /* end if */
+ /* Check for object in same file (handles mounted files) */
+ /* (re-verify address, in case we traversed a file mount) */
+ if(udata->loc->addr == obj_loc.oloc->addr && udata->loc->file == obj_loc.oloc->file) {
+ udata->path = H5MM_strdup(path);
- /* If it's a group, we recurse into it */
- if(oinfo.type == H5O_TYPE_GROUP) {
- H5G_link_iterate_t lnk_op; /* Link operator */
- hsize_t last_obj;
- size_t len_needed; /* Length of container string needed */
- size_t len;
-
- /* Build full path name of group to recurse into */
- len = HDstrlen(udata->container);
- len_needed = len + HDstrlen(name) + 2;
- if(len_needed > udata->max_container_len) {
- void *new_container; /* Pointer to new container */
-
- if(NULL == (new_container = H5MM_realloc(udata->container, len_needed)))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string")
- udata->container = new_container;
- udata->max_container_len = len_needed;
- } /* end if */
- if(!udata->is_root_group)
- HDstrcat(udata->container, name);
- else
- udata->is_root_group = FALSE;
- HDstrcat(udata->container, "/");
-
- /* Build iterator operator */
- lnk_op.op_type = H5G_LINK_OP_APP;
- lnk_op.u.app_op = H5G_refname_iterator;
-
- ret_value = H5G_obj_iterate(udata->file, udata->container, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, &last_obj, &lnk_op, udata, udata->lapl_id, udata->dxpl_id);
-
- /* If we didn't find the object, truncate the name to not include group name anymore */
- if(!ret_value)
- udata->container[len] = '\0';
- } /* end if */
- } /* end else */
+ /* We found a match so we return immediately */
+ HGOTO_DONE(H5_ITER_STOP)
+ } /* end if */
} /* end if */
+
+done:
+ if(obj_found && H5G_loc_free(&obj_loc) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location")
-done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_refname_iterator() */
+} /* end H5G_get_name_by_addr_cb() */
/*-------------------------------------------------------------------------
- * Function: H5G_free_ref_path_node
- *
- * Purpose: Free the key for a reference path table node
- *
- * Return: Non-negative on success, negative on failure
+ * Function: H5G_get_name_by_addr
*
- * Programmer: Quincey Koziol
- *
- * Modifications:
- * Leon Arber, Oct. 25, 2006. Moved into H5G from h5ls
- * tools lib for looking up path to reference.
- *
- * Quincey Koziol, Nov. 3, 2006
- * Cleaned up code.
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_free_ref_path_node(void *item, void UNUSED *key, void UNUSED *operator_data/*in,out*/)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_free_ref_path_node)
-
- H5FL_FREE(haddr_t, item);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5G_free_ref_path_node() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_get_refobj_name
- *
- * Purpose: Tries to figure out the path to a reference.
+ * Purpose: Tries to figure out the path to an object from it's address
*
* Return: returns size of path name, and copies it into buffer
* pointed to by name if that buffer is big enough.
* 0 if it cannot find the path
* negative on failure.
*
- * Programmer: Leon Arber, Nov 1, 2006.
- *
- * Modifications:
- * Quincey Koziol, Nov. 3, 2006
- * Cleaned up code.
+ * Programmer: Quincey Koziol
+ * November 4 2007
*
*-------------------------------------------------------------------------
*/
ssize_t
-H5G_get_refobj_name(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t *loc,
+H5G_get_name_by_addr(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t *loc,
char *name, size_t size)
{
- H5G_ref_path_iter_t udata; /* User data for iteration */
- H5G_loc_t root_loc; /* Root location */
- H5L_info_t root_info; /* Link info for root group */
+ H5G_gnba_iter_t udata; /* User data for iteration */
+ H5G_loc_t root_loc; /* Root group's location */
+ hbool_t found_obj = FALSE; /* If we found the object */
herr_t status; /* Status from iteration */
ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5G_get_refobj_name, FAIL)
+ FUNC_ENTER_NOAPI(H5G_get_name_by_addr, FAIL)
- /* Construct the link info for the root group */
+ /* Construct the link info for the file's root group */
if(H5G_loc(file, &root_loc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get root group's location")
- HDmemset(&root_info, 0, sizeof(root_info));
- root_info.type = H5L_TYPE_HARD;
- root_info.u.address = root_loc.oloc->addr;
-
- /* Set up user data for iterator */
- udata.file = file;
- udata.lapl_id = lapl_id;
- udata.dxpl_id = dxpl_id;
- udata.is_root_group = TRUE;
- if(NULL == (udata.container = H5MM_strdup("")))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate root group name")
- udata.max_container_len = 1;
- udata.loc = loc;
-
- /* Create skip list to store reference path information */
- if((udata.ref_path_table = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for path nodes")
-
- /* Iterate over all the objects in the file */
- if((status = H5G_refname_iterator(file, "/", &root_info, &udata)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed while looking for object name")
- else if(status > 0) {
+
+ /* Check for root group being the object looked for */
+ if(root_loc.oloc->addr == loc->addr && root_loc.oloc->file == loc->file) {
+ udata.path = H5MM_strdup("");
+ found_obj = TRUE;
+ } /* end if */
+ else {
+ /* Set up user data for iterator */
+ udata.loc = loc;
+ udata.lapl_id = lapl_id;
+ udata.dxpl_id = dxpl_id;
+ udata.path = NULL;
+
+ /* Visit all the links in the file */
+ if((status = H5G_visit(file, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G_get_name_by_addr_cb, &udata, lapl_id, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group traversal failed while looking for object name")
+ else if(status > 0)
+ found_obj = TRUE;
+ } /* end else */
+
+ /* Check for finding the object */
+ if(found_obj) {
+ size_t full_path_len = HDstrlen(udata.path) + 1; /* Length of path + 1 (for "/") */
+
/* Set the length of the full path */
- ret_value = HDstrlen(udata.container);
+ ret_value = full_path_len;
/* If there's a buffer provided, copy into it, up to the limit of its size */
if(name) {
- HDstrncpy(name, udata.container, size);
+ /* Copy the initial path separator */
+ HDstrcpy(name, "/");
+
+ /* Append the rest of the path */
+ /* (less one character, for the initial path separator) */
+ HDstrncat(name, udata.path, (size - 1));
if((size_t)ret_value >= size)
name[size - 1] = '\0';
} /* end if */
@@ -1264,10 +1172,8 @@ H5G_get_refobj_name(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t *l
done:
/* Release resources */
- H5MM_xfree(udata.container);
- if(udata.ref_path_table)
- H5SL_destroy(udata.ref_path_table, H5G_free_ref_path_node, NULL);
+ H5MM_xfree(udata.path);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_get_refobj_name() */
+} /* end H5G_get_name_by_addr() */
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 442cbf2..86585a0 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -1275,51 +1275,23 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad
if(udata->skip > 0)
--udata->skip;
else {
- const char *name; /* Pointer to link name in heap */
+ H5O_link_t lnk; /* Link for entry */
+ const char *name; /* Pointer to link name in heap */
/* Get the pointer to the name of the link in the heap */
name = H5HL_offset_into(f, udata->heap, ents[u].name_off);
HDassert(name);
- /* Check which type of callback to make */
- switch(udata->lnk_op->op_type) {
-#ifndef H5_NO_DEPRECATED_SYMBOLS
- case H5G_LINK_OP_OLD:
- /* Make the old-type application callback */
- ret_value = (udata->lnk_op->u.old_op)(udata->group_id, name, udata->op_data);
- break;
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
-
- case H5G_LINK_OP_APP:
- {
- H5L_info_t info; /* Link info for entry */
-
- /* Make a link info for an entry */
- if(H5G_ent_to_info(f, &info, udata->heap, &ents[u]) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get info for symbol table entry")
-
- /* Make the application callback */
- ret_value = (udata->lnk_op->u.app_op)(udata->group_id, name, &info, udata->op_data);
- }
- break;
-
- case H5G_LINK_OP_LIB:
- /* Call the library's callback */
- {
- H5O_link_t lnk; /* Link for entry */
-
- /* Convert the entry to a link */
- if(H5G_ent_to_link(f, &lnk, udata->heap, &ents[u], name) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5_ITER_ERROR, "unable to convert symbol table entry to link")
-
- /* Call the library's callback */
- ret_value = (udata->lnk_op->u.lib_op)(&lnk, udata->op_data);
-
- /* Release memory for link object */
- if(H5O_msg_reset(H5O_LINK_ID, &lnk) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, H5_ITER_ERROR, "unable to release link message")
- }
- } /* end switch */
+ /* Convert the entry to a link */
+ if(H5G_ent_to_link(f, &lnk, udata->heap, &ents[u], name) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5_ITER_ERROR, "unable to convert symbol table entry to link")
+
+ /* Make the callback */
+ ret_value = (udata->op)(&lnk, udata->op_data);
+
+ /* Release memory for link object */
+ if(H5O_msg_reset(H5O_LINK_ID, &lnk) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, H5_ITER_ERROR, "unable to release link message")
} /* end else */
/* Increment the number of entries passed through */
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 00bac73..8ca8c52 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -533,7 +533,6 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
H5O_linfo_t new_linfo = H5G_CRT_LINK_INFO_DEF; /* Link information */
H5O_ginfo_t new_ginfo = H5G_CRT_GROUP_INFO_DEF; /* Group information */
H5G_obj_stab_it_ud1_t udata; /* User data for iteration */
- H5G_link_iterate_t lnk_op; /* Link operator */
/* Convert group to "new format" group, in order to hold the information */
@@ -549,12 +548,8 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
udata.grp_oloc = grp_oloc;
udata.dxpl_id = dxpl_id;
- /* Build iterator operator */
- lnk_op.op_type = H5G_LINK_OP_LIB;
- lnk_op.u.lib_op = H5G_obj_stab_to_new_cb;
-
/* Iterate through all links in "old format" group and insert them into new format */
- if(H5G_stab_iterate(grp_oloc, dxpl_id, H5_ITER_NATIVE, (hsize_t)0, NULL, (hid_t)0, &lnk_op, &udata) < 0)
+ if(H5G_stab_iterate(grp_oloc, dxpl_id, H5_ITER_NATIVE, (hsize_t)0, NULL, H5G_obj_stab_to_new_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over old format links")
/* Remove the symbol table message from the group */
@@ -636,36 +631,21 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_obj_iterate(hid_t loc_id, const char *group_name,
+H5G_obj_iterate(const H5O_loc_t *grp_oloc,
H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
- H5G_link_iterate_t *lnk_op, void *op_data, hid_t lapl_id, hid_t dxpl_id)
+ H5G_lib_iterate_t op, void *op_data, hid_t dxpl_id)
{
- H5G_loc_t loc; /* Location of parent for group */
H5O_linfo_t linfo; /* Link info message */
- hid_t gid = -1; /* ID of group to iterate over */
- H5G_t *grp; /* Pointer to group data structure to iterate over */
herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_iterate, FAIL)
/* Sanity check */
- HDassert(group_name);
- HDassert(last_lnk);
- HDassert(lnk_op && lnk_op->u.lib_op);
-
- /*
- * Open the group on which to operate. We also create a group ID which
- * we can pass to the application-defined operator.
- */
- if(H5G_loc(loc_id, &loc) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if(NULL == (grp = H5G_open_name(&loc, group_name, lapl_id, dxpl_id)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
- if((gid = H5I_register(H5I_GROUP, grp)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+ HDassert(grp_oloc);
+ HDassert(op);
/* Attempt to get the link info for this group */
- if(H5G_obj_get_linfo(&(grp->oloc), &linfo, dxpl_id)) {
+ if(H5G_obj_get_linfo(grp_oloc, &linfo, dxpl_id)) {
/* Check for going out of bounds */
if(skip > 0 && (size_t)skip >= linfo.nlinks)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound")
@@ -679,13 +659,13 @@ H5G_obj_iterate(hid_t loc_id, const char *group_name,
if(H5F_addr_defined(linfo.fheap_addr)) {
/* Iterate over the links in the group, building a table of the link messages */
- if((ret_value = H5G_dense_iterate(grp->oloc.file, dxpl_id, &linfo, idx_type, order, skip, last_lnk, gid, lnk_op, op_data)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links")
+ if((ret_value = H5G_dense_iterate(grp_oloc->file, dxpl_id, &linfo, idx_type, order, skip, last_lnk, op, op_data)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over dense links")
} /* end if */
else {
/* Get the object's name from the link messages */
- if((ret_value = H5G_compact_iterate(&(grp->oloc), dxpl_id, &linfo, idx_type, order, skip, last_lnk, gid, lnk_op, op_data)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over links")
+ if((ret_value = H5G_compact_iterate(grp_oloc, dxpl_id, &linfo, idx_type, order, skip, last_lnk, op, op_data)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over compact links")
} /* end else */
} /* end if */
else {
@@ -697,14 +677,11 @@ H5G_obj_iterate(hid_t loc_id, const char *group_name,
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query")
/* Iterate over symbol table */
- if((ret_value = H5G_stab_iterate(&(grp->oloc), dxpl_id, order, skip, last_lnk, gid, lnk_op, op_data)) < 0)
+ if((ret_value = H5G_stab_iterate(grp_oloc, dxpl_id, order, skip, last_lnk, op, op_data)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over symbol table")
} /* end else */
done:
- if(gid > 0)
- H5I_dec_ref(gid); /*also closes 'grp'*/
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_obj_iterate() */
@@ -904,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/H5Gpkg.h b/src/H5Gpkg.h
index cc017b9..53692c5 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -132,18 +132,16 @@ typedef herr_t (*H5G_lib_iterate_t)(const H5O_link_t *lnk, void *op_data);
typedef struct {
enum {
#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5G_LINK_OP_OLD, /* Old application callback */
+ H5G_LINK_OP_OLD, /* "Old" application callback */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5G_LINK_OP_APP, /* Application callback */
- H5G_LINK_OP_LIB /* Library internal callback */
+ H5G_LINK_OP_NEW /* "New" application callback */
} op_type;
union {
#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5G_iterate_t old_op; /* Old application callback for each link */
+ H5G_iterate_t op_old; /* "Old" application callback for each link */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5L_iterate_t app_op; /* Application callback for each link */
- H5G_lib_iterate_t lib_op; /* Library internal callback for each link */
- } u;
+ H5L_iterate_t op_new; /* "New" application callback for each link */
+ } op_func;
} H5G_link_iterate_t;
/* Data structure to hold table of links for a group */
@@ -208,10 +206,9 @@ typedef struct H5G_bt_lkp_t {
*/
typedef struct H5G_bt_it_it_t {
/* downward */
- hid_t group_id; /*group id to pass to iteration operator */
H5HL_t *heap; /*symbol table heap */
hsize_t skip; /*initial entries to skip */
- H5G_link_iterate_t *lnk_op; /*iteration operator */
+ H5G_lib_iterate_t op; /*iteration operator */
void *op_data; /*user-defined operator data */
/* upward */
@@ -337,6 +334,9 @@ H5_DLL H5G_t *H5G_create_named(const H5G_loc_t *loc, const char *name,
hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id);
H5_DLL H5G_t *H5G_open_name(const H5G_loc_t *loc, const char *name,
hid_t gapl_id, hid_t dxpl_id);
+H5_DLL herr_t H5G_iterate(hid_t loc_id, const char *group_name,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
+ const H5G_link_iterate_t *lnk_op, void *op_data, hid_t lapl_id, hid_t dxpl_id);
/*
* Group hierarchy traversal routines
@@ -369,9 +369,8 @@ H5_DLL herr_t H5G_stab_insert(const H5O_loc_t *grp_oloc, const char *name,
H5_DLL herr_t H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name,
H5O_link_t *obj_lnk, hid_t dxpl_id);
H5_DLL herr_t H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab);
-H5_DLL herr_t H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id,
- H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, hid_t gid,
- H5G_link_iterate_t *lnk_op, void *op_data);
+H5_DLL herr_t H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
+ hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G_stab_count(struct H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id);
H5_DLL herr_t H5G_stab_bh_size(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab,
H5_ih_info_t *bh_info);
@@ -439,8 +438,7 @@ H5_DLL herr_t H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id,
H5_DLL herr_t H5G_link_sort_table(H5G_link_table_t *ltable, H5_index_t idx_type,
H5_iter_order_t order);
H5_DLL herr_t H5G_link_iterate_table(const H5G_link_table_t *ltable,
- hsize_t skip, hsize_t *last_lnk, hid_t gid, const H5G_link_iterate_t *lnk_op,
- void *op_data);
+ hsize_t skip, hsize_t *last_lnk, const H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G_link_release_table(H5G_link_table_t *ltable);
H5_DLL herr_t H5G_link_name_replace(H5F_t *file, hid_t dxpl_id,
H5RS_str_t *grp_full_path_r, const H5O_link_t *lnk);
@@ -456,9 +454,9 @@ H5_DLL herr_t H5G_compact_remove(const H5O_loc_t *oloc, hid_t dxpl_id,
H5_DLL herr_t H5G_compact_remove_by_idx(const H5O_loc_t *oloc, hid_t dxpl_id,
const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n);
-H5_DLL herr_t H5G_compact_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
- hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data);
+H5_DLL herr_t H5G_compact_iterate(const H5O_loc_t *oloc, hid_t dxpl_id,
+ const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G_compact_lookup(H5O_loc_t *grp_oloc, const char *name,
H5O_link_t *lnk, hid_t dxpl_id);
H5_DLL herr_t H5G_compact_lookup_by_idx(H5O_loc_t *oloc, hid_t dxpl_id,
@@ -482,7 +480,7 @@ H5_DLL herr_t H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id,
hsize_t n, H5O_link_t *lnk);
H5_DLL herr_t H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
- hid_t gid, const H5G_link_iterate_t *lnk_op, void *op_data);
+ H5G_lib_iterate_t op, void *op_data);
H5_DLL ssize_t H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id,
H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
char *name, size_t size);
@@ -505,9 +503,9 @@ H5_DLL H5O_linfo_t * H5G_obj_get_linfo(const H5O_loc_t *grp_oloc,
H5O_linfo_t *linfo, hid_t dxpl_id);
H5_DLL herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name,
H5O_link_t *obj_lnk, hbool_t adj_link, hid_t dxpl_id);
-H5_DLL herr_t H5G_obj_iterate(hid_t loc_id, const char *group_name,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_obj,
- H5G_link_iterate_t *lnk_op, void *op_data, hid_t lapl_id, hid_t dxpl_id);
+H5_DLL herr_t H5G_obj_iterate(const H5O_loc_t *grp_oloc,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
+ H5G_lib_iterate_t op, void *op_data, hid_t dxpl_id);
H5_DLL herr_t H5G_obj_info(H5O_loc_t *oloc, H5G_info_t *grp_info, hid_t dxpl_id);
H5_DLL ssize_t H5G_obj_get_name_by_idx(H5O_loc_t *oloc, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, char* name, size_t size, hid_t dxpl_id);
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 9717b77..c54f11d 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -162,6 +162,9 @@ H5_DLL herr_t H5G_unmount(H5G_t *grp);
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL H5G_obj_t H5G_map_obj_type(H5O_type_t obj_type);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
+H5_DLL herr_t H5G_visit(hid_t loc_id, const char *group_name,
+ H5_index_t idx_type, H5_iter_order_t order, H5L_iterate_t op, void *op_data,
+ hid_t lapl_id, hid_t dxpl_id);
/*
* These functions operate on symbol table nodes.
@@ -189,7 +192,7 @@ H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_dept
H5_DLL herr_t H5G_name_free(H5G_name_t *name);
H5_DLL ssize_t H5G_get_name(hid_t id, char *name/*out*/, size_t size,
hid_t lapl_id, hid_t dxpl_id);
-H5_DLL ssize_t H5G_get_refobj_name(hid_t fid, hid_t lapl_id, hid_t dxpl_id,
+H5_DLL ssize_t H5G_get_name_by_addr(hid_t fid, hid_t lapl_id, hid_t dxpl_id,
const struct H5O_loc_t *loc, char* name, size_t size);
/*
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index 1887943..61af068 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -484,8 +484,7 @@ done:
*/
herr_t
H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
- hsize_t skip, hsize_t *last_lnk, hid_t gid,
- H5G_link_iterate_t *lnk_op, void *op_data)
+ hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data)
{
H5HL_t *heap = NULL; /* Local heap for group */
H5O_stab_t stab; /* Info about symbol table */
@@ -496,7 +495,7 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
/* Sanity check */
HDassert(oloc);
- HDassert(lnk_op && lnk_op->u.app_op);
+ HDassert(op);
/* Get the B-tree info */
if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id))
@@ -512,11 +511,10 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
H5G_bt_it_it_t udata; /* User data to pass to B-tree callback */
/* Build udata to pass through H5B_iterate() to H5G_node_iterate() */
- udata.group_id = gid;
udata.heap = heap;
udata.skip = skip;
udata.final_ent = last_lnk;
- udata.lnk_op = lnk_op;
+ udata.op = op;
udata.op_data = op_data;
/* Iterate over the group members */
@@ -550,7 +548,7 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
HGOTO_ERROR(H5E_SYM, H5E_CANTSORT, FAIL, "error sorting link messages")
/* Iterate over links in table */
- if((ret_value = H5G_link_iterate_table(&ltable, skip, last_lnk, gid, lnk_op, op_data)) < 0)
+ if((ret_value = H5G_link_iterate_table(&ltable, skip, last_lnk, op, op_data)) < 0)
HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
} /* end else */
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index 3a7288f..bbbe26f 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -394,7 +394,6 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
H5HF_direct_t *dblock = NULL; /* Fractal heap direct block info */
- H5HF_debug_iter_ud1_t udata; /* User data for callbacks */
size_t blk_prefix_size; /* Size of prefix for block */
size_t amount_free; /* Amount of free space in block */
uint8_t *marker = NULL; /* Track free space for block */
@@ -450,36 +449,43 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Initialize the free space information for the heap */
- if(H5HF_space_start(hdr, dxpl_id) < 0)
+ if(H5HF_space_start(hdr, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
- /* Prepare user data for section iteration callback */
- udata.stream = stream;
- udata.indent = indent;
- udata.fwidth = fwidth;
- udata.dblock_addr = dblock->block_off;
- udata.dblock_size = block_size;
- udata.marker = marker;
- udata.sect_count = 0;
- udata.amount_free = 0;
-
- /* Print header */
- HDfprintf(stream, "%*sFree Blocks (offset, size):\n", indent, "");
-
- /* Iterate over the free space sections, to detect overlaps with this block */
- if(H5FS_sect_iterate(f, dxpl_id, hdr->fspace, H5HF_dblock_debug_cb, &udata) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
-
- /* Close the free space information */
- if(H5HF_space_close(hdr, dxpl_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
-
- /* Keep the amount of space free */
- amount_free = udata.amount_free;
-
- /* Check for no free space */
- if(amount_free == 0)
- HDfprintf(stream, "%*s<none>\n", indent + 3, "");
+ /* If there is a free space manager for the heap, check for sections that overlap this block */
+ if(hdr->fspace) {
+ H5HF_debug_iter_ud1_t udata; /* User data for callbacks */
+
+ /* Prepare user data for section iteration callback */
+ udata.stream = stream;
+ udata.indent = indent;
+ udata.fwidth = fwidth;
+ udata.dblock_addr = dblock->block_off;
+ udata.dblock_size = block_size;
+ udata.marker = marker;
+ udata.sect_count = 0;
+ udata.amount_free = 0;
+
+ /* Print header */
+ HDfprintf(stream, "%*sFree Blocks (offset, size):\n", indent, "");
+
+ /* Iterate over the free space sections, to detect overlaps with this block */
+ if(H5FS_sect_iterate(f, dxpl_id, hdr->fspace, H5HF_dblock_debug_cb, &udata) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
+
+ /* Close the free space information */
+ if(H5HF_space_close(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
+
+ /* Keep the amount of space free */
+ amount_free = udata.amount_free;
+
+ /* Check for no free space */
+ if(amount_free == 0)
+ HDfprintf(stream, "%*s<none>\n", indent + 3, "");
+ } /* end if */
+ else
+ amount_free = 0;
HDfprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth,
"Percent of available space for data used:",
@@ -709,7 +715,6 @@ H5HF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr,
FILE *stream, int indent, int fwidth)
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
- H5HF_debug_iter_ud2_t udata; /* User data for callbacks */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_sects_debug, FAIL)
@@ -730,22 +735,27 @@ H5HF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr,
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/* Initialize the free space information for the heap */
- if(H5HF_space_start(hdr, dxpl_id) < 0)
+ if(H5HF_space_start(hdr, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
- /* Prepare user data for section iteration callback */
- udata.fspace = hdr->fspace;
- udata.stream = stream;
- udata.indent = indent;
- udata.fwidth = fwidth;
+ /* If there is a free space manager for the heap, iterate over them */
+ if(hdr->fspace) {
+ H5HF_debug_iter_ud2_t udata; /* User data for callbacks */
- /* Iterate over all the free space sections */
- if(H5FS_sect_iterate(f, dxpl_id, hdr->fspace, H5HF_sects_debug_cb, &udata) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
+ /* Prepare user data for section iteration callback */
+ udata.fspace = hdr->fspace;
+ udata.stream = stream;
+ udata.indent = indent;
+ udata.fwidth = fwidth;
- /* Close the free space information */
- if(H5HF_space_close(hdr, dxpl_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
+ /* Iterate over all the free space sections */
+ if(H5FS_sect_iterate(f, dxpl_id, hdr->fspace, H5HF_sects_debug_cb, &udata) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
+
+ /* Close the free space information */
+ if(H5HF_space_close(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
+ } /* end if */
done:
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 461cba7..702ce08 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -692,7 +692,7 @@ H5_DLL herr_t H5HF_man_iter_offset(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter,
H5_DLL hbool_t H5HF_man_iter_ready(H5HF_block_iter_t *biter);
/* Free space manipulation routines */
-H5_DLL herr_t H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id);
+H5_DLL herr_t H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t may_create);
H5_DLL herr_t H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *node, unsigned flags);
H5_DLL htri_t H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request,
diff --git a/src/H5HFspace.c b/src/H5HFspace.c
index 16eae51..77d8b1b 100644
--- a/src/H5HFspace.c
+++ b/src/H5HFspace.c
@@ -94,7 +94,7 @@
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id)
+H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t may_create)
{
const H5FS_section_class_t *classes[] = { /* Free space section classes implemented for fractal heap */
H5HF_FSPACE_SECT_CLS_SINGLE,
@@ -118,19 +118,22 @@ H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free space info")
} /* end if */
else {
- H5FS_create_t fs_create; /* Free space creation parameters */
-
- /* Set the free space creation parameters */
- fs_create.client = H5FS_CLIENT_FHEAP_ID;
- fs_create.shrink_percent = H5HF_FSPACE_SHRINK;
- fs_create.expand_percent = H5HF_FSPACE_EXPAND;
- fs_create.max_sect_size = hdr->man_dtable.cparam.max_direct_size;
- fs_create.max_sect_addr = hdr->man_dtable.cparam.max_index;
-
- /* Create the free space structure for the heap */
- if(NULL == (hdr->fspace = H5FS_create(hdr->f, dxpl_id, &hdr->fs_addr,
- &fs_create, NELMTS(classes), classes, hdr)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free space info")
+ /* Check if we are allowed to create the free space manager */
+ if(may_create) {
+ H5FS_create_t fs_create; /* Free space creation parameters */
+
+ /* Set the free space creation parameters */
+ fs_create.client = H5FS_CLIENT_FHEAP_ID;
+ fs_create.shrink_percent = H5HF_FSPACE_SHRINK;
+ fs_create.expand_percent = H5HF_FSPACE_EXPAND;
+ fs_create.max_sect_size = hdr->man_dtable.cparam.max_direct_size;
+ fs_create.max_sect_addr = hdr->man_dtable.cparam.max_index;
+
+ /* Create the free space structure for the heap */
+ if(NULL == (hdr->fspace = H5FS_create(hdr->f, dxpl_id, &hdr->fs_addr,
+ &fs_create, NELMTS(classes), classes, hdr)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free space info")
+ } /* end if */
} /* end else */
done:
@@ -170,7 +173,7 @@ H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node,
/* Check if the free space for the heap has been initialized */
if(!hdr->fspace)
- if(H5HF_space_start(hdr, dxpl_id) < 0)
+ if(H5HF_space_start(hdr, dxpl_id, TRUE) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
/* Construct user data */
@@ -204,7 +207,7 @@ done:
htri_t
H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request, H5HF_free_section_t **node)
{
- htri_t node_found; /* Whether an existing free list node was found */
+ htri_t node_found = FALSE; /* Whether an existing free list node was found */
htri_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_space_find)
@@ -218,12 +221,13 @@ H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request, H5HF_free_secti
/* Check if the free space for the heap has been initialized */
if(!hdr->fspace)
- if(H5HF_space_start(hdr, dxpl_id) < 0)
+ if(H5HF_space_start(hdr, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
/* Search for free space in the heap */
- if((node_found = H5FS_sect_find(hdr->f, dxpl_id, hdr->fspace, request, (H5FS_section_info_t **)node)) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
+ if(hdr->fspace)
+ if((node_found = H5FS_sect_find(hdr->f, dxpl_id, hdr->fspace, request, (H5FS_section_info_t **)node)) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
/* Set return value */
ret_value = node_found;
@@ -262,12 +266,16 @@ H5HF_space_size(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t *fs_size)
/* Check if the free space for the heap has been initialized */
if(!hdr->fspace)
- if(H5HF_space_start(hdr, dxpl_id) < 0)
+ if(H5HF_space_start(hdr, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
/* Get free space metadata size */
- if(H5FS_size(hdr->f, hdr->fspace, fs_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't retrieve FS meta storage info")
+ if(hdr->fspace) {
+ if(H5FS_size(hdr->f, hdr->fspace, fs_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't retrieve FS meta storage info")
+ } /* end if */
+ else
+ *fs_size = 0;
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5HL.c b/src/H5HL.c
index 1cf3c9f..358816b 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -213,87 +213,91 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
size_t free_block = H5HL_FREE_NULL;
H5HL_t *ret_value;
- FUNC_ENTER_NOAPI(H5HL_load, NULL);
+ FUNC_ENTER_NOAPI(H5HL_load, NULL)
/* check arguments */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(!udata1);
- assert(!udata2);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(!udata1);
+ HDassert(!udata2);
/* Cache this for later */
- sizeof_hdr= H5HL_SIZEOF_HDR(f);
- assert(sizeof_hdr <= sizeof(hdr));
+ sizeof_hdr = H5HL_SIZEOF_HDR(f);
+ HDassert(sizeof_hdr <= sizeof(hdr));
/* Get the local heap's header */
- if (H5F_block_read(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read heap header");
+ if(H5F_block_read(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read heap header")
p = hdr;
/* Check magic number */
if(HDmemcmp(hdr, H5HL_MAGIC, (size_t)H5HL_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap signature");
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap signature")
p += H5HL_SIZEOF_MAGIC;
/* Version */
- if (H5HL_VERSION!=*p++)
- HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap");
+ if(H5HL_VERSION != *p++)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap")
/* Reserved */
p += 3;
/* Allocate space in memory for the heap */
- if (NULL==(heap = H5FL_CALLOC(H5HL_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(NULL == (heap = H5FL_CALLOC(H5HL_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* heap data size */
H5F_DECODE_LENGTH(f, p, heap->heap_alloc);
/* free list head */
H5F_DECODE_LENGTH(f, p, free_block);
- if (free_block != H5HL_FREE_NULL && free_block >= heap->heap_alloc)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
+ if(free_block != H5HL_FREE_NULL && free_block >= heap->heap_alloc)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
/* data */
H5F_addr_decode(f, &p, &(heap->addr));
- if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + heap->heap_alloc))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (heap->heap_alloc &&
+ if(NULL == (heap->chunk = H5FL_BLK_CALLOC(heap_chunk, (sizeof_hdr + heap->heap_alloc))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(heap->heap_alloc &&
H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data");
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data")
/* Build free list */
- while (H5HL_FREE_NULL != free_block) {
- if (free_block >= heap->heap_alloc)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
- if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ while(H5HL_FREE_NULL != free_block) {
+ if(free_block >= heap->heap_alloc)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
+ if(NULL == (fl = H5FL_MALLOC(H5HL_free_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
fl->offset = free_block;
fl->prev = tail;
fl->next = NULL;
- if (tail) tail->next = fl;
+ if(tail)
+ tail->next = fl;
tail = fl;
- if (!heap->freelist) heap->freelist = fl;
+ if(!heap->freelist)
+ heap->freelist = fl;
p = heap->chunk + sizeof_hdr + free_block;
+
H5F_DECODE_LENGTH(f, p, free_block);
- H5F_DECODE_LENGTH(f, p, fl->size);
+ if(free_block == 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "free block size is zero?")
+ H5F_DECODE_LENGTH(f, p, fl->size);
if (fl->offset + fl->size > heap->heap_alloc)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
- }
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list")
+ } /* end while */
/* Set return value */
ret_value = heap;
done:
- if (!ret_value && heap) {
- if(H5HL_dest(f,heap)<0)
- HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy local heap collection");
- }
+ if(!ret_value && heap)
+ if(H5HL_dest(f,heap) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "unable to destroy local heap collection")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_load() */
/*-------------------------------------------------------------------------
@@ -963,6 +967,45 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t buf_size, const void *
need_more = need_size;
new_heap_alloc = heap->heap_alloc + need_more;
+#if 0 /* JRM */ /* delete this once we are convinced that the general
+ * fix will do the job.
+ */
+/*
+ * XXX: This is a _total_ hack, a real kludge. :-/ The metadata cache currently
+ * responds very poorly when an object is inserted into the cache (or
+ * resized) that is larger than the current cache size. It waits through
+ * an entire 'epoch' of cache operations to resize the cache larger (getting
+ * _very_ poor performance), instead of immediately accommodating the large
+ * object by increasing the cache size.
+ *
+ * So, what we are doing here is to look at the current cache size, check
+ * if the new local heap will overwhelm the cache and, if so, resize the
+ * cache to be large enough to hold the new local heap block along with
+ * leaving room for other objects in the cache.
+ *
+ * John will be working on a fix inside the cache itself, so this special
+ * case code here can be removed when he's finished. - QAK, 2007/12/21
+ */
+{
+ H5AC_cache_config_t mdc_config;
+
+ /* Retrieve the current cache information */
+ mdc_config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
+ if(H5AC_get_cache_auto_resize_config(f->shared->cache, &mdc_config) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (size_t)-1, "H5AC_get_cache_auto_resize_config() failed.")
+
+ /* Check if the current cache will get blown out by adding this heap
+ * block and resize it if so.
+ */
+ if((2 * new_heap_alloc) >= mdc_config.initial_size) {
+ mdc_config.set_initial_size = TRUE;
+ mdc_config.initial_size = 2 * new_heap_alloc;
+
+ if(H5AC_set_cache_auto_resize_config(f->shared->cache, &mdc_config) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (size_t)-1, "H5AC_set_cache_auto_resize_config() failed.")
+ } /* end if */
+}
+#endif /* JRM */
HDassert(heap->heap_alloc < new_heap_alloc);
H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
H5_CHECK_OVERFLOW(new_heap_alloc, size_t, hsize_t);
diff --git a/src/H5L.c b/src/H5L.c
index 238815a..bbb3996 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -1171,11 +1171,11 @@ H5Literate(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
last_lnk = 0;
/* Build link operator info */
- lnk_op.op_type = H5G_LINK_OP_APP;
- lnk_op.u.app_op = op;
+ lnk_op.op_type = H5G_LINK_OP_NEW;
+ lnk_op.op_func.op_new = op;
/* Iterate over the links */
- if((ret_value = H5G_obj_iterate(grp_id, ".", idx_type, order, idx, &last_lnk, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
+ if((ret_value = H5G_iterate(grp_id, ".", idx_type, order, idx, &last_lnk, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed")
/* Set the index we stopped at */
@@ -1243,11 +1243,11 @@ H5Literate_by_name(hid_t loc_id, const char *group_name,
last_lnk = 0;
/* Build link operator info */
- lnk_op.op_type = H5G_LINK_OP_APP;
- lnk_op.u.app_op = op;
+ lnk_op.op_type = H5G_LINK_OP_NEW;
+ lnk_op.op_func.op_new = op;
/* Iterate over the links */
- if((ret_value = H5G_obj_iterate(loc_id, group_name, idx_type, order, idx, &last_lnk, &lnk_op, op_data, lapl_id, H5AC_ind_dxpl_id)) < 0)
+ if((ret_value = H5G_iterate(loc_id, group_name, idx_type, order, idx, &last_lnk, &lnk_op, op_data, lapl_id, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed")
/* Set the index we stopped at */
@@ -1258,6 +1258,126 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Literate_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lvisit
+ *
+ * Purpose: Recursively visit all the links in a group and all
+ * the groups that are linked to from that group. Links within
+ * each group are visited according to the order within the
+ * specified index (unless the specified index does not exist for
+ * a particular group, then the "name" index is used).
+ *
+ * NOTE: Each _link_ reachable from the initial group will only be
+ * visited once. However, because an object may be reached from
+ * more than one link, the visitation may call the application's
+ * callback with more than one link that points to a particular
+ * _object_.
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ * Programmer: Quincey Koziol
+ * November 24 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
+ H5L_iterate_t op, void *op_data)
+{
+ H5I_type_t id_type; /* Type of ID */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Lvisit, FAIL)
+ H5TRACE5("e", "iIiIox*x", grp_id, idx_type, order, op, op_data);
+
+ /* Check args */
+ id_type = H5I_get_type(grp_id);
+ if(!(H5I_GROUP == id_type || H5I_FILE == id_type))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
+ if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+ if(!op)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified")
+
+ /* Call internal group visitation routine */
+ if((ret_value = H5G_visit(grp_id, ".", idx_type, order, op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link visitation failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lvisit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lvisit_by_name
+ *
+ * Purpose: Recursively visit all the links in a group and all
+ * the groups that are linked to from that group. Links within
+ * each group are visited according to the order within the
+ * specified index (unless the specified index does not exist for
+ * a particular group, then the "name" index is used).
+ *
+ * NOTE: Each _link_ reachable from the initial group will only be
+ * visited once. However, because an object may be reached from
+ * more than one link, the visitation may call the application's
+ * callback with more than one link that points to a particular
+ * _object_.
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ * Programmer: Quincey Koziol
+ * November 3 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lvisit_by_name(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, H5L_iterate_t op, void *op_data, hid_t lapl_id)
+{
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Lvisit_by_name, FAIL)
+ H5TRACE7("e", "i*sIiIox*xi", loc_id, group_name, idx_type, order, op, op_data,
+ lapl_id);
+
+ /* Check args */
+ if(!group_name || !*group_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+ if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+ if(!op)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ /* Call internal group visitation routine */
+ if((ret_value = H5G_visit(loc_id, group_name, idx_type, order, op, op_data, lapl_id, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link visitation failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lvisit_by_name() */
+
/*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h
index 1645e4b..823b046 100644
--- a/src/H5Lpublic.h
+++ b/src/H5Lpublic.h
@@ -170,6 +170,11 @@ H5_DLL herr_t H5Literate(hid_t grp_id, H5_index_t idx_type,
H5_DLL herr_t H5Literate_by_name(hid_t loc_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx,
H5L_iterate_t op, void *op_data, hid_t lapl_id);
+H5_DLL herr_t H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
+ H5L_iterate_t op, void *op_data);
+H5_DLL herr_t H5Lvisit_by_name(hid_t loc_id, const char *group_name,
+ H5_index_t idx_type, H5_iter_order_t order, H5L_iterate_t op,
+ void *op_data, hid_t lapl_id);
/* UD link functions */
H5_DLL herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name,
diff --git a/src/H5MF.c b/src/H5MF.c
index ab62038..df4531e 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -21,25 +21,59 @@
*
* Purpose: File memory management functions.
*
- * Modifications:
- * Robb Matzke, 5 Aug 1997
- * Added calls to H5E.
- *
- * Robb Matzke, 8 Jun 1998
- * Implemented a very simple free list which is not persistent and which
- * is lossy.
- *
*-------------------------------------------------------------------------
*/
+
+/****************/
+/* Module Setup */
+/****************/
+
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
-#include "H5private.h"
-#include "H5Eprivate.h"
-#include "H5Fpkg.h"
-#include "H5FDprivate.h"
-#include "H5MFprivate.h"
-#include "H5FDmulti.h" /*multiple files partitioned by mem usage */
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5MFprivate.h" /* File memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+static hbool_t H5MF_alloc_overflow(const H5F_t *f, hsize_t size);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
/*-------------------------------------------------------------------------
@@ -51,16 +85,12 @@
* is being requested.
*
* Return: Success: The file address of new chunk.
- *
* Failure: HADDR_UNDEF
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Jul 11 1997
*
- * Modifications:
- * Robb Matzke, 1999-08-04
- * Modified to work with the virtual file layer.
*-------------------------------------------------------------------------
*/
haddr_t
@@ -68,33 +98,29 @@ H5MF_alloc(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
{
haddr_t ret_value;
- FUNC_ENTER_NOAPI(H5MF_alloc, HADDR_UNDEF);
+ FUNC_ENTER_NOAPI(H5MF_alloc, HADDR_UNDEF)
/* check arguments */
- assert(f);
- assert(size > 0);
+ HDassert(f);
+ HDassert(size > 0);
/* Fail if we don't have write access */
- if (0==(f->intent & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "file is read-only");
-
- /* Check that the file can address the new space */
- if( H5MF_alloc_overflow(f, size) )
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "not enough address space in file");
+ if(0 == (f->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "file is read-only")
/* Allocate space from the virtual file layer */
- if (HADDR_UNDEF==(ret_value=H5FD_alloc(f->shared->lf, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed");
+ if(HADDR_UNDEF == (ret_value = H5FD_alloc(f->shared->lf, type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed")
/* Convert absolute file address to relative file address */
- assert(ret_value>=f->shared->base_addr);
+ HDassert(ret_value >= f->shared->base_addr);
/* Set return value */
ret_value -= f->shared->base_addr;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc() */
/*-------------------------------------------------------------------------
@@ -109,44 +135,35 @@ done:
* matzke@llnl.gov
* Jul 17 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value
- *
- * Robb Matzke, 1999-08-03
- * Modified to use the virtual file layer.
*-------------------------------------------------------------------------
*/
herr_t
H5MF_xfree(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5MF_xfree);
+ FUNC_ENTER_NOAPI_NOFUNC(H5MF_xfree)
/* check arguments */
- assert(f);
- if (!H5F_addr_defined(addr) || 0 == size)
+ HDassert(f);
+ if(!H5F_addr_defined(addr) || 0 == size)
HGOTO_DONE(SUCCEED);
- assert(addr!=0);
+ HDassert(addr != 0);
/* Convert relative address to absolute address */
addr += f->shared->base_addr;
/* Allow virtual file layer to free block */
- if (H5FD_free(f->shared->lf, type, dxpl_id, addr, size)<0) {
+ if(H5FD_free(f->shared->lf, type, dxpl_id, addr, size) < 0) {
#ifdef H5MF_DEBUG
- if (H5DEBUG(MF)) {
- fprintf(H5DEBUG(MF),
- "H5MF_free: lost %lu bytes of file storage\n",
- (unsigned long)size);
- }
+ if(H5DEBUG(MF))
+ fprintf(H5DEBUG(MF), "H5MF_free: lost %lu bytes of file storage\n", (unsigned long)size);
#endif
- }
+ } /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_xfree() */
/*-------------------------------------------------------------------------
@@ -169,19 +186,11 @@ done:
* circumstances the library may return the same address.
*
* Return: Success: The relative file address of the new block.
- *
* Failure: HADDR_UNDEF
*
* Programmer: Robb Matzke
* Thursday, April 16, 1998
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ORIG_ADDR is passed by value. The name of NEW_ADDR has
- * been changed to NEW_ADDR_P
- *
- * Robb Matzke, 1999-08-04
- * Modified to work with the virtual file layer.
*-------------------------------------------------------------------------
*/
haddr_t
@@ -190,31 +199,25 @@ H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr, hsize_t
{
haddr_t ret_value;
- FUNC_ENTER_NOAPI(H5MF_realloc, HADDR_UNDEF);
+ FUNC_ENTER_NOAPI(H5MF_realloc, HADDR_UNDEF)
/* Convert old relative address to absolute address */
old_addr += f->shared->base_addr;
- /* Check that the file can address the new space. */
- /* In the worst case, this means adding new_size bytes to the end of the file. */
- if( H5MF_alloc_overflow(f, new_size) )
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "not enough address space in file");
-
/* Reallocate memory from the virtual file layer */
- ret_value = H5FD_realloc(f->shared->lf, type, dxpl_id, old_addr, old_size,
- new_size);
- if (HADDR_UNDEF==ret_value)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "unable to allocate new file memory");
+ ret_value = H5FD_realloc(f->shared->lf, type, dxpl_id, old_addr, old_size, new_size);
+ if(HADDR_UNDEF == ret_value)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "unable to allocate new file memory")
/* Convert return value to relative address */
- assert(ret_value>=f->shared->base_addr);
+ HDassert(ret_value >= f->shared->base_addr);
/* Set return value */
ret_value -= f->shared->base_addr;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_realloc() */
/*-------------------------------------------------------------------------
@@ -224,8 +227,8 @@ done:
* F is the file whose space is being allocated, SIZE is the amount
* of space needed.
*
- * Return: 0 if no overflow would result
- * 1 if overflow would result (the allocation should not be allowed)
+ * Return: FALSE if no overflow would result
+ * TRUE if overflow would result (the allocation should not be allowed)
*
* Programmer: James Laird
* Nat Furrer
@@ -233,46 +236,33 @@ done:
*
*-------------------------------------------------------------------------
*/
-hbool_t
+static hbool_t
H5MF_alloc_overflow(const H5F_t *f, hsize_t size)
{
- hsize_t space_needed = 0; /* Accumulator variable */
- size_t c; /* Local index variable */
- hbool_t ret_value; /* Return value */
+ haddr_t eoa; /* End-of-allocation in the file */
+ haddr_t space_avail; /* Unallocated space still available in file */
+ hbool_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5MF_alloc_overflow)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MF_alloc_overflow)
/* Start with the current end of the file's address. */
- space_needed = (hsize_t)H5F_get_eoa(f);
-
- HDassert(H5F_addr_defined(space_needed));
+ eoa = H5F_get_eoa(f);
+ HDassert(H5F_addr_defined(eoa));
- /* Subtract the file's base address to get the actual amount of
- * space being used:
- * (end of allocated space - beginning of allocated space)
+ /* Subtract EOA from the file's maximum address to get the actual amount of
+ * addressable space left in the file.
*/
- HDassert(H5F_BASE_ADDR(f) < space_needed);
- space_needed -= (hsize_t)H5F_BASE_ADDR(f);
+ HDassert(f->shared->maxaddr >= eoa);
+ space_avail = (hsize_t)(f->shared->maxaddr - eoa);
- /* Add the amount of space requested for this allocation */
- space_needed += size;
-
- /* Ensure that this final number is less than the file's
- * address space. We do this by shifting in multiples
- * of 16 bits because some systems will do nothing if
- * we shift by 64 bits all at once (<cough> Linux <cough>).
- * Thus, we break one shift into several smaller shifts.
- */
- for(c=0; c < H5F_SIZEOF_ADDR(f); c += 2)
- space_needed = space_needed >> 16;
-
- if(space_needed != 0)
+ /* Ensure that there's enough room left in the file for something of this size */
+ if(size > space_avail)
ret_value = TRUE;
else
ret_value = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5MF_alloc_overflow() */
/*-------------------------------------------------------------------------
@@ -281,14 +271,11 @@ H5MF_alloc_overflow(const H5F_t *f, hsize_t size)
* Purpose: Check if a block in the file can be extended.
*
* Return: Success: TRUE(1)/FALSE(0)
- *
* Failure: FAIL
*
* Programmer: Quincey Koziol
* Friday, June 11, 2004
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
htri_t
@@ -296,21 +283,17 @@ H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t e
{
htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5MF_can_extend, FAIL);
+ FUNC_ENTER_NOAPI(H5MF_can_extend, FAIL)
/* Convert old relative address to absolute address */
addr += H5F_BASE_ADDR(f);
/* Pass the request down to the virtual file layer */
- if((ret_value=H5FD_can_extend(f->shared->lf, type, addr, size, extra_requested))<0)
+ if((ret_value = H5FD_can_extend(f->shared->lf, type, addr, size, extra_requested)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory");
- /* Make sure there is enough addressable space to satisfy the request */
- if (ret_value == TRUE)
- ret_value = !H5MF_alloc_overflow(f, extra_requested);
-
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_can_extend() */
@@ -320,14 +303,11 @@ done:
* Purpose: Extend a block in the file.
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Quincey Koziol
* Saturday, June 12, 2004
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -335,19 +315,16 @@ H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra
{
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5MF_extend, FAIL);
-
- /* Make sure there is enough addressable space to satisfy the request */
- if ( H5MF_alloc_overflow(f, extra_requested) )
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory: out of address space");
+ FUNC_ENTER_NOAPI(H5MF_extend, FAIL)
- /* Convert old relative address to absolute address */
+ /* Convert relative address to absolute address */
addr += H5F_BASE_ADDR(f);
/* Pass the request down to the virtual file layer */
- if((ret_value=H5FD_extend(f->shared->lf, type, addr, size, extra_requested))<0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory");
+ if((ret_value = H5FD_extend(f->shared->lf, type, addr, size, extra_requested)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate new file memory")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_extend() */
+
diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h
index b3f0d17..e01a9f6 100644
--- a/src/H5MFprivate.h
+++ b/src/H5MFprivate.h
@@ -29,9 +29,8 @@
#define _H5MFprivate_H
/* Private headers needed by this file */
-#include "H5private.h"
-#include "H5Fprivate.h"
-#include "H5FDprivate.h" /*file driver */
+#include "H5Fprivate.h" /* File access */
+#include "H5FDprivate.h" /* File Drivers */
/*
* Feature: Define H5MF_DEBUG on the compiler command line if you want to
@@ -49,10 +48,10 @@ H5_DLL herr_t H5MF_xfree(const H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t
hsize_t size);
H5_DLL haddr_t H5MF_realloc(H5F_t *f, H5FD_mem_t type, hid_t dxpl_id, haddr_t old_addr,
hsize_t old_size, hsize_t new_size);
-H5_DLL hbool_t H5MF_alloc_overflow(const H5F_t *f, hsize_t size);
H5_DLL htri_t H5MF_can_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr,
hsize_t size, hsize_t extra_requested);
H5_DLL herr_t H5MF_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size,
hsize_t extra_requested);
-#endif
+#endif /* end _H5MFprivate_H */
+
diff --git a/src/H5O.c b/src/H5O.c
index f72fe7e..e42f1eb 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -58,6 +58,17 @@
/* Local Typedefs */
/******************/
+/* User data for recursive traversal over objects from a group */
+typedef struct {
+ hid_t obj_id; /* The ID for the starting group */
+ H5G_loc_t *start_loc; /* Location of starting group */
+ hid_t lapl_id; /* LAPL for walking across links */
+ hid_t dxpl_id; /* DXPL for operations */
+ H5SL_t *visited; /* Skip list for tracking visited nodes */
+ H5O_iterate_t op; /* Application callback */
+ void *op_data; /* Application's op data */
+} H5O_iter_visit_ud_t;
+
/********************/
/* Package Typedefs */
@@ -71,6 +82,9 @@
static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
static const H5O_obj_class_t *H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id);
static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type);
+static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
+ H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id,
+ hid_t dxpl_id);
/*********************/
@@ -79,9 +93,11 @@ static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type);
/* Header message ID to class mapping */
-/* Remember to increment H5O_MSG_TYPES in H5Opkg.h when adding a new
+
+/* Remember to increment H5O_MSG_TYPES in H5Opkg.h when adding a new
* message.
*/
+
const H5O_msg_class_t *const H5O_msg_class_g[] = {
H5O_MSG_NULL, /*0x0000 Null */
H5O_MSG_SDSPACE, /*0x0001 Dataspace */
@@ -148,6 +164,9 @@ H5FL_BLK_DEFINE(chunk_image);
/* Declare external the free list for time_t's */
H5FL_EXTERN(time_t);
+/* Declare external the free list for H5_obj_t's */
+H5FL_EXTERN(H5_obj_t);
+
/*******************/
/* Local Variables */
@@ -841,6 +860,130 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Ovisit
+ *
+ * Purpose: Recursively visit an object and all the objects reachable
+ * from it. If the starting object is a group, all the objects
+ * linked to from that group will be visited. Links within
+ * each group are visited according to the order within the
+ * specified index (unless the specified index does not exist for
+ * a particular group, then the "name" index is used).
+ *
+ * NOTE: Soft links and user-defined links are ignored during
+ * this operation.
+ *
+ * NOTE: Each _object_ reachable from the initial group will only
+ * be visited once. If multiple hard links point to the same
+ * object, the first link to the object's path (according to the
+ * iteration index and iteration order given) will be used to in
+ * the callback about the object.
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ * Programmer: Quincey Koziol
+ * November 25 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ovisit(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order,
+ H5O_iterate_t op, void *op_data)
+{
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Ovisit, FAIL)
+ H5TRACE5("e", "iIiIox*x", obj_id, idx_type, order, op, op_data);
+
+ /* Check args */
+ if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+ if(!op)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified")
+
+ /* Call internal object visitation routine */
+ if((ret_value = H5O_visit(obj_id, ".", idx_type, order, op, op_data, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "object visitation failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ovisit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ovisit_by_name
+ *
+ * Purpose: Recursively visit an object and all the objects reachable
+ * from it. If the starting object is a group, all the objects
+ * linked to from that group will be visited. Links within
+ * each group are visited according to the order within the
+ * specified index (unless the specified index does not exist for
+ * a particular group, then the "name" index is used).
+ *
+ * NOTE: Soft links and user-defined links are ignored during
+ * this operation.
+ *
+ * NOTE: Each _object_ reachable from the initial group will only
+ * be visited once. If multiple hard links point to the same
+ * object, the first link to the object's path (according to the
+ * iteration index and iteration order given) will be used to in
+ * the callback about the object.
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ * Programmer: Quincey Koziol
+ * November 24 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ovisit_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
+ H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id)
+{
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Ovisit_by_name, FAIL)
+ H5TRACE7("e", "i*sIiIox*xi", loc_id, obj_name, idx_type, order, op, op_data,
+ lapl_id);
+
+ /* Check args */
+ if(!obj_name || !*obj_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+ if(!op)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ /* Call internal object visitation routine */
+ if((ret_value = H5O_visit(loc_id, obj_name, idx_type, order, op, op_data, lapl_id, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "object visitation failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ovisit_by_name() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Oclose
*
* Purpose: Close an open file object.
@@ -953,6 +1096,14 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
oh->version = H5O_VERSION_1;
oh->sizeof_size = H5F_SIZEOF_SIZE(f);
oh->sizeof_addr = H5F_SIZEOF_ADDR(f);
+#ifdef H5O_ENABLE_BAD_MESG_COUNT
+ /* Check whether the "bad message count" property is set */
+ if(H5P_exist_plist(oc_plist, H5O_BAD_MESG_COUNT_NAME) > 0) {
+ /* Retrieve bad message count flag */
+ if(H5P_get(oc_plist, H5O_BAD_MESG_COUNT_NAME, &oh->store_bad_mesg_count) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get bad message count flag")
+ } /* end if */
+#endif /* H5O_ENABLE_BAD_MESG_COUNT */
/* Set initial status flags */
oh->flags = oh_flags;
@@ -1141,7 +1292,7 @@ H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id)
loc_found = TRUE;
/* Open the object */
- if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
done:
@@ -2138,8 +2289,7 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o
HDmemset(oinfo, 0, sizeof(*oinfo));
/* Retrieve the file's fileno */
- if(H5F_get_fileno(oloc->file, &oinfo->fileno) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to read fileno")
+ H5F_GET_FILENO(oloc->file, oinfo->fileno);
/* Set the object's address */
oinfo->addr = oloc->addr;
@@ -2429,3 +2579,300 @@ H5O_get_oh_addr(const H5O_t *oh)
FUNC_LEAVE_NOAPI(oh->chunk[0].addr)
} /* end H5O_get_oh_addr() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_rc_and_type
+ *
+ * Purpose: Retrieve an object's reference count and type
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * November 4 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_get_rc_and_type(const H5O_loc_t *oloc, hid_t dxpl_id, unsigned *rc, H5O_type_t *otype)
+{
+ H5O_t *oh = NULL; /* Object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_get_rc_and_type, FAIL)
+
+ /* Check args */
+ HDassert(oloc);
+ HDassert(rc);
+ HDassert(otype);
+
+ /* Get the object header */
+ if(NULL == (oh = H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* Set the object's reference count */
+ *rc = oh->nlink;
+
+ /* Retrieve the type of the object */
+ if(H5O_obj_type_real(oh, otype) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type")
+
+done:
+ if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_get_rc_and_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_free_visit_visited
+ *
+ * Purpose: Free the key for an object visited during a group traversal
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Nov 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_free_visit_visited(void *item, void UNUSED *key, void UNUSED *operator_data/*in,out*/)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_visit_visited)
+
+ H5FL_FREE(H5_obj_t, item);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_free_visit_visited() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_visit_cb
+ *
+ * Purpose: Callback function for recursively visiting objects from a group
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Nov 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_visit_cb(hid_t UNUSED group, const char *name, const H5L_info_t *linfo,
+ void *_udata)
+{
+ H5O_iter_visit_ud_t *udata = (H5O_iter_visit_ud_t *)_udata; /* User data for callback */
+ H5G_loc_t obj_loc; /* Location of object */
+ H5G_name_t obj_path; /* Object's group hier. path */
+ H5O_loc_t obj_oloc; /* Object's object location */
+ hbool_t obj_found = FALSE; /* Object at 'name' found */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_visit_cb)
+
+ /* Sanity check */
+ HDassert(name);
+ HDassert(linfo);
+ HDassert(udata);
+
+ /* Check if this is a hard link */
+ if(linfo->type == H5L_TYPE_HARD) {
+ H5_obj_t obj_pos; /* Object "position" for this object */
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Find the object using the LAPL passed in */
+ /* (Correctly handles mounted files) */
+ if(H5G_loc_find(udata->start_loc, name, &obj_loc/*out*/, udata->lapl_id, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, H5_ITER_ERROR, "object not found")
+ obj_found = TRUE;
+
+ /* Construct unique "position" for this object */
+ H5F_GET_FILENO(obj_oloc.file, obj_pos.fileno);
+ obj_pos.addr = obj_oloc.addr;
+
+ /* Check if we've seen the object the link references before */
+ if(NULL == H5SL_search(udata->visited, &obj_pos)) {
+ H5O_info_t oinfo; /* Object info */
+
+ /* Get the object's info */
+ if(H5O_get_info(&obj_oloc, udata->dxpl_id, TRUE, &oinfo) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "unable to get object info")
+
+ /* Make the application callback */
+ ret_value = (udata->op)(udata->obj_id, name, &oinfo, udata->op_data);
+
+ /* Check for continuing to visit objects */
+ if(ret_value == H5_ITER_CONT) {
+ /* If its ref count is > 1, we add it to the list of visited objects */
+ /* (because it could come up again during traversal) */
+ if(oinfo.rc > 1) {
+ H5_obj_t *new_node; /* New object node for visited list */
+
+ /* Allocate new object "position" node */
+ if((new_node = H5FL_MALLOC(H5_obj_t)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate object node")
+
+ /* Set node information */
+ *new_node = obj_pos;
+
+ /* Add to list of visited objects */
+ if(H5SL_insert(udata->visited, new_node, new_node) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert object node into visited list")
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(obj_found && H5G_loc_free(&obj_loc) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_visit_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_visit
+ *
+ * Purpose: Recursively visit an object and all the objects reachable
+ * from it. If the starting object is a group, all the objects
+ * linked to from that group will be visited. Links within
+ * each group are visited according to the order within the
+ * specified index (unless the specified index does not exist for
+ * a particular group, then the "name" index is used).
+ *
+ * NOTE: Soft links and user-defined links are ignored during
+ * this operation.
+ *
+ * NOTE: Each _object_ reachable from the initial group will only
+ * be visited once. If multiple hard links point to the same
+ * object, the first link to the object's path (according to the
+ * iteration index and iteration order given) will be used to in
+ * the callback about the object.
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ * Programmer: Quincey Koziol
+ * November 24 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
+ H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id,
+ hid_t dxpl_id)
+{
+ H5O_iter_visit_ud_t udata; /* User data for callback */
+ H5G_loc_t loc; /* Location of reference object */
+ H5G_loc_t obj_loc; /* Location used to open object */
+ H5G_name_t obj_path; /* Opened object group hier. path */
+ H5O_loc_t obj_oloc; /* Opened object object location */
+ hbool_t loc_found = FALSE; /* Entry at 'name' found */
+ H5O_info_t oinfo; /* Object info struct */
+ hid_t obj_id = (-1); /* ID of object */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_visit, FAIL)
+
+ /* Portably initialize user data struct to zeros */
+ HDmemset(&udata, 0, sizeof(udata));
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Find the object's location */
+ if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found")
+ loc_found = TRUE;
+
+ /* Get the object's info */
+ if(H5O_get_info(&obj_oloc, dxpl_id, TRUE, &oinfo) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info")
+
+ /* Open the object */
+ /* (Takes ownership of the obj_loc information) */
+ if((obj_id = H5O_open_by_loc(&obj_loc, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
+
+ /* Make callback for starting object */
+ if((ret_value = op(obj_id, ".", &oinfo, op_data)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "can't visit objects")
+
+ /* Check for object being a group */
+ if(oinfo.type == H5O_TYPE_GROUP) {
+ H5G_loc_t start_loc; /* Location of starting group */
+
+ /* Get the location of the starting group */
+ if(H5G_loc(obj_id, &start_loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+
+ /* Set up user data for visiting links */
+ udata.obj_id = obj_id;
+ udata.start_loc = &start_loc;
+ udata.lapl_id = lapl_id;
+ udata.dxpl_id = dxpl_id;
+ udata.op = op;
+ udata.op_data = op_data;
+
+ /* Create skip list to store visited object information */
+ if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, 0.5, (size_t)16)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
+
+ /* If its ref count is > 1, we add it to the list of visited objects */
+ /* (because it could come up again during traversal) */
+ if(oinfo.rc > 1) {
+ H5_obj_t *obj_pos; /* New object node for visited list */
+
+ /* Allocate new object "position" node */
+ if((obj_pos = H5FL_MALLOC(H5_obj_t)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "can't allocate object node")
+
+ /* Construct unique "position" for this object */
+ obj_pos->fileno = oinfo.fileno;
+ obj_pos->addr = oinfo.addr;
+
+ /* Add to list of visited objects */
+ if(H5SL_insert(udata.visited, obj_pos, obj_pos) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object node into visited list")
+ } /* end if */
+
+ /* Call internal group visitation routine */
+ if((ret_value = H5G_visit(obj_id, ".", idx_type, order, H5O_visit_cb, &udata, lapl_id, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed")
+ } /* end if */
+
+done:
+ if(obj_id > 0) {
+ if(H5I_dec_ref(obj_id) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
+ } /* end if */
+ else if(loc_found && H5G_loc_free(&obj_loc) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location")
+ if(udata.visited)
+ H5SL_destroy(udata.visited, H5O_free_visit_visited, NULL);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_visit() */
+
+
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index b5c8c7d..0d5765e 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -580,10 +580,25 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
if(merged_null_msgs)
oh->cache_info.is_dirty = TRUE;
+/* Don't check for the incorrect # of object header messages bug unless we've
+ * enabled strict format checking. This allows for older files, created with
+ * a version of the library that had a bug in tracking the correct # of header
+ * messages to be read in without the library fussing about things. -QAK
+ */
+#ifdef H5_STRICT_FORMAT_CHECKS
/* Sanity check for the correct # of messages in object header */
if(oh->version == H5O_VERSION_1)
if((oh->nmesgs + merged_null_msgs) != nmesgs)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too few messages")
+#else /* H5_STRICT_FORMAT_CHECKS */
+ /* Check for incorrect # of messages in object header and if we have write
+ * access on the file, flag the object header as dirty, so it gets fixed.
+ */
+ if(oh->version == H5O_VERSION_1)
+ if((oh->nmesgs + merged_null_msgs) != nmesgs &&
+ (H5F_get_intent(f) & H5F_ACC_RDWR))
+ oh->cache_info.is_dirty = TRUE;
+#endif /* H5_STRICT_FORMAT_CHECKS */
#ifdef H5O_DEBUG
H5O_assert(oh);
@@ -710,7 +725,12 @@ H5O_assert(oh);
*p++ = 0;
/* Number of messages */
- UINT16ENCODE(p, oh->nmesgs);
+#ifdef H5O_ENABLE_BAD_MESG_COUNT
+ if(oh->store_bad_mesg_count)
+ UINT16ENCODE(p, (oh->nmesgs - 1))
+ else
+#endif /* H5O_ENABLE_BAD_MESG_COUNT */
+ UINT16ENCODE(p, oh->nmesgs);
/* Link count */
UINT32ENCODE(p, oh->nlink);
diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c
index 660b0e1..384353c 100644
--- a/src/H5Olinfo.c
+++ b/src/H5Olinfo.c
@@ -513,7 +513,6 @@ H5O_linfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
/* Check for copying dense link storage */
if(H5F_addr_defined(linfo_src->fheap_addr)) {
H5O_linfo_postcopy_ud_t udata; /* User data for iteration callback */
- H5G_link_iterate_t lnk_op; /* Link operator */
/* Set up dense link iteration user data */
udata.src_oloc = src_oloc;
@@ -522,12 +521,8 @@ H5O_linfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
udata.dxpl_id = dxpl_id;
udata.cpy_info = cpy_info;
- /* Build iterator operator */
- lnk_op.op_type = H5G_LINK_OP_LIB;
- lnk_op.u.lib_op = H5O_linfo_post_copy_file_cb;
-
/* Iterate over the links in the group, building a table of the link messages */
- if(H5G_dense_iterate(src_oloc->file, dxpl_id, linfo_src, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, (hid_t)0, &lnk_op, &udata) < 0)
+ if(H5G_dense_iterate(src_oloc->file, dxpl_id, linfo_src, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, H5O_linfo_post_copy_file_cb, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links")
} /* end if */
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index b3d94d9..29a7e79 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/H5Opkg.h b/src/H5Opkg.h
index 94af802..69feff4 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -253,6 +253,12 @@ struct H5O_t {
/* File-specific information (not stored) */
size_t sizeof_size; /* Size of file sizes */
size_t sizeof_addr; /* Size of file addresses */
+#ifdef H5O_ENABLE_BAD_MESG_COUNT
+ hbool_t store_bad_mesg_count; /* Flag to indicate that a bad message count should be stored */
+ /* (This is to simulate a bug in earlier
+ * versions of the library)
+ */
+#endif /* H5O_ENABLE_BAD_MESG_COUNT */
/* Object information (stored) */
hbool_t has_refcount_msg; /* Whether the object has a ref. count message */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 393d4e1..19da881 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -93,6 +93,10 @@ typedef struct H5O_t H5O_t;
#define H5O_BOGUS_MSG_FLAGS_NAME "bogus msg flags" /* Flags for 'bogus' message */
#define H5O_BOGUS_MSG_FLAGS_SIZE sizeof(uint8_t)
#endif /* H5O_ENABLE_BOGUS */
+#ifdef H5O_ENABLE_BAD_MESG_COUNT
+#define H5O_BAD_MESG_COUNT_NAME "bad message count" /* Flag setting bad message count */
+#define H5O_BAD_MESG_COUNT_SIZE sizeof(hbool_t)
+#endif /* H5O_ENABLE_BAD_MESG_COUNT */
/* ========= Object Copy properties ============ */
#define H5O_CPY_OPTION_NAME "copy object" /* Copy options */
@@ -571,13 +575,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,
@@ -588,14 +592,17 @@ H5_DLL hid_t H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id);
H5_DLL herr_t H5O_get_nlinks(const H5O_loc_t *loc, hid_t dxpl_id, hsize_t *nlinks);
H5_DLL void *H5O_obj_create(H5F_t *f, H5O_type_t obj_type, void *crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id);
H5_DLL haddr_t H5O_get_oh_addr(const H5O_t *oh);
+H5_DLL herr_t H5O_get_rc_and_type(const H5O_loc_t *oloc, hid_t dxpl_id, unsigned *rc, H5O_type_t *otype);
/* 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/H5Opublic.h b/src/H5Opublic.h
index 6ddd565..acce42c 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -52,13 +52,13 @@
* but we need to assign each kind of message to a different bit so that
* one index can hold multiple types.)
*/
-#define H5O_MESG_NONE_FLAG 0x0000 /* No shared messages */
-#define H5O_MESG_SDSPACE_FLAG 0x0001 /* Simple Dataspace Message. */
-#define H5O_MESG_DTYPE_FLAG 0x0002 /* Datatype Message. */
-#define H5O_MESG_FILL_FLAG 0x0004 /* Fill Value Message. */
-#define H5O_MESG_PLINE_FLAG 0x0008 /* Filter pipeline message. */
-#define H5O_MESG_ATTR_FLAG 0x0010 /* Attribute Message. */
-#define H5O_MESG_ALL_FLAG (H5O_MESG_SDSPACE_FLAG | H5O_MESG_DTYPE_FLAG | H5O_MESG_FILL_FLAG | H5O_MESG_PLINE_FLAG | H5O_MESG_ATTR_FLAG)
+#define H5O_SHMESG_NONE_FLAG 0x0000 /* No shared messages */
+#define H5O_SHMESG_SDSPACE_FLAG ((unsigned)1 << 0x0001) /* Simple Dataspace Message. */
+#define H5O_SHMESG_DTYPE_FLAG ((unsigned)1 << 0x0003) /* Datatype Message. */
+#define H5O_SHMESG_FILL_FLAG ((unsigned)1 << 0x0005) /* Fill Value Message. */
+#define H5O_SHMESG_PLINE_FLAG ((unsigned)1 << 0x000b) /* Filter pipeline message. */
+#define H5O_SHMESG_ATTR_FLAG ((unsigned)1 << 0x000c) /* Attribute Message. */
+#define H5O_SHMESG_ALL_FLAG (H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_FILL_FLAG | H5O_SHMESG_PLINE_FLAG | H5O_SHMESG_ATTR_FLAG)
/* Object header status flag definitions */
#define H5O_HDR_CHUNK0_SIZE 0x03 /* 2-bit field indicating # of bytes to store the size of chunk 0's data */
@@ -124,6 +124,10 @@ typedef struct H5O_info_t {
/* Typedef for message creation indexes */
typedef uint32_t H5O_msg_crt_idx_t;
+/* Prototype for H5Ovisit/H5Ovisit_by_name() operator */
+typedef herr_t (*H5O_iterate_t)(hid_t obj, const char *name, const H5O_info_t *info,
+ void *op_data);
+
/********************/
/* Public Variables */
@@ -159,6 +163,11 @@ H5_DLL herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name,
H5_DLL ssize_t H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize);
H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name,
char *comment, size_t bufsize, hid_t lapl_id);
+H5_DLL herr_t H5Ovisit(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order,
+ H5O_iterate_t op, void *op_data);
+H5_DLL herr_t H5Ovisit_by_name(hid_t loc_id, const char *obj_name,
+ H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op,
+ void *op_data, hid_t lapl_id);
H5_DLL herr_t H5Oclose(hid_t object_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index 44ac3c4..f31d1a4 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -1877,76 +1877,163 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Pset_latest_format
- *
- * Purpose: Indicates that the library should always use the latest version
- * of the file format when creating objects. If this flag is not set,
- * the library will always use the most backwardly compatibly format
- * possible that can store the information about an object.
- *
- * The default value is set to FALSE (creating backwardly compatible files)
+ * Function: H5Pset_libver_bounds
+ *
+ * Purpose: Indicates which versions of the file format the library should
+ * use when creating objects. LOW is the earliest version of the HDF5
+ * library that is guaranteed to be able to access the objects created
+ * (the format of some objects in an HDF5 file may not have changed between
+ * versions of the HDF5 library, possibly allowing earlier versions of the
+ * HDF5 library to access those objects) and HIGH is the latest version
+ * of the library required to access the objects created (later versions
+ * of the HDF5 library will also be able to access those objects).
+ *
+ * LOW is used to require that objects use a more modern format and HIGH
+ * is used to restrict objects from using a more modern format.
+ *
+ * The special values of H5F_FORMAT_EARLIEST and H5F_FORMAT_LATEST can be
+ * used in the following manner: Setting LOW and HIGH to H5F_FORMAT_LATEST
+ * will produce files whose objects use the latest version of the file
+ * format available in the current HDF5 library for each object created.
+ * Setting LOW and HIGH to H5F_FORMAT_EARLIEST will produce files that that
+ * always require the use of the earliest version of the file format for
+ * each object created. [NOTE! LOW=HIGH=H5F_FORMAT_EARLIEST is not
+ * implemented as of version 1.8.0 and setting LOW and HIGH to
+ * H5F_FORMAT_EARLIEST will produce an error currently].
+ *
+ * Currently, the only two valid combinations for this routine are:
+ * LOW = H5F_FORMAT_EARLIEST and HIGH = H5F_FORMAT_LATEST (the default
+ * setting, which creates objects with the ealiest version possible for
+ * each object, but no upper limit on the version allowed to be created if
+ * a newer version of an object's format is required to support a feature
+ * requested with an HDF5 library API routine), and LOW = H5F_FORMAT_LATEST
+ * and HIGH = H5F_FORMAT_LATEST (which is described above).
+ *
+ * The LOW and HIGH values set with this routine at imposed with each
+ * HDF5 library API call that creates objects in the file. API calls that
+ * would violate the LOW or HIGH format bound will fail.
+ *
+ * Setting the LOW and HIGH values will not affect reading/writing existing
+ * objects, only the creation of new objects.
+ *
+ * Note: Eventually we want to add more values to the H5F_libver_t
+ * enumerated type that indicate library release values where the file
+ * format was changed (like "H5F_FORMAT_1_2_0" for the file format changes
+ * in the 1.2.x release branch and possily even "H5F_FORMAT_1_4_2" for
+ * a change mid-way through the 1.4.x release branch, etc).
+ *
+ * Adding more values will allow applications to make settings like the
+ * following:
+ * LOW = H5F_FORMAT_EARLIEST, HIGH = H5F_FORMAT_1_2_0 => Create objects
+ * with the earliest possible format and don't allow any objects
+ * to be created that require a library version greater than 1.2.x
+ * (This is the "make certain that <application> linked with v1.2.x
+ * of the library can read the file produced" use case)
+ *
+ * LOW = H5F_FORMAT_1_4_2, HIGH = H5F_FORMAT_LATEST => create objects
+ * with at least the version of their format that the 1.4.2 library
+ * uses and allow any later version of the object's format
+ * necessary to represent features used.
+ * (This is the "make certain to take advantage of <new feature>
+ * in the file format" use case (maybe <new feature> is smaller
+ * or scales better than an ealier version, which would otherwise
+ * be used))
+ *
+ * LOW = H5F_FORMAT_1_2_0, HIGH = H5F_FORMAT_1_6_0 => creates objects
+ * with at least the version of their format that the 1.2.x library
+ * uses and don't allow any objects to be created that require a
+ * library version greater than 1.6.x.
+ * (Not certain of a particular use case for these settings,
+ * although its probably just the logical combination of the
+ * previous two; it just falls out as possible/logical (if it turns
+ * out to be hard to implement in some way, we can always disallow
+ * it))
+ *
+ * Note #2: We talked about whether to include enum values for only library
+ * versions where the format changed and decided it would be less confusing
+ * for application developers if we include enum values for _all_ library
+ * releases and then map down to the previous actual library release which
+ * had a format change.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Friday, September 9, 2006
+ * Sunday, December 30, 2007
*
*-------------------------------------------------------------------------
*/
herr_t
-H5Pset_latest_format(hid_t plist_id, hbool_t latest)
+H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low,
+ H5F_libver_t high)
{
H5P_genplist_t *plist; /* Property list pointer */
+ hbool_t latest; /* Whether to use the latest version or not */
herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_API(H5Pset_latest_format, FAIL)
- H5TRACE2("e", "ib", plist_id, latest);
+ FUNC_ENTER_API(H5Pset_libver_bounds, FAIL)
+ H5TRACE3("e", "iFvFv", plist_id, low, high);
+
+ /* Check args */
+ /* (Note that this is _really_ restricted right now, we'll want to loosen
+ * this up more as we add features - QAK)
+ */
+ if(high != H5F_LIBVER_LATEST)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid high library version bound")
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set values */
+ latest = (low == H5F_LIBVER_LATEST) ? TRUE : FALSE;
if(H5P_set(plist, H5F_ACS_LATEST_FORMAT_NAME, &latest) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set library version bounds")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Pset_latest_format() */
+} /* end H5Pset_libver_bounds() */
/*-------------------------------------------------------------------------
- * Function: H5Pget_latest_format
+ * Function: H5Pget_libver_bounds
*
- * Purpose: Returns the current settings for the 'latest format' flag
+ * Purpose: Returns the current settings for the library version format bounds
* from a file access property list.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Friday, September 9, 2006
+ * Thursday, January 3, 2008
*
*-------------------------------------------------------------------------
*/
herr_t
-H5Pget_latest_format(hid_t plist_id, hbool_t *latest/*out*/)
+H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low/*out*/,
+ H5F_libver_t *high/*out*/)
{
H5P_genplist_t *plist; /* Property list pointer */
+ hbool_t latest; /* Whether to use the latest version or not */
herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_API(H5Pget_latest_format, FAIL)
- H5TRACE2("e", "ix", plist_id, latest);
+ FUNC_ENTER_API(H5Pget_libver_bounds, FAIL)
+ H5TRACE3("e", "ixx", plist_id, low, high);
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get value */
- if(latest)
- if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, latest) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get 'latest format' flag")
+ if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &latest) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get library version bounds")
+
+ /* Check for setting values to return */
+ /* (Again, this is restricted now, we'll need to open it up later -QAK) */
+ if(low)
+ *low = latest ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST;
+ if(high)
+ *high = H5F_LIBVER_LATEST;
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Pget_latest_format() */
+} /* end H5Pget_libver_bounds() */
diff --git a/src/H5Pfcpl.c b/src/H5Pfcpl.c
index 6345961..8fd4909 100644
--- a/src/H5Pfcpl.c
+++ b/src/H5Pfcpl.c
@@ -757,7 +757,7 @@ H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_
H5TRACE4("e", "iIuIuIu", plist_id, index_num, mesg_type_flags, min_mesg_size);
/* Check arguments */
- if(mesg_type_flags > H5O_MESG_ALL_FLAG)
+ if(mesg_type_flags > H5O_SHMESG_ALL_FLAG)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "unrecognized flags in mesg_type_flags");
/* Get the plist structure */
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 214aaec..8382101 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -265,14 +265,16 @@ H5_DLL herr_t H5Pset_sieve_buf_size(hid_t fapl_id, size_t size);
H5_DLL herr_t H5Pget_sieve_buf_size(hid_t fapl_id, size_t *size/*out*/);
H5_DLL herr_t H5Pset_small_data_block_size(hid_t fapl_id, hsize_t size);
H5_DLL herr_t H5Pget_small_data_block_size(hid_t fapl_id, hsize_t *size/*out*/);
-H5_DLL herr_t H5Pset_latest_format(hid_t plist_id, hbool_t latest);
-H5_DLL herr_t H5Pget_latest_format(hid_t plist_id, hbool_t *latest);
+H5_DLL herr_t H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low,
+ H5F_libver_t high);
+H5_DLL herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low,
+ H5F_libver_t *high);
H5_DLL herr_t H5Pset_journal(hid_t fapl_id, const char *journal_file);
/* Dataset creation property list (DCPL) routines */
H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout);
H5_DLL H5D_layout_t H5Pget_layout(hid_t plist_id);
-H5_DLL herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[]);
+H5_DLL herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]);
H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/);
H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset,
hsize_t size);
diff --git a/src/H5R.c b/src/H5R.c
index 63da596..9ac93b2 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -887,7 +887,7 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID")
/* Get name, length, etc. */
- if((ret_value = H5G_get_refobj_name(file_id, lapl_id, dxpl_id, &oloc, name, size)) < 0)
+ if((ret_value = H5G_get_name_by_addr(file_id, lapl_id, dxpl_id, &oloc, name, size)) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't determine name")
done:
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/H5SL.c b/src/H5SL.c
index 53c0f2d..a720182 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -90,61 +90,93 @@
#define H5SL_LOCATE_FIND_FOUND(SLIST,X,UPDATE,I) \
HGOTO_DONE(X);
-/* Define a code template for updating the "update" vector for the "DOUPDATE" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_YES_UPDATE(X,UPDATE,I) \
- UPDATE[I]=&X->forward[I];
-/* Define a code template for _NOT_ updating the "update" vector for the "DOUPDATE" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_NO_UPDATE(X,UPDATE,I)
+/* Define a code template for "OP"s that update the "update" vector for the H5SL_LOCATE macro */
+#define H5SL_LOCATE_INSERT_UPDATE(X, UPDATE, I) \
+ UPDATE[I] = &X->forward[I];
+#define H5SL_LOCATE_REMOVE_UPDATE(X, UPDATE, I) \
+ UPDATE[I] = &X->forward[I];
+
+/* Define a code template for "OP"s that _DON'T_ update the "update" vector for the H5SL_LOCATE macro */
+#define H5SL_LOCATE_SEARCH_UPDATE(X, UPDATE, I)
+#define H5SL_LOCATE_FIND_UPDATE(X, UPDATE, I)
+
/* Define a code template for comparing scalar keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SCALAR_CMP(TYPE,PKEY1,PKEY2) \
- (*(TYPE *)PKEY1<*(TYPE *)PKEY2)
+#define H5SL_LOCATE_SCALAR_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+ (*(TYPE *)((PNODE)->key) < *(TYPE *)PKEY)
/* Define a code template for comparing string keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_STRING_CMP(TYPE,PKEY1,PKEY2) \
- (HDstrcmp(PKEY1,PKEY2)<0)
+#define H5SL_LOCATE_STRING_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+ (((PNODE)->hashval == HASHVAL) ? (HDstrcmp((PNODE)->key, PKEY) < 0) : ((PNODE)->hashval < HASHVAL))
+
+/* Define a code template for comparing H5_obj_t keys for the "CMP" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_OBJ_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+ ((((TYPE *)((PNODE)->key))->fileno < ((TYPE *)PKEY)->fileno) ? TRUE : (((TYPE *)((PNODE)->key))->addr < ((TYPE *)PKEY)->addr))
+
/* Define a code template for comparing scalar keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SCALAR_EQ(TYPE,PKEY1,PKEY2) \
- (*(TYPE *)PKEY1==*(TYPE *)PKEY2)
+#define H5SL_LOCATE_SCALAR_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+ (*(TYPE *)((PNODE)->key) == *(TYPE *)PKEY)
/* Define a code template for comparing string keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_STRING_EQ(TYPE,PKEY1,PKEY2) \
- (HDstrcmp(PKEY1,PKEY2)==0)
+#define H5SL_LOCATE_STRING_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+ (((PNODE)->hashval == HASHVAL) && (HDstrcmp(((PNODE)->key), PKEY) == 0))
+
+/* Define a code template for comparing H5_obj_t keys for the "EQ" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_OBJ_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+ ((((TYPE *)((PNODE)->key))->fileno == ((TYPE *)PKEY)->fileno) && (((TYPE *)((PNODE)->key))->addr == ((TYPE *)PKEY)->addr))
+
+
+/* Define a code template for initializing the hash value for scalar keys for the "HASHINIT" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_SCALAR_HASHINIT(KEY, HASHVAL)
+
+/* Define a code template for initializing the hash value for string keys for the "HASHINIT" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_STRING_HASHINIT(KEY, HASHVAL) \
+ HASHVAL = H5_hash_string(KEY);
+
+/* Define a code template for initializing the hash value for H5_obj_t keys for the "HASHINIT" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_OBJ_HASHINIT(KEY, HASHVAL)
+
/* Macro used to find node for operation */
-#define H5SL_LOCATE(OP,DOUPDATE,CMP,SLIST,X,UPDATE,I,TYPE,KEY,CHECKED) \
- CHECKED=NULL; \
- for(I=(int)SLIST->curr_level; I>=0; I--) { \
- if(X->forward[I]!=CHECKED) { \
- while(X->forward[I] && H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE,X->forward[I]->key,KEY) ) \
- X=X->forward[I]; \
- CHECKED=X->forward[I]; \
+#define H5SL_LOCATE(OP, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+{ \
+ H5SL_node_t *_checked; /* Pointer to last node checked */ \
+ int _i; /* Local index variable */ \
+ \
+ _checked = NULL; \
+ H5_GLUE3(H5SL_LOCATE_,CMP,_HASHINIT)(KEY, HASHVAL) \
+ for(_i = (int)SLIST->curr_level; _i >= 0; _i--) { \
+ if(X->forward[_i] != _checked) { \
+ while(X->forward[_i] && H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL) ) \
+ X = X->forward[_i]; \
+ _checked = X->forward[_i]; \
} /* end if */ \
- H5_GLUE3(H5SL_LOCATE_,DOUPDATE,_UPDATE)(X,UPDATE,I) \
+ H5_GLUE3(H5SL_LOCATE_,OP,_UPDATE)(X, UPDATE, _i) \
} /* end for */ \
- X=X->forward[0]; \
- if(X!=NULL && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE,X->key,KEY) ) { \
+ X = X->forward[0]; \
+ if(X != NULL && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, X, KEY, HASHVAL) ) { \
/* What to do when a node is found */ \
- H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST,X,UPDATE,I) \
- } /* end if */
+ H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST, X, UPDATE, _i) \
+ } /* end if */ \
+}
/* Macro used to insert node */
-#define H5SL_INSERT(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(INSERT, YES, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_INSERT(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(INSERT, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Macro used to remove node */
-#define H5SL_REMOVE(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(REMOVE, YES, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_REMOVE(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(REMOVE, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Macro used to search for node */
-#define H5SL_SEARCH(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(SEARCH, NO, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_SEARCH(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(SEARCH, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Macro used to find a node */
-#define H5SL_FIND(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(FIND, NO, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_FIND(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(FIND, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Private typedefs & structs */
@@ -154,6 +186,7 @@ struct H5SL_node_t {
const void *key; /* Pointer to node's key */
void *item; /* Pointer to node's item */
size_t level; /* The level of this node */
+ uint32_t hashval; /* Hash value for key (only for strings, currently) */
struct H5SL_node_t **forward; /* Array of forward pointers from this node */
struct H5SL_node_t *backward; /* Backward pointer from this node */
};
@@ -175,7 +208,7 @@ struct H5SL_t {
/* Static functions */
static size_t H5SL_random_level(int p1, size_t max_level);
-static H5SL_node_t * H5SL_new_node(size_t lvl, void *item, const void *key);
+static H5SL_node_t * H5SL_new_node(size_t lvl, void *item, const void *key, uint32_t hashval);
static H5SL_node_t *H5SL_insert_common(H5SL_t *slist, void *item, const void *key);
static herr_t H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
static herr_t H5SL_close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
@@ -287,24 +320,25 @@ H5SL_random_level(int p1, size_t max_level)
REVISION LOG
--------------------------------------------------------------------------*/
static H5SL_node_t *
-H5SL_new_node(size_t lvl, void *item, const void *key)
+H5SL_new_node(size_t lvl, void *item, const void *key, uint32_t hashval)
{
H5SL_node_t *ret_value; /* New skip list node */
- FUNC_ENTER_NOAPI_NOINIT(H5SL_new_node);
+ FUNC_ENTER_NOAPI_NOINIT(H5SL_new_node)
/* Allocate the node */
- if((ret_value=H5FL_ARR_MALLOC(H5SL_node_ptr_t,(lvl+1)))==NULL)
- HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_ARR_MALLOC(H5SL_node_ptr_t, (lvl + 1))))
+ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed")
/* Initialize node */
- ret_value->key=key;
- ret_value->item=item;
- ret_value->level=lvl;
- ret_value->forward=(H5SL_node_t **)((unsigned char *)ret_value+sizeof(H5SL_node_t));
+ ret_value->key = key;
+ ret_value->item = item;
+ ret_value->level = lvl;
+ ret_value->hashval = hashval;
+ ret_value->forward = (H5SL_node_t **)((unsigned char *)ret_value + sizeof(H5SL_node_t));
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SL_new_node() */
@@ -333,8 +367,8 @@ static H5SL_node_t *
H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
{
H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
+ uint32_t hashval = 0; /* Hash value for key */
size_t lvl; /* Level of new node */
int i; /* Local index value */
H5SL_node_t *ret_value; /* Return value */
@@ -356,27 +390,31 @@ H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_INSERT(SCALAR, slist, x, update, i, const int, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_INSERT(SCALAR, slist, x, update, i, const haddr_t, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_INSERT(STRING, slist, x, update, i, char *, key, checked)
+ H5SL_INSERT(STRING, slist, x, update, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_INSERT(SCALAR, slist, x, update, i, const hsize_t, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_INSERT(SCALAR, slist, x, update, i, const unsigned, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_INSERT(SCALAR, slist, x, update, i, const size_t, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_INSERT(OBJ, slist, x, update, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -396,8 +434,8 @@ H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
} /* end if */
/* Create new node of proper level */
- if((x=H5SL_new_node(lvl,item,key))==NULL)
- HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"can't create new skip list node");
+ if(NULL == (x = H5SL_new_node(lvl, item, key, hashval)))
+ HGOTO_ERROR(H5E_SLIST ,H5E_NOSPACE, NULL, "can't create new skip list node")
/* Update the backward links */
if(*update[0]!=NULL) {
@@ -571,7 +609,7 @@ H5SL_create(H5SL_type_t type, double p, size_t max_level)
/* Check args */
HDassert(p>0.0 && p<1.0);
HDassert(max_level>0 && max_level<=H5SL_LEVEL_MAX);
- HDassert(type>=H5SL_TYPE_INT && type<=H5SL_TYPE_SIZE);
+ HDassert(type>=H5SL_TYPE_INT && type<=H5SL_TYPE_OBJ);
/* Allocate skip list structure */
if((new_slist=H5FL_MALLOC(H5SL_t))==NULL)
@@ -588,8 +626,8 @@ H5SL_create(H5SL_type_t type, double p, size_t max_level)
new_slist->nobjs=0;
/* Allocate the header node */
- if((header=H5SL_new_node(max_level-1,NULL,NULL))==NULL)
- HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (header = H5SL_new_node((max_level - 1), NULL, NULL, ULONG_MAX)))
+ HGOTO_ERROR(H5E_SLIST ,H5E_NOSPACE, NULL, "can't create new skip list node")
/* Initialize header node's forward pointers */
for(u=0; u<max_level; u++)
@@ -764,9 +802,8 @@ void *
H5SL_remove(H5SL_t *slist, const void *key)
{
H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_remove);
@@ -786,27 +823,31 @@ H5SL_remove(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const int, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const haddr_t, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_REMOVE(STRING, slist, x, update, i, char *, key, checked)
+ H5SL_REMOVE(STRING, slist, x, update, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const hsize_t, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const unsigned, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const size_t, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_REMOVE(OBJ, slist, x, update, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -911,9 +952,8 @@ H5SL_remove_first(H5SL_t *slist)
void *
H5SL_search(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_search);
@@ -933,27 +973,31 @@ H5SL_search(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -990,9 +1034,8 @@ done:
void *
H5SL_less(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_less);
@@ -1012,27 +1055,31 @@ H5SL_less(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -1082,9 +1129,8 @@ done:
void *
H5SL_greater(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_greater);
@@ -1104,27 +1150,31 @@ H5SL_greater(H5SL_t *slist, const void *key)
x = slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -1164,9 +1214,8 @@ done:
H5SL_node_t *
H5SL_find(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
H5SL_node_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_find);
@@ -1186,27 +1235,31 @@ H5SL_find(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_FIND(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_FIND(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_FIND(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_FIND(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_FIND(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_FIND(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_FIND(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const size_t, key, -)
+ break;
+
+ case H5SL_TYPE_OBJ:
+ H5SL_FIND(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h
index 98c1b84..9f73893 100644
--- a/src/H5SLprivate.h
+++ b/src/H5SLprivate.h
@@ -46,7 +46,8 @@ typedef enum {
H5SL_TYPE_STR, /* Skip list keys are 'char *'s (ie. strings) */
H5SL_TYPE_HSIZE, /* Skip list keys are 'hsize_t's */
H5SL_TYPE_UNSIGNED, /* Skip list keys are 'unsigned's */
- H5SL_TYPE_SIZE /* Skip list keys are 'size_t's */
+ H5SL_TYPE_SIZE, /* Skip list keys are 'size_t's */
+ H5SL_TYPE_OBJ /* Skip list keys are 'H5_obj_t's */
} H5SL_type_t;
/**********/
diff --git a/src/H5SM.c b/src/H5SM.c
index 179a526..9607f23 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -220,7 +220,7 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d
/* Check for sharing attributes in this file, which means that creation
* indices must be tracked on object header message in the file.
*/
- if(type_flags_used & H5O_MESG_ATTR_FLAG)
+ if(type_flags_used & H5O_SHMESG_ATTR_FLAG)
f->shared->store_msg_crt_idx = TRUE;
/* Write shared message information to the superblock extension */
@@ -263,22 +263,18 @@ H5SM_type_to_flag(unsigned type_id, unsigned *type_flag)
/* Translate the H5O type_id into an H5SM type flag */
switch(type_id) {
+ case H5O_FILL_ID:
+ type_id = H5O_FILL_NEW_ID;
+ /* Fall through... */
+
case H5O_SDSPACE_ID:
- *type_flag = H5O_MESG_SDSPACE_FLAG;
- break;
case H5O_DTYPE_ID:
- *type_flag = H5O_MESG_DTYPE_FLAG;
- break;
- case H5O_FILL_ID:
case H5O_FILL_NEW_ID:
- *type_flag = H5O_MESG_FILL_FLAG;
- break;
case H5O_PLINE_ID:
- *type_flag = H5O_MESG_PLINE_FLAG;
- break;
case H5O_ATTR_ID:
- *type_flag = H5O_MESG_ATTR_FLAG;
+ *type_flag = (unsigned)1 << type_id;
break;
+
default:
HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unknown message type ID")
} /* end switch */
@@ -307,7 +303,7 @@ done:
ssize_t
H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id)
{
- ssize_t x;
+ size_t x;
unsigned type_flag;
ssize_t ret_value = FAIL;
@@ -322,7 +318,7 @@ H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id)
*/
for(x = 0; x < table->num_indexes; ++x)
if(table->indexes[x].mesg_types & type_flag)
- HGOTO_DONE(x)
+ HGOTO_DONE((ssize_t)x)
/* At this point, ret_value is either the location of the correct
* index or it's still FAIL because we didn't find an index.
@@ -1828,7 +1824,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id)
/* Check for sharing attributes in this file, which means that creation
* indices must be tracked on object header message in the file.
*/
- if(index_flags[u] & H5O_MESG_ATTR_FLAG)
+ if(index_flags[u] & H5O_SHMESG_ATTR_FLAG)
shared->store_msg_crt_idx = TRUE;
} /* end for */
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 5d01fec..c603251 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -42,6 +42,7 @@ static hssize_t H5S_all_serial_size(const H5S_t *space);
static herr_t H5S_all_serialize(const H5S_t *space, uint8_t *buf);
static herr_t H5S_all_deserialize(H5S_t *space, const uint8_t *buf);
static herr_t H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+static herr_t H5S_all_offset(const H5S_t *space, hsize_t *off);
static htri_t H5S_all_is_contiguous(const H5S_t *space);
static htri_t H5S_all_is_single(const H5S_t *space);
static htri_t H5S_all_is_regular(const H5S_t *space);
@@ -70,6 +71,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{
H5S_all_serialize,
H5S_all_deserialize,
H5S_all_bounds,
+ H5S_all_offset,
H5S_all_is_contiguous,
H5S_all_is_single,
H5S_all_is_regular,
@@ -585,26 +587,61 @@ done:
herr_t
H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
- int rank; /* Dataspace rank */
- int i; /* index variable */
+ unsigned rank; /* Dataspace rank */
+ unsigned i; /* index variable */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_all_bounds);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_all_bounds)
- assert(space);
- assert(start);
- assert(end);
+ HDassert(space);
+ HDassert(start);
+ HDassert(end);
/* Get the dataspace extent rank */
- rank=space->extent.rank;
+ rank = space->extent.rank;
/* Just copy over the complete extent */
- for(i=0; i<rank; i++) {
- start[i]=0;
- end[i]=space->extent.size[i]-1;
+ for(i = 0; i < rank; i++) {
+ start[i] = 0;
+ end[i] = space->extent.size[i] - 1;
} /* end for */
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* H5Sget_all_bounds() */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5S_all_bounds() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_all_offset
+ PURPOSE
+ Gets the linear offset of the first element for the selection.
+ USAGE
+ herr_t H5S_all_offset(space, offset)
+ const H5S_t *space; IN: Dataspace pointer of selection to query
+ hsize_t *offset; OUT: Linear offset of first element in selection
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the linear offset (in "units" of elements) of the first element
+ selected within the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Calling this function on a "none" selection returns fail.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_all_offset(const H5S_t *space, hsize_t *offset)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_all_offset)
+
+ HDassert(space);
+ HDassert(offset);
+
+ /* 'All' selections always start at offset 0 */
+ *offset = 0;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5S_all_offset() */
/*--------------------------------------------------------------------------
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 8acbfd5..455a251 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -57,6 +57,7 @@ static hssize_t H5S_hyper_serial_size(const H5S_t *space);
static herr_t H5S_hyper_serialize(const H5S_t *space, uint8_t *buf);
static herr_t H5S_hyper_deserialize(H5S_t *space, const uint8_t *buf);
static herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+static herr_t H5S_hyper_offset(const H5S_t *space, hsize_t *offset);
static htri_t H5S_hyper_is_contiguous(const H5S_t *space);
static htri_t H5S_hyper_is_single(const H5S_t *space);
static htri_t H5S_hyper_is_regular(const H5S_t *space);
@@ -90,6 +91,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{
H5S_hyper_serialize,
H5S_hyper_deserialize,
H5S_hyper_bounds,
+ H5S_hyper_offset,
H5S_hyper_is_contiguous,
H5S_hyper_is_single,
H5S_hyper_is_regular,
@@ -275,12 +277,17 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
/* Don't flatten adjacent elements into contiguous block if the
* element size is 0. This is for the H5S_select_shape_same() code.
*/
- if(iter->elmt_size>0) {
+ if(iter->elmt_size > 0) {
/* Check for any "contiguous" blocks that can be flattened */
- for(u=rank-1; u>0; u--) {
- if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u])
+ for(u = (rank - 1); u > 0; u--) {
+ if(tdiminfo[u].count == 1 && tdiminfo[u].block == mem_size[u]) {
cont_dim++;
+ iter->u.hyp.flattened[u] = TRUE;
+ } /* end if */
+ else
+ iter->u.hyp.flattened[u] = FALSE;
} /* end for */
+ iter->u.hyp.flattened[0] = FALSE;
} /* end if */
/* Check if the regular selection can be "flattened" */
@@ -430,23 +437,59 @@ H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
/* Check for a single "regular" hyperslab */
if(iter->u.hyp.diminfo_valid) {
/* Check if this is a "flattened" regular hyperslab selection */
- if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<iter->rank) {
- unsigned flat_dim; /* The rank of the flattened dimension */
+ if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) {
+ int u, v; /* Dimension indices */
+
+ /* Set the starting rank of both the "natural" & "flattened" dimensions */
+ u = iter->rank - 1;
+ v = iter->u.hyp.iter_rank - 1;
+
+ /* Construct the "natural" dimensions from a set of flattened coordinates */
+ while(u >= 0) {
+ if(iter->u.hyp.flattened[u]) {
+ int begin = u; /* The rank of the first flattened dimension */
+
+ /* Walk up through as many flattened dimensions as possible */
+ do {
+ u--;
+ } while(u >= 0 && iter->u.hyp.flattened[u]);
- /* Get the rank of the flattened dimension */
- flat_dim=iter->u.hyp.iter_rank-1;
+ /* Compensate for possibly overshooting dim 0 */
+ if(u < 0)
+ u = 0;
- /* Copy the coordinates up to where things got flattened */
- HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*flat_dim);
+ /* Sanity check */
+ HDassert(v >= 0);
- /* Compute the coordinates for the flattened dimensions */
- H5V_array_calc(iter->u.hyp.off[flat_dim],iter->rank-flat_dim,&(iter->dims[flat_dim]),&(coords[flat_dim]));
+ /* Compute the coords for the flattened dimensions */
+ H5V_array_calc(iter->u.hyp.off[v], (unsigned)((begin - u) + 1), &(iter->dims[u]), &(coords[u]));
+
+ /* Continue to faster dimension in both indices */
+ u--;
+ v--;
+ } /* end if */
+ else {
+ /* Walk up through as many non-flattened dimensions as possible */
+ while(u >= 0 && !iter->u.hyp.flattened[u]) {
+ /* Sanity check */
+ HDassert(v >= 0);
+
+ /* Copy the coordinate */
+ coords[u] = iter->u.hyp.off[v];
+
+ /* Continue to faster dimension in both indices */
+ u--;
+ v--;
+ } /* end while */
+ } /* end else */
+ } /* end while */
+ HDassert(v < 0);
} /* end if */
else
- HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*iter->rank);
+ HDmemcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank);
} /* end if */
else
- HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*iter->rank);
+ HDmemcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank);
FUNC_LEAVE_NOAPI(SUCCEED);
} /* H5S_hyper_iter_coords() */
@@ -2515,7 +2558,7 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc
hid_t dsid; IN: Dataspace ID of selection to query
hsize_t startblock; IN: Hyperslab block to start with
hsize_t numblocks; IN: Number of hyperslab blocks to get
- hsize_t *buf; OUT: List of hyperslab blocks selected
+ hsize_t buf[]; OUT: List of hyperslab blocks selected
RETURNS
Non-negative on success, negative on failure
DESCRIPTION
@@ -2536,13 +2579,14 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, hsize_t numblocks, hsize_t *buf)
+H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
+ hsize_t numblocks, hsize_t buf[/*numblocks*/])
{
H5S_t *space = NULL; /* Dataspace to modify selection of */
herr_t ret_value; /* return value */
FUNC_ENTER_API(H5Sget_select_hyper_blocklist, FAIL);
- H5TRACE4("e", "ihh*h", spaceid, startblock, numblocks, buf);
+ H5TRACE4("e", "ihh*[a2]h", spaceid, startblock, numblocks, buf);
/* Check args */
if(buf==NULL)
@@ -2708,6 +2752,114 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_hyper_offset
+ PURPOSE
+ Gets the linear offset of the first element for the selection.
+ USAGE
+ herr_t H5S_hyper_offset(space, offset)
+ const H5S_t *space; IN: Dataspace pointer of selection to query
+ hsize_t *offset; OUT: Linear offset of first element in selection
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the linear offset (in "units" of elements) of the first element
+ selected within the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Calling this function on a "none" selection returns fail.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_offset(const H5S_t *space, hsize_t *offset)
+{
+ const hssize_t *sel_offset; /* Pointer to the selection's offset */
+ const hsize_t *dim_size; /* Pointer to a dataspace's extent */
+ hsize_t accum; /* Accumulator for dimension sizes */
+ int rank; /* Dataspace rank */
+ int i; /* index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_hyper_offset, FAIL)
+
+ HDassert(space);
+ HDassert(offset);
+
+ /* Start at linear offset 0 */
+ *offset = 0;
+
+ /* Set up pointers to arrays of values */
+ rank = space->extent.rank;
+ sel_offset = space->select.offset;
+ dim_size = space->extent.size;
+
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab->diminfo_valid) {
+ const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Local alias for diminfo */
+
+ /* Loop through starting coordinates, calculating the linear offset */
+ accum = 1;
+ for(i = (rank - 1); i >= 0; i--) {
+ hssize_t hyp_offset = (hssize_t)diminfo[i].start + sel_offset[i]; /* Hyperslab's offset in this dimension */
+
+ /* Check for offset moving selection out of the dataspace */
+ if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i])
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+
+ /* Add the hyperslab's offset in this dimension to the total linear offset */
+ *offset += hyp_offset * accum;
+
+ /* Increase the accumulator */
+ accum *= dim_size[i];
+ } /* end for */
+ } /* end if */
+ else {
+ const H5S_hyper_span_t *span; /* Hyperslab span node */
+ hsize_t dim_accum[H5S_MAX_RANK]; /* Accumulators, for each dimension */
+
+ /* Calculate the accumulator for each dimension */
+ accum = 1;
+ for(i = (rank - 1); i >= 0; i--) {
+ /* Set the accumulator for this dimension */
+ dim_accum[i] = accum;
+
+ /* Increase the accumulator */
+ accum *= dim_size[i];
+ } /* end for */
+
+ /* Get information for the first span, in the slowest changing dimension */
+ span = space->select.sel_info.hslab->span_lst->head;
+
+ /* Work down the spans, computing the linear offset */
+ i = 0;
+ while(span) {
+ hssize_t hyp_offset = (hssize_t)span->low + sel_offset[i]; /* Hyperslab's offset in this dimension */
+
+ /* Check for offset moving selection out of the dataspace */
+ if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i])
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+
+ /* Add the hyperslab's offset in this dimension to the total linear offset */
+ *offset += hyp_offset * dim_accum[i];
+
+ /* Advance to first span in "down" dimension */
+ if(span->down) {
+ HDassert(span->down->head);
+ span = span->down->head;
+ } /* end if */
+ else
+ span = NULL;
+ i++;
+ } /* end while */
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_hyper_offset() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_hyper_is_contiguous
PURPOSE
Check if a hyperslab selection is contiguous within the dataspace extent.
@@ -2727,12 +2879,10 @@ done:
htri_t
H5S_hyper_is_contiguous(const H5S_t *space)
{
- H5S_hyper_span_info_t *spans; /* Hyperslab span info node */
- H5S_hyper_span_t *span; /* Hyperslab span node */
- unsigned u; /* index variable */
unsigned small_contiguous, /* Flag for small contiguous block */
large_contiguous; /* Flag for large contiguous block */
- htri_t ret_value=FALSE; /* return value */
+ unsigned u; /* index variable */
+ htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOFUNC(H5S_hyper_is_contiguous);
@@ -2791,6 +2941,9 @@ H5S_hyper_is_contiguous(const H5S_t *space)
ret_value=TRUE;
} /* end if */
else {
+ H5S_hyper_span_info_t *spans; /* Hyperslab span info node */
+ H5S_hyper_span_t *span; /* Hyperslab span node */
+
/*
* For a hyperslab to be contiguous, it must have only one block and
* (either it's size must be the same as the dataspace extent's in all
@@ -4127,35 +4280,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() */
@@ -4183,25 +4338,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/H5Snone.c b/src/H5Snone.c
index 89a1875..88ab67f 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -43,6 +43,7 @@ static hssize_t H5S_none_serial_size(const H5S_t *space);
static herr_t H5S_none_serialize(const H5S_t *space, uint8_t *buf);
static herr_t H5S_none_deserialize(H5S_t *space, const uint8_t *buf);
static herr_t H5S_none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+static herr_t H5S_none_offset(const H5S_t *space, hsize_t *off);
static htri_t H5S_none_is_contiguous(const H5S_t *space);
static htri_t H5S_none_is_single(const H5S_t *space);
static htri_t H5S_none_is_regular(const H5S_t *space);
@@ -71,6 +72,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{
H5S_none_serialize,
H5S_none_deserialize,
H5S_none_bounds,
+ H5S_none_offset,
H5S_none_is_contiguous,
H5S_none_is_single,
H5S_none_is_regular,
@@ -565,11 +567,43 @@ H5S_none_bounds(const H5S_t UNUSED *space, hsize_t UNUSED *start, hsize_t UNUSED
/*--------------------------------------------------------------------------
NAME
+ H5S_none_offset
+ PURPOSE
+ Gets the linear offset of the first element for the selection.
+ USAGE
+ herr_t H5S_none_offset(space, offset)
+ const H5S_t *space; IN: Dataspace pointer of selection to query
+ hsize_t *offset; OUT: Linear offset of first element in selection
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the linear offset (in "units" of elements) of the first element
+ selected within the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Calling this function on a "none" selection returns fail.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_none_offset(const H5S_t *space, hsize_t *offset)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_none_offset)
+
+ HDassert(space);
+ HDassert(offset);
+
+ FUNC_LEAVE_NOAPI(FAIL)
+} /* H5S_none_offset() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_none_is_contiguous
PURPOSE
Check if a "none" selection is contiguous within the dataspace extent.
USAGE
- htri_t H5S_all_is_contiguous(space)
+ htri_t H5S_none_is_contiguous(space)
H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
@@ -767,7 +801,7 @@ done:
PURPOSE
Create a list of offsets & lengths for a selection
USAGE
- herr_t H5S_all_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len)
+ herr_t H5S_none_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len)
H5S_t *space; IN: Dataspace containing selection to use.
unsigned flags; IN: Flags for extra information about operation
H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last
@@ -816,4 +850,5 @@ H5S_none_get_seq_list(const H5S_t UNUSED *space, unsigned UNUSED flags, H5S_sel_
*nelem=0;
FUNC_LEAVE_NOAPI(SUCCEED);
-} /* end H5S_all_get_seq_list() */
+} /* end H5S_none_get_seq_list() */
+
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 71cc43b..e13e6be 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -133,8 +133,10 @@ typedef hssize_t (*H5S_sel_serial_size_func_t)(const H5S_t *space);
typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t *buf);
/* Method to store create selection from "serialized" form (a byte sequence suitable for storing on disk) */
typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t *space, const uint8_t *buf);
-/* Method to determine to smallest n-D bounding box containing the current selection */
+/* Method to determine smallest n-D bounding box containing the current selection */
typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsize_t *end);
+/* Method to determine linear offset of initial element in selection within dataspace */
+typedef herr_t (*H5S_sel_offset_func_t)(const H5S_t *space, hsize_t *offset);
/* Method to determine if current selection is contiguous */
typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space);
/* Method to determine if current selection is a single block */
@@ -159,6 +161,7 @@ typedef struct {
H5S_sel_serialize_func_t serialize; /* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */
H5S_sel_deserialize_func_t deserialize; /* Method to store create selection from "serialized" form (a byte sequence suitable for storing on disk) */
H5S_sel_bounds_func_t bounds; /* Method to determine to smallest n-D bounding box containing the current selection */
+ H5S_sel_offset_func_t offset; /* Method to determine linear offset of initial element in selection within dataspace */
H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */
H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */
H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */
@@ -169,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/H5Spoint.c b/src/H5Spoint.c
index eb37945..cf7751e 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -44,6 +44,7 @@ static hssize_t H5S_point_serial_size(const H5S_t *space);
static herr_t H5S_point_serialize(const H5S_t *space, uint8_t *buf);
static herr_t H5S_point_deserialize(H5S_t *space, const uint8_t *buf);
static herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+static herr_t H5S_point_offset(const H5S_t *space, hsize_t *off);
static htri_t H5S_point_is_contiguous(const H5S_t *space);
static htri_t H5S_point_is_single(const H5S_t *space);
static htri_t H5S_point_is_regular(const H5S_t *space);
@@ -72,6 +73,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S_point_serialize,
H5S_point_deserialize,
H5S_point_bounds,
+ H5S_point_offset,
H5S_point_is_contiguous,
H5S_point_is_single,
H5S_point_is_regular,
@@ -380,71 +382,70 @@ H5S_point_iter_release (H5S_sel_iter_t UNUSED * iter)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_point_add (H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t **_coord)
+H5S_point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *coord)
{
H5S_pnt_node_t *top, *curr, *new_node; /* Point selection nodes */
- const hsize_t *coord=(const hsize_t *)_coord; /* Pointer to the actual coordinates */
- unsigned i; /* Counter */
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned i; /* Counter */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_point_add);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_add)
- assert(space);
- assert(num_elem>0);
- assert(coord);
- assert(op==H5S_SELECT_SET || op==H5S_SELECT_APPEND || op==H5S_SELECT_PREPEND);
+ HDassert(space);
+ HDassert(num_elem > 0);
+ HDassert(coord);
+ HDassert(op == H5S_SELECT_SET || op == H5S_SELECT_APPEND || op == H5S_SELECT_PREPEND);
- top=curr=NULL;
- for(i=0; i<num_elem; i++) {
+ top = curr = NULL;
+ for(i = 0; i < num_elem; i++) {
/* Allocate space for the new node */
- if((new_node = H5FL_MALLOC(H5S_pnt_node_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node");
+ if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node")
- if((new_node->pnt = H5MM_malloc(space->extent.rank*sizeof(hsize_t)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information");
+ if(NULL == (new_node->pnt = H5MM_malloc(space->extent.rank * sizeof(hsize_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information")
/* Copy over the coordinates */
- HDmemcpy(new_node->pnt,coord+(i*space->extent.rank),(space->extent.rank*sizeof(hsize_t)));
+ HDmemcpy(new_node->pnt, coord + (i * space->extent.rank), (space->extent.rank * sizeof(hsize_t)));
/* Link into list */
- new_node->next=NULL;
- if(top==NULL)
- top=new_node;
+ new_node->next = NULL;
+ if(top == NULL)
+ top = new_node;
else
- curr->next=new_node;
- curr=new_node;
+ curr->next = new_node;
+ curr = new_node;
} /* end for */
/* Insert the list of points selected in the proper place */
- if(op==H5S_SELECT_SET || op==H5S_SELECT_PREPEND) {
+ if(op == H5S_SELECT_SET || op == H5S_SELECT_PREPEND) {
/* Append current list, if there is one */
- if(space->select.sel_info.pnt_lst->head!=NULL)
- curr->next=space->select.sel_info.pnt_lst->head;
+ if(space->select.sel_info.pnt_lst->head != NULL)
+ curr->next = space->select.sel_info.pnt_lst->head;
/* Put new list in point selection */
- space->select.sel_info.pnt_lst->head=top;
+ space->select.sel_info.pnt_lst->head = top;
} /* end if */
else { /* op==H5S_SELECT_APPEND */
- new_node=space->select.sel_info.pnt_lst->head;
- if(new_node!=NULL) {
- while(new_node->next!=NULL)
- new_node=new_node->next;
+ new_node = space->select.sel_info.pnt_lst->head;
+ if(new_node != NULL) {
+ while(new_node->next != NULL)
+ new_node = new_node->next;
/* Append new list to point selection */
- new_node->next=top;
+ new_node->next = top;
} /* end if */
else
- space->select.sel_info.pnt_lst->head=top;
+ space->select.sel_info.pnt_lst->head = top;
} /* end else */
/* Set the number of elements in the new selection */
- if(op==H5S_SELECT_SET)
- space->select.num_elem=num_elem;
+ if(op == H5S_SELECT_SET)
+ space->select.num_elem = num_elem;
else
- space->select.num_elem+=num_elem;
+ space->select.num_elem += num_elem;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_point_add() */
@@ -505,7 +506,7 @@ H5S_point_release (H5S_t *space)
hid_t dsid; IN: Dataspace ID of selection to modify
H5S_seloper_t op; IN: Operation to perform on current selection
size_t num_elem; IN: Number of elements in COORD array.
- const hsize_t **coord; IN: The location of each element selected
+ const hsize_t *coord; IN: The location of each element selected
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -526,40 +527,38 @@ H5S_point_release (H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
- const hsize_t **coord)
+H5S_select_elements(H5S_t *space, H5S_seloper_t op, size_t num_elem,
+ const hsize_t *coord)
{
- herr_t ret_value=SUCCEED; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_select_elements);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_select_elements)
/* Check args */
- assert(space);
- assert(num_elem);
- assert(coord);
- assert(op==H5S_SELECT_SET || op==H5S_SELECT_APPEND || op==H5S_SELECT_PREPEND);
+ HDassert(space);
+ HDassert(num_elem);
+ HDassert(coord);
+ HDassert(op == H5S_SELECT_SET || op == H5S_SELECT_APPEND || op == H5S_SELECT_PREPEND);
/* If we are setting a new selection, remove current selection first */
- if(op==H5S_SELECT_SET || H5S_GET_SELECT_TYPE(space)!=H5S_SEL_POINTS) {
- if(H5S_SELECT_RELEASE(space)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release point selection");
- } /* end if */
+ if(op == H5S_SELECT_SET || H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS)
+ if(H5S_SELECT_RELEASE(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release point selection")
/* Allocate space for the point selection information if necessary */
- if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_POINTS || space->select.sel_info.pnt_lst==NULL) {
- if((space->select.sel_info.pnt_lst = H5FL_CALLOC(H5S_pnt_list_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate element information");
- } /* end if */
+ if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS || space->select.sel_info.pnt_lst == NULL)
+ if(NULL == (space->select.sel_info.pnt_lst = H5FL_CALLOC(H5S_pnt_list_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate element information")
/* Add points to selection */
- if(H5S_point_add(space,op,num_elem,coord)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert elements");
+ if(H5S_point_add(space, op, num_elem, coord) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert elements")
/* Set selection type */
- space->select.type=H5S_sel_point;
+ space->select.type = H5S_sel_point;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_elements() */
@@ -965,7 +964,7 @@ H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoint
hid_t dsid; IN: Dataspace ID of selection to query
hsize_t startpoint; IN: Element point to start with
hsize_t numpoints; IN: Number of element points to get
- hsize_t *buf; OUT: List of element points selected
+ hsize_t buf[]; OUT: List of element points selected
RETURNS
Non-negative on success, negative on failure
DESCRIPTION
@@ -985,13 +984,14 @@ H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoint
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint, hsize_t numpoints, hsize_t *buf)
+H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint,
+ hsize_t numpoints, hsize_t buf[/*numpoints*/])
{
H5S_t *space = NULL; /* Dataspace to modify selection of */
herr_t ret_value; /* return value */
FUNC_ENTER_API(H5Sget_select_elem_pointlist, FAIL);
- H5TRACE4("e", "ihh*h", spaceid, startpoint, numpoints, buf);
+ H5TRACE4("e", "ihh*[a2]h", spaceid, startpoint, numpoints, buf);
/* Check args */
if(buf==NULL)
@@ -1038,48 +1038,114 @@ static herr_t
H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
H5S_pnt_node_t *node; /* Point node */
- int rank; /* Dataspace rank */
- int i; /* index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned rank; /* Dataspace rank */
+ unsigned u; /* index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_point_bounds);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_bounds)
- assert(space);
- assert(start);
- assert(end);
+ HDassert(space);
+ HDassert(start);
+ HDassert(end);
/* Get the dataspace extent rank */
- rank=space->extent.rank;
+ rank = space->extent.rank;
/* Set the start and end arrays up */
- for(i=0; i<rank; i++) {
- start[i]=HSIZET_MAX;
- end[i]=0;
+ for(u = 0; u < rank; u++) {
+ start[u] = HSIZET_MAX;
+ end[u] = 0;
} /* end for */
/* Iterate through the node, checking the bounds on each element */
- node=space->select.sel_info.pnt_lst->head;
- while(node!=NULL) {
- for(i=0; i<rank; i++) {
+ node = space->select.sel_info.pnt_lst->head;
+ while(node != NULL) {
+ for(u = 0; u < rank; u++) {
/* Check for offset moving selection negative */
- if(((hssize_t)node->pnt[i]+space->select.offset[i])<0)
+ if(((hssize_t)node->pnt[u] + space->select.offset[u]) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
- if(start[i]>(node->pnt[i]+space->select.offset[i]))
- start[i]=node->pnt[i]+space->select.offset[i];
- if(end[i]<(node->pnt[i]+space->select.offset[i]))
- end[i]=node->pnt[i]+space->select.offset[i];
+ if(start[u] > (node->pnt[u] + space->select.offset[u]))
+ start[u] = node->pnt[u] + space->select.offset[u];
+ if(end[u] < (node->pnt[u] + space->select.offset[u]))
+ end[u] = node->pnt[u] + space->select.offset[u];
} /* end for */
- node=node->next;
+ node = node->next;
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_point_bounds() */
/*--------------------------------------------------------------------------
NAME
+ H5S_point_offset
+ PURPOSE
+ Gets the linear offset of the first element for the selection.
+ USAGE
+ herr_t H5S_point_offset(space, offset)
+ const H5S_t *space; IN: Dataspace pointer of selection to query
+ hsize_t *offset; OUT: Linear offset of first element in selection
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the linear offset (in "units" of elements) of the first element
+ selected within the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Calling this function on a "none" selection returns fail.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_point_offset(const H5S_t *space, hsize_t *offset)
+{
+ const hsize_t *pnt; /* Pointer to a selected point's coordinates */
+ const hssize_t *sel_offset; /* Pointer to the selection's offset */
+ const hsize_t *dim_size; /* Pointer to a dataspace's extent */
+ hsize_t accum; /* Accumulator for dimension sizes */
+ int rank; /* Dataspace rank */
+ int i; /* index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_point_offset, FAIL)
+
+ HDassert(space);
+ HDassert(offset);
+
+ /* Start at linear offset 0 */
+ *offset = 0;
+
+ /* Set up pointers to arrays of values */
+ pnt = space->select.sel_info.pnt_lst->head->pnt;
+ sel_offset = space->select.offset;
+ dim_size = space->extent.size;
+
+ /* Loop through coordinates, calculating the linear offset */
+ rank = space->extent.rank;
+ accum = 1;
+ for(i = (rank - 1); i >= 0; i--) {
+ hssize_t pnt_offset = (hssize_t)pnt[i] + sel_offset[i]; /* Point's offset in this dimension */
+
+ /* Check for offset moving selection out of the dataspace */
+ if(pnt_offset < 0 || (hsize_t)pnt_offset >= dim_size[i])
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+
+ /* Add the point's offset in this dimension to the total linear offset */
+ *offset += pnt_offset * accum;
+
+ /* Increase the accumulator */
+ accum *= dim_size[i];
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_point_offset() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_point_is_contiguous
PURPOSE
Check if a point selection is contiguous within the dataspace extent.
@@ -1258,7 +1324,7 @@ H5S_point_adjust_u(H5S_t *space, const hsize_t *offset)
hid_t dsid; IN: Dataspace ID of selection to modify
H5S_seloper_t op; IN: Operation to perform on current selection
size_t num_elem; IN: Number of elements in COORD array.
- const hsize_t **coord; IN: The location of each element selected
+ const hsize_t *coord; IN: The location of each element selected
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -1280,32 +1346,32 @@ H5S_point_adjust_u(H5S_t *space, const hsize_t *offset)
--------------------------------------------------------------------------*/
herr_t
H5Sselect_elements(hid_t spaceid, H5S_seloper_t op, size_t num_elem,
- const hsize_t **coord)
+ const hsize_t *coord)
{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- herr_t ret_value; /* return value */
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ herr_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Sselect_elements, FAIL);
- H5TRACE4("e", "iSsz**h", spaceid, op, num_elem, coord);
+ FUNC_ENTER_API(H5Sselect_elements, FAIL)
+ H5TRACE4("e", "iSsz*h", spaceid, op, num_elem, coord);
/* Check args */
- if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace");
- if (H5S_SCALAR==H5S_GET_EXTENT_TYPE(space))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "point doesn't support H5S_SCALAR space");
- if (H5S_NULL==H5S_GET_EXTENT_TYPE(space))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "point doesn't support H5S_NULL space");
- if(coord==NULL || num_elem==0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "elements not specified");
- if(!(op==H5S_SELECT_SET || op==H5S_SELECT_APPEND || op==H5S_SELECT_PREPEND))
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "unsupported operation attempted");
+ if(NULL == (space = H5I_object_verify(spaceid, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ if(H5S_SCALAR == H5S_GET_EXTENT_TYPE(space))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "point doesn't support H5S_SCALAR space")
+ if(H5S_NULL == H5S_GET_EXTENT_TYPE(space))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "point doesn't support H5S_NULL space")
+ if(coord == NULL || num_elem == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "elements not specified")
+ if(!(op == H5S_SELECT_SET || op == H5S_SELECT_APPEND || op == H5S_SELECT_PREPEND))
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "unsupported operation attempted")
/* Call the real element selection routine */
- if((ret_value=H5S_select_elements(space,op,num_elem,coord))<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't select elements");
+ if((ret_value = H5S_select_elements(space, op, num_elem, coord)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't select elements")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* H5Sselect_elements() */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index ec48de9..bd27f09 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -78,8 +78,9 @@ typedef struct {
/* "Flattened" regular hyperslab selection fields */
H5S_hyper_dim_t diminfo[H5S_MAX_RANK]; /* "Flattened" regular selection information */
- hsize_t size[H5S_MAX_RANK]; /* "Flattened" dataspace extent information */
- hssize_t sel_off[H5S_MAX_RANK]; /* "Flattened" selection offset information */
+ hsize_t size[H5S_MAX_RANK]; /* "Flattened" dataspace extent information */
+ hssize_t sel_off[H5S_MAX_RANK]; /* "Flattened" selection offset information */
+ hbool_t flattened[H5S_MAX_RANK]; /* Whether this dimension has been flattened */
/* Irregular hyperslab selection fields */
H5S_hyper_span_info_t *spans; /* Pointer to copy of the span tree */
@@ -152,6 +153,7 @@ typedef struct H5S_iostats_t {
#define H5S_SELECT_SERIAL_SIZE(S) ((*(S)->select.type->serial_size)(S))
#define H5S_SELECT_SERIALIZE(S,BUF) ((*(S)->select.type->serialize)(S,BUF))
#define H5S_SELECT_BOUNDS(S,START,END) ((*(S)->select.type->bounds)(S,START,END))
+#define H5S_SELECT_OFFSET(S, OFFSET) ((*(S)->select.type->offset)(S, OFFSET))
#define H5S_SELECT_IS_CONTIGUOUS(S) ((*(S)->select.type->is_contiguous)(S))
#define H5S_SELECT_IS_SINGLE(S) ((*(S)->select.type->is_single)(S))
#define H5S_SELECT_IS_REGULAR(S) ((*(S)->select.type->is_regular)(S))
@@ -175,6 +177,7 @@ typedef struct H5S_iostats_t {
#define H5S_SELECT_SERIAL_SIZE(S) (H5S_select_serial_size(S))
#define H5S_SELECT_SERIALIZE(S,BUF) (H5S_select_serialize(S,BUF))
#define H5S_SELECT_BOUNDS(S,START,END) (H5S_get_select_bounds(S,START,END))
+#define H5S_SELECT_OFFSET(S, OFFSET) (H5S_get_select_offset(S, OFFSET))
#define H5S_SELECT_IS_CONTIGUOUS(S) (H5S_select_is_contiguous(S))
#define H5S_SELECT_IS_SINGLE(S) (H5S_select_is_single(S))
#define H5S_SELECT_IS_REGULAR(S) (H5S_select_is_regular(S))
@@ -205,10 +208,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);
@@ -234,6 +236,7 @@ H5_DLL herr_t H5S_select_fill(const void *fill, size_t fill_size,
H5_DLL htri_t H5S_select_valid(const H5S_t *space);
H5_DLL hssize_t H5S_get_select_npoints(const H5S_t *space);
H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+H5_DLL herr_t H5S_get_select_offset(const H5S_t *space, hsize_t *offset);
H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset);
H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2);
@@ -255,8 +258,8 @@ H5_DLL herr_t H5S_select_all(H5S_t *space, hbool_t rel_prev);
H5_DLL herr_t H5S_select_none(H5S_t *space);
/* Operations on point selections */
-H5_DLL herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op,
- size_t num_elem, const hsize_t **coord);
+H5_DLL herr_t H5S_select_elements(H5S_t *space, H5S_seloper_t op,
+ size_t num_elem, const hsize_t *coord);
/* Operations on hyperslab selections */
H5_DLL herr_t H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hsize_t start[],
@@ -271,7 +274,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/H5Spublic.h b/src/H5Spublic.h
index 4a49da2..43f79b9 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -126,8 +126,7 @@ H5_DLL hid_t H5Scombine_select(hid_t space1_id, H5S_seloper_t op,
hid_t space2_id);
#endif /* NEW_HYPERSLAB_API */
H5_DLL herr_t H5Sselect_elements(hid_t space_id, H5S_seloper_t op,
- size_t num_elemn,
- const hsize_t **coord);
+ size_t num_elem, const hsize_t *coord);
H5_DLL H5S_class_t H5Sget_simple_extent_type(hid_t space_id);
H5_DLL herr_t H5Sset_extent_none(hid_t space_id);
H5_DLL herr_t H5Sextent_copy(hid_t dst_id,hid_t src_id);
@@ -138,9 +137,12 @@ H5_DLL herr_t H5Soffset_simple(hid_t space_id, const hssize_t *offset);
H5_DLL htri_t H5Sselect_valid(hid_t spaceid);
H5_DLL hssize_t H5Sget_select_hyper_nblocks(hid_t spaceid);
H5_DLL hssize_t H5Sget_select_elem_npoints(hid_t spaceid);
-H5_DLL herr_t H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, hsize_t numblocks, hsize_t *buf);
-H5_DLL herr_t H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint, hsize_t numpoints, hsize_t *buf);
-H5_DLL herr_t H5Sget_select_bounds(hid_t spaceid, hsize_t *start, hsize_t *end);
+H5_DLL herr_t H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
+ hsize_t numblocks, hsize_t buf[/*numblocks*/]);
+H5_DLL herr_t H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint,
+ hsize_t numpoints, hsize_t buf[/*numpoints*/]);
+H5_DLL herr_t H5Sget_select_bounds(hid_t spaceid, hsize_t start[],
+ hsize_t end[]);
H5_DLL H5S_sel_type H5Sget_select_type(hid_t spaceid);
#ifdef __cplusplus
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 31fd05e..ed3c740 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);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ /* Indicate that the offset was changed */
+ space->select.offset_changed = TRUE;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_select_offset() */
@@ -488,8 +491,8 @@ done:
USAGE
herr_t H5S_get_select_bounds(space, start, end)
hid_t dsid; IN: Dataspace ID of selection to query
- hsize_t *start; OUT: Starting coordinate of bounding box
- hsize_t *end; OUT: Opposite coordinate of bounding box
+ hsize_t start[]; OUT: Starting coordinate of bounding box
+ hsize_t end[]; OUT: Opposite coordinate of bounding box
RETURNS
Non-negative on success, negative on failure
DESCRIPTION
@@ -511,7 +514,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5Sget_select_bounds(hid_t spaceid, hsize_t *start, hsize_t *end)
+H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[])
{
H5S_t *space = NULL; /* Dataspace to modify selection of */
herr_t ret_value; /* return value */
@@ -579,6 +582,46 @@ H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
/*--------------------------------------------------------------------------
NAME
+ H5S_get_select_offset
+ PURPOSE
+ Gets the linear offset of the first element for the selection.
+ USAGE
+ herr_t H5S_get_select_offset(space, offset)
+ const H5S_t *space; IN: Dataspace pointer of selection to query
+ hsize_t *offset; OUT: Linear offset of first element in selection
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the linear offset (in "units" of elements) of the first element
+ selected within the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The offset calculation _does_ include the current offset of the
+ selection within the dataspace extent.
+
+ Calling this function on a "none" selection returns fail.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
+{
+ herr_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_offset)
+
+ /* Check args */
+ HDassert(space);
+ HDassert(offset);
+
+ ret_value = (*space->select.type->offset)(space, offset);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_get_select_offset() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_is_contiguous
PURPOSE
Determines if a selection is contiguous in the dataspace
@@ -758,10 +801,9 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s
/* Save the dataspace's rank */
sel_iter->rank=space->extent.rank;
- if(sel_iter->rank>0) {
- /* Point to the dataspace dimensions */
- sel_iter->dims=space->extent.size;
- } /* end if */
+ /* Point to the dataspace dimensions, if there are any */
+ if(sel_iter->rank > 0)
+ sel_iter->dims = space->extent.size;
else
sel_iter->dims = NULL;
diff --git a/src/H5TS.c b/src/H5TS.c
index e311c29..a250067 100644
--- a/src/H5TS.c
+++ b/src/H5TS.c
@@ -96,10 +96,6 @@ H5TS_first_thread_init(void)
{
H5_g.H5_libinit_g = FALSE;
- /* set the owner objects to initial values */
- H5_g.init_lock.owner_thread = pthread_self();
- H5_g.init_lock.owner_valid = FALSE;
-
/* initialize global API mutex lock */
pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL);
pthread_cond_init(&H5_g.init_lock.cond_var, NULL);
@@ -150,26 +146,17 @@ H5TS_mutex_lock(H5TS_mutex_t *mutex)
if (ret_value)
return ret_value;
- if (mutex->owner_valid && pthread_equal(pthread_self(), mutex->owner_thread)) {
+ if(mutex->lock_count && pthread_equal(pthread_self(), mutex->owner_thread)) {
/* already owned by self - increment count */
mutex->lock_count++;
- } else if (!mutex->owner_valid) {
- /* no one else has locked it - set owner and grab lock */
+ } else {
+ /* if owned by other thread, wait for condition signal */
+ while(mutex->lock_count)
+ pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock);
+
+ /* After we've received the signal, take ownership of the mutex */
mutex->owner_thread = pthread_self();
- mutex->owner_valid = TRUE;
mutex->lock_count = 1;
- } else {
- /* if already locked by someone else */
- for (;;) {
- pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock);
-
- if (!mutex->owner_valid) {
- mutex->owner_thread = pthread_self();
- mutex->owner_valid = TRUE;
- mutex->lock_count = 1;
- break;
- }
- }
}
return pthread_mutex_unlock(&mutex->atomic_lock);
@@ -204,26 +191,26 @@ H5TS_mutex_lock(H5TS_mutex_t *mutex)
herr_t
H5TS_mutex_unlock(H5TS_mutex_t *mutex)
{
- herr_t ret_value;
+ herr_t ret_value; /* Return value */
ret_value = pthread_mutex_lock(&mutex->atomic_lock);
- if (ret_value)
- return ret_value;
+ if(ret_value)
+ return ret_value;
mutex->lock_count--;
- if (mutex->lock_count == 0) {
- mutex->owner_valid = FALSE;
- ret_value = pthread_cond_signal(&mutex->cond_var);
+ ret_value = pthread_mutex_unlock(&mutex->atomic_lock);
- if (ret_value) {
- pthread_mutex_unlock(&mutex->atomic_lock);
- return ret_value;
- }
- }
+ if(mutex->lock_count == 0) {
+ int err;
- return pthread_mutex_unlock(&mutex->atomic_lock);
+ err = pthread_cond_signal(&mutex->cond_var);
+ if(err != 0)
+ ret_value = err;
+ } /* end if */
+
+ return ret_value;
}
/*--------------------------------------------------------------------------
diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h
index f817120..0d0b620 100644
--- a/src/H5TSprivate.h
+++ b/src/H5TSprivate.h
@@ -37,7 +37,6 @@
typedef struct H5TS_mutex_struct {
pthread_t owner_thread; /* current lock owner */
- unsigned owner_valid; /* if current lock owner info is valid */
pthread_mutex_t atomic_lock; /* lock for atomicity of new mechanism */
pthread_cond_t cond_var; /* condition variable */
unsigned int lock_count;
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index 7a29d45..1b9265d 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -96,7 +96,6 @@ H5Z_class_t H5Z_NBIT[1] = {{
#define H5Z_NBIT_ARRAY 2 /* Array datatype class */
#define H5Z_NBIT_COMPOUND 3 /* Compound datatype class */
#define H5Z_NBIT_NOOPTYPE 4 /* Other datatype class: nbit does no compression */
-#define H5Z_NBIT_USER_NPARMS 0 /* Number of parameters that users can set */
#define H5Z_NBIT_MAX_NPARMS 4096 /* Max number of parameters for filter */
#define H5Z_NBIT_ORDER_LE 0 /* Little endian for datatype byte order */
#define H5Z_NBIT_ORDER_BE 1 /* Big endian for datatype byte order */
@@ -1409,4 +1408,4 @@ static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned c
*buffer_size = j + 1; /* sometimes is catually j, but to be safe */
}
-#endif /* H5_HAVE_FILTER_NZIP */
+#endif /* H5_HAVE_FILTER_NBIT */
diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h
index 1fac71c..7211a2b 100644
--- a/src/H5Zpublic.h
+++ b/src/H5Zpublic.h
@@ -74,6 +74,25 @@ typedef int H5Z_filter_t;
#define H5_SZIP_NN_OPTION_MASK 32
#define H5_SZIP_MAX_PIXELS_PER_BLOCK 32
+/* Macros for the shuffle filter */
+#define H5Z_SHUFFLE_USER_NPARMS 0 /* Number of parameters that users can set */
+#define H5Z_SHUFFLE_TOTAL_NPARMS 1 /* Total number of parameters for filter */
+
+/* Macros for the szip filter */
+#define H5Z_SZIP_USER_NPARMS 2 /* Number of parameters that users can set */
+#define H5Z_SZIP_TOTAL_NPARMS 4 /* Total number of parameters for filter */
+#define H5Z_SZIP_PARM_MASK 0 /* "User" parameter for option mask */
+#define H5Z_SZIP_PARM_PPB 1 /* "User" parameter for pixels-per-block */
+#define H5Z_SZIP_PARM_BPP 2 /* "Local" parameter for bits-per-pixel */
+#define H5Z_SZIP_PARM_PPS 3 /* "Local" parameter for pixels-per-scanline */
+
+/* Macros for the nbit filter */
+#define H5Z_NBIT_USER_NPARMS 0 /* Number of parameters that users can set */
+
+/* Macros for the scale offset filter */
+#define H5Z_SCALEOFFSET_USER_NPARMS 2 /* Number of parameters that users can set */
+
+
/* Special parameters for ScaleOffset filter*/
#define H5Z_SO_INT_MINBITS_DEFAULT 0
typedef enum H5Z_SO_scale_type_t {
diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
index b970cdf..5ef3e7a 100644
--- a/src/H5Zscaleoffset.c
+++ b/src/H5Zscaleoffset.c
@@ -93,7 +93,6 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
}};
/* Local macros */
-#define H5Z_SCALEOFFSET_USER_NPARMS 2 /* Number of parameters that users can set */
#define H5Z_SCALEOFFSET_TOTAL_NPARMS 20 /* Total number of parameters for filter */
#define H5Z_SCALEOFFSET_PARM_SCALETYPE 0 /* "User" parameter for scale type */
#define H5Z_SCALEOFFSET_PARM_SCALEFACTOR 1 /* "User" parameter for scale factor */
diff --git a/src/H5Zshuffle.c b/src/H5Zshuffle.c
index c203ed9..3f40707 100644
--- a/src/H5Zshuffle.c
+++ b/src/H5Zshuffle.c
@@ -44,8 +44,6 @@ const H5Z_class_t H5Z_SHUFFLE[1] = {{
}};
/* Local macros */
-#define H5Z_SHUFFLE_USER_NPARMS 0 /* Number of parameters that users can set */
-#define H5Z_SHUFFLE_TOTAL_NPARMS 1 /* Total number of parameters for filter */
#define H5Z_SHUFFLE_PARM_SIZE 0 /* "Local" parameter for shuffling size */
diff --git a/src/H5Zszip.c b/src/H5Zszip.c
index cdc26aa..9201a80 100644
--- a/src/H5Zszip.c
+++ b/src/H5Zszip.c
@@ -51,13 +51,6 @@ H5Z_class_t H5Z_SZIP[1] = {{
H5Z_filter_szip, /* The actual filter function */
}};
-/* Local macros */
-#define H5Z_SZIP_USER_NPARMS 2 /* Number of parameters that users can set */
-#define H5Z_SZIP_TOTAL_NPARMS 4 /* Total number of parameters for filter */
-#define H5Z_SZIP_PARM_MASK 0 /* "User" parameter for option mask */
-#define H5Z_SZIP_PARM_PPB 1 /* "User" parameter for pixels-per-block */
-#define H5Z_SZIP_PARM_BPP 2 /* "Local" parameter for bits-per-pixel */
-#define H5Z_SZIP_PARM_PPS 3 /* "Local" parameter for pixels-per-scanline */
/*-------------------------------------------------------------------------
diff --git a/src/H5checksum.c b/src/H5checksum.c
index f2e344d..e42f152 100644
--- a/src/H5checksum.c
+++ b/src/H5checksum.c
@@ -459,3 +459,36 @@ H5_checksum_metadata(const void *data, size_t len, uint32_t initval)
FUNC_LEAVE_NOAPI(H5_checksum_lookup3(data, len, initval))
} /* end H5_checksum_metadata() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5_hash_string
+ *
+ * Purpose: Provide a simple & fast routine for hashing strings
+ *
+ * Note: This algorithm is the 'djb2' algorithm described on this page:
+ * http://www.cse.yorku.ca/~oz/hash.html
+ *
+ * Return: hash of input string (can't fail)
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 11, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+uint32_t
+H5_hash_string(const char *str)
+{
+ uint32_t hash = 5381;
+ int c;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5_hash_string)
+
+ /* Sanity check */
+ HDassert(str);
+
+ while(c = *str++)
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ FUNC_LEAVE_NOAPI(hash)
+} /* end H5_hash_string() */
+
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 0c89e98..5c767ef 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -570,6 +570,9 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
+/* Define if strict file format checks are enabled */
+#undef STRICT_FORMAT_CHECKS
+
/* Define if your system supports pthread_attr_setscope(&attribute,
PTHREAD_SCOPE_SYSTEM) call. */
#undef SYSTEM_SCOPE_THREADS
diff --git a/src/H5private.h b/src/H5private.h
index ebbad21..343e652 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -485,6 +485,12 @@ typedef enum {
H5_COPY_DEEP /* Deep copy from source to destination, including duplicating fields pointed to */
} H5_copy_depth_t;
+/* Unique object "position" */
+typedef struct {
+ unsigned long fileno; /* The unique identifier for the file of the object */
+ haddr_t addr; /* The unique address of the object's header in that file */
+} H5_obj_t;
+
/*
* Redefine all the POSIX functions. We should never see a POSIX
* function (or any other non-HDF5 function) in the source!
@@ -1473,6 +1479,7 @@ H5_DLL uint32_t H5_checksum_fletcher32(const void *data, size_t len);
H5_DLL uint32_t H5_checksum_crc(const void *data, size_t len);
H5_DLL uint32_t H5_checksum_lookup3(const void *data, size_t len, uint32_t initval);
H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t initval);
+H5_DLL uint32_t H5_hash_string(const char *str);
/* Functions for debugging */
H5_DLL herr_t H5_buffer_dump(FILE *stream, int indent, uint8_t *buf,
diff --git a/src/H5public.h b/src/H5public.h
index 608e52c..06060dd 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -72,9 +72,9 @@ extern "C" {
#define H5_VERS_MAJOR 1 /* For major interface/format changes */
#define H5_VERS_MINOR 8 /* For minor interface/format changes */
#define H5_VERS_RELEASE 0 /* For tweaks, bug-fixes, or development */
-#define H5_VERS_SUBRELEASE "beta4post1" /* For pre-releases like snap0 */
+#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */
/* Empty string for real releases. */
-#define H5_VERS_INFO "HDF5 library version: 1.8.0-beta4post1" /* Full version string */
+#define H5_VERS_INFO "HDF5 library version: 1.8.0" /* Full version string */
#define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \
H5_VERS_RELEASE)
diff --git a/src/H5trace.c b/src/H5trace.c
index 0ad99b2..926a590 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -647,6 +647,26 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
}
break;
+ case 'v':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } else {
+ H5F_libver_t libver_vers = va_arg(ap, H5F_libver_t); /*lint !e64 Type mismatch not really occuring */
+
+ switch(libver_vers) {
+ case H5F_LIBVER_EARLIEST:
+ fprintf(out, "H5F_LIBVER_EARLIEST");
+ break;
+ case H5F_LIBVER_LATEST:
+ fprintf(out, "H5F_LIBVER_LATEST");
+ break;
+ }
+ }
+ break;
+
default:
fprintf(out, "BADTYPE(F%c)", type[1]);
goto error;
diff --git a/src/Makefile.am b/src/Makefile.am
index 75f84e6..5671533 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -54,7 +54,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.c \
H5FD.c H5FDcore.c \
H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
- H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \
+ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \
H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \
H5G.c H5Gbtree2.c H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
H5Gint.c H5Glink.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 79d8f07..197191e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -89,37 +89,38 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Edeprec.lo H5Eint.lo H5F.lo H5Fdbg.lo H5Ffake.lo H5Fmount.lo \
H5Fsfile.lo H5Fsuper.lo H5Ftest.lo H5FD.lo H5FDcore.lo \
H5FDdirect.lo H5FDfamily.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \
- H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDstdio.lo H5FL.lo \
- H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo H5FSsection.lo H5G.lo \
- H5Gbtree2.lo H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo \
- H5Gint.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo \
- H5Goh.lo H5Gstab.lo H5Gtest.lo H5Gtraverse.lo H5HF.lo \
- H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \
- H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo H5HFiblock.lo H5HFiter.lo \
- H5HFman.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \
- H5HFtiny.lo H5HG.lo H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo \
- H5I.lo H5L.lo H5Lexternal.lo H5MF.lo H5MM.lo H5MP.lo \
- H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \
- H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \
- H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo \
- H5Oefl.lo H5Ofill.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo \
- H5Olink.lo H5Omdj_msg.lo H5Omessage.lo H5Omtime.lo H5Oname.lo \
- H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \
- H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \
- H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo \
- H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \
- H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \
- H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo \
- H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \
- H5Spoint.lo H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo \
- H5SMbtree2.lo H5SMcache.lo H5SMtest.lo H5ST.lo H5T.lo \
- H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo \
- H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo H5Tfields.lo \
- H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo \
- H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo \
- H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo \
- H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \
- H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo
+ H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \
+ H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \
+ H5FSsection.lo H5G.lo H5Gbtree2.lo H5Gcompact.lo H5Gdense.lo \
+ H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \
+ H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \
+ H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo \
+ H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \
+ H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \
+ H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \
+ H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5L.lo \
+ H5Lexternal.lo H5MF.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \
+ H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \
+ H5Obtreek.lo H5Ocache.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo \
+ H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \
+ H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omdj_msg.lo \
+ H5Omessage.lo H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo \
+ H5Orefcount.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \
+ H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo H5Pacpl.lo \
+ H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo \
+ H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo H5Plapl.lo H5Plcpl.lo \
+ H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5R.lo \
+ H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo \
+ H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo \
+ H5Stest.lo H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo \
+ H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo \
+ H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo \
+ H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \
+ H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \
+ H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo \
+ H5TS.lo H5V.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \
+ H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \
+ H5Ztrans.lo
libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS)
libhdf5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -270,6 +271,7 @@ SET_MAKE = @SET_MAKE@
SHELL = /bin/sh
SIZE_T = @SIZE_T@
STATIC_SHARED = @STATIC_SHARED@
+STRICT_FORMAT_CHECKS = @STRICT_FORMAT_CHECKS@
STRIP = @STRIP@
TESTPARALLEL = @TESTPARALLEL@
TIME = @TIME@
@@ -382,9 +384,9 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
-LT_VERS_INTERFACE = 4
-LT_VERS_REVISION = 4
-LT_VERS_AGE = 3
+LT_VERS_INTERFACE = 5
+LT_VERS_REVISION = 0
+LT_VERS_AGE = 0
H5detect_CFLAGS = -g
# Our main target, the HDF5 library
@@ -412,7 +414,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.c \
H5FD.c H5FDcore.c \
H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
- H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \
+ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \
H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \
H5G.c H5Gbtree2.c H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
H5Gint.c H5Glink.c \
@@ -632,6 +634,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDmpiposix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDmulti.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDsec2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDspace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDstdio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FL.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FO.Plo@am__quote@