summaryrefslogtreecommitdiffstats
path: root/src/H5Pdcpl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Pdcpl.c')
-rw-r--r--src/H5Pdcpl.c794
1 files changed, 782 insertions, 12 deletions
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index 9bf58e4..f687104 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -41,7 +41,9 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
+#include "H5Oprivate.h" /* Object headers */
#include "H5Ppkg.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspaces */
#include "H5Tprivate.h" /* Datatypes */
#include "H5Zpkg.h" /* Data filters */
@@ -55,13 +57,16 @@
#define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0}
#define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_IDX_BTREE, HADDR_UNDEF, NULL, {{HADDR_UNDEF, NULL}}}
#define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
+#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, H5D_VDS_ERROR, HSIZE_UNDEF, -1, -1, FALSE}
#ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER
#define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }}
#define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }}
#define H5D_DEF_STORAGE_CHUNK {H5D_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }}
+#define H5D_DEF_STORAGE_VIRTUAL {H5D_VIRTUAL, { .virt = H5D_DEF_STORAGE_VIRTUAL_INIT }}
#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_COMPACT}
#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CONTIG}
#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CHUNK}
+#define H5D_DEF_LAYOUT_VIRTUAL {H5D_VIRTUAL, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_VIRTUAL}
#else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
/* Note that the compact & chunked layout initialization values are using the
* contiguous layout initialization in the union, because the contiguous
@@ -71,6 +76,7 @@
#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
+#define H5D_DEF_LAYOUT_VIRTUAL {H5D_VIRTUAL, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
/* ======== Dataset creation properties ======== */
@@ -79,7 +85,9 @@
#define H5D_CRT_LAYOUT_DEF H5D_DEF_LAYOUT_CONTIG
#define H5D_CRT_LAYOUT_ENC H5P__dcrt_layout_enc
#define H5D_CRT_LAYOUT_DEC H5P__dcrt_layout_dec
+#define H5D_CRT_LAYOUT_DEL H5P__dcrt_layout_del
#define H5D_CRT_LAYOUT_CMP H5P__dcrt_layout_cmp
+#define H5D_CRT_LAYOUT_CLOSE H5P__dcrt_layout_close
/* Definitions for fill value. size=0 means fill value will be 0 as
* library default; size=-1 means fill value is undefined. */
#define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t)
@@ -128,7 +136,9 @@ static herr_t H5P__dcrt_close(hid_t dxpl_id, void *close_data);
/* Property callbacks */
static herr_t H5P__dcrt_layout_enc(const void *value, void **pp, size_t *size);
static herr_t H5P__dcrt_layout_dec(const void **pp, void *value);
+static herr_t H5P__dcrt_layout_del(hid_t prop_id, const char *name, size_t size, void *value);
static int H5P__dcrt_layout_cmp(const void *value1, const void *value2, size_t size);
+static herr_t H5P__dcrt_layout_close(const char *name, size_t size, void *value);
static herr_t H5P__fill_value_enc(const void *value, void **pp, size_t *size);
static herr_t H5P__fill_value_dec(const void **pp, void *value);
static herr_t H5P__dcrt_ext_file_list_enc(const void *value, void **pp, size_t *size);
@@ -183,10 +193,12 @@ static const H5O_efl_t H5D_def_efl_g = H5D_CRT_EXT_FILE_LIST_DEF;
static const H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT;
static const H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG;
static const H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK;
+static const H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_VIRTUAL;
#else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
static H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT;
static H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG;
static H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK;
+static H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_VIRTUAL;
static hbool_t H5P_dcrt_def_layout_init_g = FALSE;
#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
@@ -213,7 +225,7 @@ H5P__dcrt_reg_prop(H5P_genclass_t *pclass)
/* Register the storage layout property */
if(H5P_register_real(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &H5D_def_layout_g,
NULL, NULL, NULL, H5D_CRT_LAYOUT_ENC, H5D_CRT_LAYOUT_DEC,
- NULL, NULL, H5D_CRT_LAYOUT_CMP, NULL) < 0)
+ H5D_CRT_LAYOUT_DEL, NULL, H5D_CRT_LAYOUT_CMP, H5D_CRT_LAYOUT_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register the fill value property */
@@ -314,6 +326,11 @@ H5P__dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void H5_ATTR_UNUSED *copy
dst_layout.storage.u.chunk.ops = NULL;
break;
+ case H5D_VIRTUAL:
+ dst_layout.storage.u.virt.serial_list_hobjid.addr = HADDR_UNDEF;
+ dst_layout.storage.u.virt.serial_list_hobjid.idx = 0;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -421,8 +438,12 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size)
{
const H5O_layout_t *layout = (const H5O_layout_t *)value; /* Create local aliases for values */
uint8_t **pp = (uint8_t **)_pp;
+ uint8_t *tmp_p;
+ size_t tmp_size;
+ size_t u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_NOERR
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(layout);
@@ -434,16 +455,84 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size)
/* If layout is chunked, encode chunking structure */
if(H5D_CHUNKED == layout->type) {
- unsigned u; /* Local index variable */
-
/* Encode rank */
*(*pp)++ = (uint8_t)layout->u.chunk.ndims;
/* Encode chunk dims */
HDcompile_assert(sizeof(uint32_t) == sizeof(layout->u.chunk.dim[0]));
- for(u = 0; u < layout->u.chunk.ndims; u++)
+ for(u = 0; u < (size_t)layout->u.chunk.ndims; u++)
UINT32ENCODE(*pp, layout->u.chunk.dim[u])
} /* end if */
+ else if(H5D_VIRTUAL == layout->type) {
+ uint64_t nentries = (uint64_t)layout->storage.u.virt.list_nused;
+
+ /* Encode number of entries */
+ UINT64ENCODE(*pp, nentries)
+ *size += (size_t)8;
+
+ /* Iterate over entries */
+ for(u = 0; u < layout->storage.u.virt.list_nused; u++) {
+ /* Source file name */
+ tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_file_name) + (size_t)1;
+ (void)HDmemcpy(*pp, layout->storage.u.virt.list[u].source_file_name, tmp_size);
+ *pp += tmp_size;
+ *size += tmp_size;
+
+ /* Source dataset name */
+ tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_dset_name) + (size_t)1;
+ (void)HDmemcpy(*pp, layout->storage.u.virt.list[u].source_dset_name, tmp_size);
+ *pp += tmp_size;
+ *size += tmp_size;
+
+ /* Source selection. Note that we are not passing the real
+ * allocated size because we do no know it. H5P__encode should
+ * have verified that the buffer is large enough for the entire
+ * list before we get here. */
+ tmp_size = (size_t)-1;
+ tmp_p = *pp;
+ if(H5S_encode(layout->storage.u.virt.list[u].source_select, pp, &tmp_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize source selection")
+ *size += (size_t)(*pp - tmp_p);
+
+ /* Virtual dataset selection. Same notes as above apply. */
+ tmp_size = (size_t)-1;
+ tmp_p = *pp;
+ if(H5S_encode(layout->storage.u.virt.list[u].source_dset.virtual_select, pp, &tmp_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize virtual selection")
+ *size += (size_t)(*pp - tmp_p);
+ } /* end for */
+ } /* end if */
+ } /* end if */
+ else if(H5D_VIRTUAL == layout->type) {
+ /* Calculate size of virtual layout info */
+ /* number of entries */
+ *size += (size_t)8;
+
+ /* NULL pointer to pass to H5S_encode */
+ tmp_p = NULL;
+
+ /* Iterate over entries */
+ for(u = 0; u < layout->storage.u.virt.list_nused; u++) {
+ /* Source file name */
+ tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_file_name) + (size_t)1;
+ *size += tmp_size;
+
+ /* Source dataset name */
+ tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_dset_name) + (size_t)1;
+ *size += tmp_size;
+
+ /* Source selection */
+ tmp_size = (size_t)0;
+ if(H5S_encode(layout->storage.u.virt.list[u].source_select, &tmp_p, &tmp_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize source selection")
+ *size += tmp_size;
+
+ /* Virtual dataset selection */
+ tmp_size = (size_t)0;
+ if(H5S_encode(layout->storage.u.virt.list[u].source_dset.virtual_select, &tmp_p, &tmp_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize virtual selection")
+ *size += tmp_size;
+ } /* end for */
} /* end if */
/* Size of layout type */
@@ -455,7 +544,8 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size)
*size += layout->u.chunk.ndims * sizeof(uint32_t);
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__dcrt_layout_enc() */
@@ -478,7 +568,7 @@ static herr_t
H5P__dcrt_layout_dec(const void **_pp, void *value)
{
const H5O_layout_t *layout; /* Storage layout */
- H5O_layout_t chunk_layout; /* Layout structure for chunk info */
+ H5O_layout_t tmp_layout; /* Temporary local layout structure */
H5D_layout_t type; /* Layout type */
const uint8_t **pp = (const uint8_t **)_pp;
herr_t ret_value = SUCCEED; /* Return value */
@@ -518,19 +608,113 @@ H5P__dcrt_layout_dec(const void **_pp, void *value)
unsigned u; /* Local index variable */
/* Initialize to default values */
- chunk_layout = H5D_def_layout_chunk_g;
+ tmp_layout = H5D_def_layout_chunk_g;
/* Set rank & dimensions */
- chunk_layout.u.chunk.ndims = (unsigned)ndims;
+ tmp_layout.u.chunk.ndims = (unsigned)ndims;
for(u = 0; u < ndims; u++)
- UINT32DECODE(*pp, chunk_layout.u.chunk.dim[u])
+ UINT32DECODE(*pp, tmp_layout.u.chunk.dim[u])
/* Point at the newly set up struct */
- layout = &chunk_layout;
+ layout = &tmp_layout;
} /* end else */
}
break;
+ case H5D_VIRTUAL:
+ {
+ uint64_t nentries; /* Number of VDS mappings */
+
+ /* Decode number of entries */
+ UINT64DECODE(*pp, nentries)
+
+ if(nentries == (uint64_t)0)
+ /* Just use the default struct */
+ layout = &H5D_def_layout_virtual_g;
+ else {
+ size_t tmp_size;
+ size_t u; /* Local index variable */
+
+ /* Initialize to default values */
+ tmp_layout = H5D_def_layout_virtual_g;
+
+ /* Allocate entry list */
+ if(NULL == (tmp_layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc((size_t)nentries * sizeof(H5O_storage_virtual_ent_t))))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate heap block")
+ tmp_layout.storage.u.virt.list_nalloc = (size_t)nentries;
+ tmp_layout.storage.u.virt.list_nused = (size_t)nentries;
+
+ /* Decode each entry */
+ for(u = 0; u < (size_t)nentries; u++) {
+ /* Source file name */
+ tmp_size = HDstrlen((const char *)*pp) + 1;
+ if(NULL == (tmp_layout.storage.u.virt.list[u].source_file_name = (char *)H5MM_malloc(tmp_size)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate memory for source file name")
+ (void)HDmemcpy(tmp_layout.storage.u.virt.list[u].source_file_name, *pp, tmp_size);
+ *pp += tmp_size;
+
+ /* Source dataset name */
+ tmp_size = HDstrlen((const char *)*pp) + 1;
+ if(NULL == (tmp_layout.storage.u.virt.list[u].source_dset_name = (char *)H5MM_malloc(tmp_size)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate memory for source dataset name")
+ (void)HDmemcpy(tmp_layout.storage.u.virt.list[u].source_dset_name, *pp, tmp_size);
+ *pp += tmp_size;
+
+ /* Source selection */
+ if(NULL == (tmp_layout.storage.u.virt.list[u].source_select = H5S_decode(pp)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode source space selection")
+ tmp_layout.storage.u.virt.list[u].source_space_status = H5O_VIRTUAL_STATUS_USER;
+
+ /* Virtual selection */
+ if(NULL == (tmp_layout.storage.u.virt.list[u].source_dset.virtual_select = H5S_decode(pp)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode virtual space selection")
+ tmp_layout.storage.u.virt.list[u].virtual_space_status = H5O_VIRTUAL_STATUS_USER;
+
+ /* Parse source file and dataset names for "printf"
+ * style format specifiers */
+ if(H5D_virtual_parse_source_name(tmp_layout.storage.u.virt.list[u].source_file_name, &tmp_layout.storage.u.virt.list[u].parsed_source_file_name, &tmp_layout.storage.u.virt.list[u].psfn_static_strlen, &tmp_layout.storage.u.virt.list[u].psfn_nsubs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source file name")
+ if(H5D_virtual_parse_source_name(tmp_layout.storage.u.virt.list[u].source_dset_name, &tmp_layout.storage.u.virt.list[u].parsed_source_dset_name, &tmp_layout.storage.u.virt.list[u].psdn_static_strlen, &tmp_layout.storage.u.virt.list[u].psdn_nsubs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name")
+
+ /* Set source names in source_dset struct */
+ if((tmp_layout.storage.u.virt.list[u].psfn_nsubs == 0)
+ && (tmp_layout.storage.u.virt.list[u].psdn_nsubs == 0)) {
+ if(tmp_layout.storage.u.virt.list[u].parsed_source_file_name)
+ tmp_layout.storage.u.virt.list[u].source_dset.file_name = tmp_layout.storage.u.virt.list[u].parsed_source_file_name->name_segment;
+ else
+ tmp_layout.storage.u.virt.list[u].source_dset.file_name = tmp_layout.storage.u.virt.list[u].source_file_name;
+ if(tmp_layout.storage.u.virt.list[u].parsed_source_dset_name)
+ tmp_layout.storage.u.virt.list[u].source_dset.dset_name = tmp_layout.storage.u.virt.list[u].parsed_source_dset_name->name_segment;
+ else
+ tmp_layout.storage.u.virt.list[u].source_dset.dset_name = tmp_layout.storage.u.virt.list[u].source_dset_name;
+ } /* end if */
+
+ /* unlim_dim fields */
+ tmp_layout.storage.u.virt.list[u].unlim_dim_source = H5S_get_select_unlim_dim(tmp_layout.storage.u.virt.list[u].source_select);
+ tmp_layout.storage.u.virt.list[u].unlim_dim_virtual = H5S_get_select_unlim_dim(tmp_layout.storage.u.virt.list[u].source_dset.virtual_select);
+ tmp_layout.storage.u.virt.list[u].unlim_extent_source = HSIZE_UNDEF;
+ tmp_layout.storage.u.virt.list[u].unlim_extent_virtual = HSIZE_UNDEF;
+ tmp_layout.storage.u.virt.list[u].clip_size_source = HSIZE_UNDEF;
+ tmp_layout.storage.u.virt.list[u].clip_size_virtual = HSIZE_UNDEF;
+
+ /* Clipped selections */
+ if(tmp_layout.storage.u.virt.list[u].unlim_dim_virtual < 0) {
+ tmp_layout.storage.u.virt.list[u].source_dset.clipped_source_select = tmp_layout.storage.u.virt.list[u].source_select;
+ tmp_layout.storage.u.virt.list[u].source_dset.clipped_virtual_select = tmp_layout.storage.u.virt.list[u].source_dset.virtual_select;
+ } /* end if */
+
+ /* Update min_dims */
+ if(H5D_virtual_update_min_dims(&tmp_layout, u) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to update virtual dataset minimum dimensions")
+ } /* end for */
+
+ /* Point at the newly set up struct */
+ layout = &tmp_layout;
+ } /* end else */
+ } /* end block */
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -546,6 +730,41 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5P__dcrt_layout_del
+ *
+ * Purpose: Frees memory used to store the layout property
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, Feb 10, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__dcrt_layout_del(hid_t H5_ATTR_UNUSED prop_id,
+ const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size,
+ void *value)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(value);
+
+ /* Reset the old layout */
+ if(((H5O_layout_t *)value)->type == H5D_VIRTUAL) /* Temp hack until proper fix is in trunk */
+ if(H5O_msg_reset(H5O_LAYOUT_ID, value) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release layout message")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__dcrt_layout_del() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5P__dcrt_layout_cmp
*
* Purpose: Callback routine which is called whenever the layout
@@ -605,6 +824,51 @@ H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t H5_ATTR_
} /* end case */
break;
+ case H5D_VIRTUAL:
+ {
+ htri_t equal;
+ int strcmp_ret;
+ size_t u; /* Local index variable */
+
+ /* Compare number of mappings */
+ if(layout1->storage.u.virt.list_nused < layout2->storage.u.virt.list_nused) HGOTO_DONE(-1)
+ if(layout1->storage.u.virt.list_nused > layout2->storage.u.virt.list_nused) HGOTO_DONE(1)
+
+ /* Iterate over mappings */
+ for(u = 0; u < layout1->storage.u.virt.list_nused; u++) {
+ /* Compare virtual spaces. Note we cannot tell which is
+ * "greater", so just return 1 if different, -1 on failure.
+ */
+ if((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_dset.virtual_select, layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0) HGOTO_DONE(-1)
+ if(!equal)
+ HGOTO_DONE(1)
+ if((equal = H5S_select_shape_same(layout1->storage.u.virt.list[u].source_dset.virtual_select, layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0) HGOTO_DONE(-1)
+ if(!equal)
+ HGOTO_DONE(1)
+
+ /* Compare source file names */
+ strcmp_ret = HDstrcmp(layout1->storage.u.virt.list[u].source_file_name, layout2->storage.u.virt.list[u].source_file_name);
+ if(strcmp_ret < 0) HGOTO_DONE(-1)
+ if(strcmp_ret > 0) HGOTO_DONE(1)
+
+ /* Compare source dataset names */
+ strcmp_ret = HDstrcmp(layout1->storage.u.virt.list[u].source_dset_name, layout2->storage.u.virt.list[u].source_dset_name);
+ if(strcmp_ret < 0) HGOTO_DONE(-1)
+ if(strcmp_ret > 0) HGOTO_DONE(1)
+
+ /* Compare source spaces. Note we cannot tell which is
+ * "greater", so just return 1 if different, -1 on failure.
+ */
+ if((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_select, layout2->storage.u.virt.list[u].source_select)) < 0) HGOTO_DONE(-1)
+ if(!equal)
+ HGOTO_DONE(1)
+ if((equal = H5S_select_shape_same(layout1->storage.u.virt.list[u].source_select, layout2->storage.u.virt.list[u].source_select)) < 0) HGOTO_DONE(-1)
+ if(!equal)
+ HGOTO_DONE(1)
+ } /* end for */
+ } /* end block */
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -617,6 +881,40 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5P__dcrt_layout_close
+ *
+ * Purpose: Frees memory used to store the layout property
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, Feb 10, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__dcrt_layout_close(const char H5_ATTR_UNUSED *name,
+ size_t H5_ATTR_UNUSED size, void *value)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(value);
+
+ /* Reset the old layout */
+ if(((H5O_layout_t *)value)->type == H5D_VIRTUAL) /* Temp hack until proper fix is in trunk */
+ if(H5O_msg_reset(H5O_LAYOUT_ID, value) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release layout message")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__dcrt_layout_close() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5P__fill_value_enc
*
* Purpose: Callback routine which is called whenever the fill value
@@ -1110,6 +1408,7 @@ done:
static herr_t
H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout)
{
+ H5O_layout_t old_layout; /* Layout propertry already on list */
unsigned alloc_time_state; /* State of allocation time property */
herr_t ret_value = SUCCEED; /* return value */
@@ -1141,6 +1440,10 @@ H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout)
fill.alloc_time = H5D_ALLOC_TIME_INCR;
break;
+ case H5D_VIRTUAL:
+ fill.alloc_time = H5D_ALLOC_TIME_INCR;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -1152,6 +1455,14 @@ H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time")
} /* end if */
+ /* Get the old layout */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &old_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout")
+
+ /* Reset the old layout before overwriting it */
+ if(H5O_msg_reset(H5O_LAYOUT_ID, &old_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release layout message")
+
/* Set layout value */
if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, layout) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout")
@@ -1167,7 +1478,8 @@ done:
*
* Purpose: Set the default layout information for the various types of
* dataset layouts
- *
+
+
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
@@ -1181,13 +1493,18 @@ H5P__init_def_layout(void)
const H5O_layout_chunk_t def_layout_chunk = H5D_DEF_LAYOUT_CHUNK_INIT;
const H5O_storage_compact_t def_store_compact = H5D_DEF_STORAGE_COMPACT_INIT;
const H5O_storage_chunk_t def_store_chunk = H5D_DEF_STORAGE_CHUNK_INIT;
+ const H5O_storage_virtual_t def_store_virtual = H5D_DEF_STORAGE_VIRTUAL_INIT;
FUNC_ENTER_STATIC_NOERR
/* Initialize the default layout info for non-contigous layouts */
+ H5D_def_layout_compact_g.storage.type = H5D_COMPACT;
H5D_def_layout_compact_g.storage.u.compact = def_store_compact;
H5D_def_layout_chunk_g.u.chunk = def_layout_chunk;
+ H5D_def_layout_chunk_g.storage.type = H5D_CHUNKED;
H5D_def_layout_chunk_g.storage.u.chunk = def_store_chunk;
+ H5D_def_layout_virtual_g.storage.type = H5D_VIRTUAL;
+ H5D_def_layout_virtual_g.storage.u.virt = def_store_virtual;
/* Note that we've initialized the default values */
H5P_dcrt_def_layout_init_g = TRUE;
@@ -1257,6 +1574,10 @@ H5Pset_layout(hid_t plist_id, H5D_layout_t layout_type)
layout = &H5D_def_layout_chunk_g;
break;
+ case H5D_VIRTUAL:
+ layout = &H5D_def_layout_virtual_g;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -1462,6 +1783,451 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Pset_virtual
+ *
+ * Purpose: VDSINC
+ *
+ * As a side effect, the layout method is changed to
+ * H5D_VIRTUAL.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Friday, February 13, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name,
+ const char *src_dset_name, hid_t src_space_id)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_layout_t layout; /* Layout information for setting chunk info */
+ H5S_t *vspace; /* Virtual dataset space selection */
+ H5S_t *src_space; /* Source dataset space selection */
+ hssize_t nelmts; /* Number of elements */
+ hbool_t new_layout = FALSE; /* Whether we are adding a new virtual layout message to plist */
+ H5O_storage_virtual_ent_t *ent = NULL; /* Convenience pointer to new VDS entry */
+ hbool_t adding_entry = FALSE; /* Whether we are in the middle of adding an entry */
+ H5O_storage_virtual_ent_t *old_list = NULL; /* List pointer previously on property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "ii*s*si", dcpl_id, vspace_id, src_file_name, src_dset_name,
+ src_space_id);
+
+ /* Check arguments */
+ if(!src_file_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source file name not provided")
+ if(!src_dset_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "source dataset name not provided")
+ if(NULL == (vspace = (H5S_t *)H5I_object_verify(vspace_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ if(NULL == (src_space = (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ nelmts = H5S_GET_SELECT_NPOINTS(vspace);
+ if((nelmts != H5S_UNLIMITED)
+ && (nelmts != H5S_GET_SELECT_NPOINTS(src_space)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual and source space selections have different numbers of elements")
+ /* Check for unlimited selections having the same number of elements in the
+ * non-unlimited dimensions, and check for printf selections having the
+ * correct numbers of elements and unlimited/non-unlimited dimensions VDSINC
+ */
+
+#ifndef H5_HAVE_C99_DESIGNATED_INITIALIZER
+ /* If the compiler doesn't support C99 designated initializers, check if
+ * the default layout structs have been initialized yet or not. *ick* -QAK
+ */
+ if(!H5P_dcrt_def_layout_init_g)
+ if(H5P__init_def_layout() < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't initialize default layout info")
+#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the current layout */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout")
+
+ /* If the layout was not already virtual, Start with default virtual layout.
+ * Otherwise, add the mapping to the current list. */
+ if(layout.type == H5D_VIRTUAL)
+ /* Save old list pointer for error recovery */
+ old_list = layout.storage.u.virt.list;
+ else {
+ new_layout = TRUE;
+ HDmemcpy(&layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g));
+
+ HDassert(layout.storage.u.virt.list_nalloc == 0);
+ } /* end else */
+
+ /* Expand list if necessary */
+ if(layout.storage.u.virt.list_nalloc == 0) {
+ /* Allocate initial entry list */
+ if(NULL == (layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc(H5D_VIRTUAL_DEF_LIST_SIZE * sizeof(H5O_storage_virtual_ent_t))))
+ HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't allocate virtual dataset mapping list")
+ adding_entry = TRUE;
+ layout.storage.u.virt.list_nalloc = H5D_VIRTUAL_DEF_LIST_SIZE;
+ } /* end if */
+ else if(layout.storage.u.virt.list_nused
+ == layout.storage.u.virt.list_nalloc) {
+ HDassert((layout.storage.u.virt.list_nused > 0) && "checking code coverage...");//VDSINC
+ /* Double size of entry list. Make sure to zero out new memory. */
+ if(NULL == (layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_realloc(layout.storage.u.virt.list, (size_t)2 * layout.storage.u.virt.list_nalloc * sizeof(H5O_storage_virtual_ent_t))))
+ HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't reallocate virtual dataset mapping list")
+ adding_entry = TRUE;
+ (void)HDmemset(layout.storage.u.virt.list + layout.storage.u.virt.list_nalloc, 0, layout.storage.u.virt.list_nalloc * sizeof(H5O_storage_virtual_ent_t));
+ layout.storage.u.virt.list_nalloc *= (size_t)2;
+ } /* end if */
+
+ /* Add virtual dataset mapping entry */
+ ent = &layout.storage.u.virt.list[layout.storage.u.virt.list_nused];
+ if(NULL == (ent->source_dset.virtual_select = H5S_copy(vspace, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection")
+ adding_entry = TRUE;
+ if(NULL == (ent->source_file_name = HDstrdup(src_file_name)))
+ HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name")
+ if(NULL == (ent->source_dset_name = HDstrdup(src_dset_name)))
+ HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name")
+ if(NULL == (ent->source_select = H5S_copy(src_space, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection")
+ if(H5D_virtual_parse_source_name(ent->source_file_name, &ent->parsed_source_file_name, &ent->psfn_static_strlen, &ent->psfn_nsubs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source file name")
+ if(H5D_virtual_parse_source_name(ent->source_dset_name, &ent->parsed_source_dset_name, &ent->psdn_static_strlen, &ent->psdn_nsubs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name")
+ if((ent->psfn_nsubs == 0) && (ent->psdn_nsubs == 0)) {
+ if(ent->parsed_source_file_name)
+ ent->source_dset.file_name = ent->parsed_source_file_name->name_segment;
+ else
+ ent->source_dset.file_name = ent->source_file_name;
+ if(ent->parsed_source_dset_name)
+ ent->source_dset.dset_name = ent->parsed_source_dset_name->name_segment;
+ else
+ ent->source_dset.dset_name = ent->source_dset_name;
+ } /* end if */
+ ent->unlim_dim_source = H5S_get_select_unlim_dim(src_space);
+ ent->unlim_dim_virtual = H5S_get_select_unlim_dim(vspace);
+ if(ent->unlim_dim_virtual < 0) {
+ ent->source_dset.clipped_source_select = ent->source_select;
+ ent->source_dset.clipped_virtual_select = ent->source_dset.virtual_select;
+ } /* end if */
+
+ ent->unlim_extent_source = HSIZE_UNDEF;
+ ent->unlim_extent_virtual = HSIZE_UNDEF;
+ ent->clip_size_source = HSIZE_UNDEF;
+ ent->clip_size_virtual = HSIZE_UNDEF;
+ ent->source_space_status = H5O_VIRTUAL_STATUS_USER;
+ ent->virtual_space_status = H5O_VIRTUAL_STATUS_USER;
+
+ /* Update min_dims */
+ if(H5D_virtual_update_min_dims(&layout, layout.storage.u.virt.list_nused) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to update virtual dataset minimum dimensions")
+
+ /* Finish adding entry */
+ layout.storage.u.virt.list_nused++;
+
+done:
+ /* Only need to do things if we started to add an entry */
+ if(adding_entry) {
+ hbool_t free_list = FALSE;
+
+ /* Set chunk information in property list. If we are adding a new layout,
+ * use H5P__set_layout so other fields are initialized properly. If we are
+ * extending the layout, just use H5P_set directly so we don't mess with
+ * anything else. */
+ if(new_layout) {
+ if(H5P__set_layout(plist, &layout) < 0) {
+ HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout")
+ free_list = TRUE;
+ } /* end if */
+ } /* end if */
+ else
+ if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) {
+ HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout")
+ if(old_list != layout.storage.u.virt.list)
+ free_list = TRUE;
+ } /* end if */
+
+ /* Check if the entry has been partly allocated but not added to the
+ * property list or not included in list_nused */
+ if(ret_value < 0) {
+ /* Free incomplete entry if present */
+ if(ent) {
+ ent->source_file_name = (char *)H5MM_xfree(ent->source_file_name);
+ ent->source_dset_name = (char *)H5MM_xfree(ent->source_dset_name);
+ if(ent->source_dset.virtual_select && H5S_close(ent->source_dset.virtual_select) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection")
+ ent->source_dset.virtual_select = NULL;
+ if(ent->source_select && H5S_close(ent->source_select) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection")
+ ent->source_select = NULL;
+ H5D_virtual_free_parsed_name(ent->parsed_source_file_name);
+ ent->parsed_source_file_name = NULL;
+ H5D_virtual_free_parsed_name(ent->parsed_source_dset_name);
+ ent->parsed_source_dset_name = NULL;
+ } /* end if */
+
+ /* Free list if necessary */
+ if(free_list)
+ layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_xfree(layout.storage.u.virt.list);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_virtual() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_virtual_count
+ *
+ * Purpose: VDSINC
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Friday, February 13, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_virtual_count(hid_t dcpl_id, size_t *count/*out*/)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_layout_t layout; /* Layout information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", dcpl_id, count);
+
+ if(count) {
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Retrieve the layout property */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout")
+ if(H5D_VIRTUAL != layout.type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout")
+
+ /* Return the number of mappings */
+ *count = layout.storage.u.virt.list_nused;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_virtual_count() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_virtual_vspace
+ *
+ * Purpose: VDSINC
+ *
+ * Return: VDSINC
+ *
+ * Programmer: Neil Fortner
+ * Friday, February 13, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Pget_virtual_vspace(hid_t dcpl_id, size_t index)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_layout_t layout; /* Layout information */
+ H5S_t *space = NULL; /* Dataspace pointer */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("i", "iz", dcpl_id, index);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Retrieve the layout property */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout")
+ if(H5D_VIRTUAL != layout.type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout")
+
+ /* Get the virtual space */
+ if(index >= layout.storage.u.virt.list_nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)")
+ HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
+ if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].source_dset.virtual_select, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection")
+
+ /* Register ID */
+ if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space")
+
+done:
+ /* Free space on failure */
+ if((ret_value < 0) && space)
+ if(H5S_close(space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_virtual_vspace() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_virtual_srcspace
+ *
+ * Purpose: VDSINC
+ *
+ * Return: VDSINC
+ *
+ * Programmer: Neil Fortner
+ * Saturday, February 14, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_layout_t layout; /* Layout information */
+ H5S_t *space = NULL; /* Dataspace pointer */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("i", "iz", dcpl_id, index);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Retrieve the layout property */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout")
+ if(H5D_VIRTUAL != layout.type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout")
+
+ /* Attempt to open source dataset and patch extent if extent status is not
+ * H5O_VIRTUAL_STATUS_CORRECT, otherwise if status is
+ * H5O_VIRTUAL_STATUS_INVALID, patch with bounds of selection VDSINC */
+
+ /* Get the source space */
+ if(index >= layout.storage.u.virt.list_nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)")
+ HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
+ if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].source_select, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection")
+
+ /* Register ID */
+ if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space")
+
+done:
+ /* Free space on failure */
+ if((ret_value < 0) && space)
+ if(H5S_close(space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_virtual_srcspace() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_virtual_filename
+ *
+ * Purpose: VDSINC
+ *
+ * Return: VDSINC
+ *
+ * Programmer: Neil Fortner
+ * Saturday, February 14, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5Pget_virtual_filename(hid_t dcpl_id, size_t index, char *name/*out*/,
+ size_t size)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_layout_t layout; /* Layout information */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("Zs", "izxz", dcpl_id, index, name, size);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Retrieve the layout property */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout")
+ if(H5D_VIRTUAL != layout.type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout")
+
+ /* Get the virtual filename */
+ if(index >= layout.storage.u.virt.list_nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)")
+ HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
+ HDassert(layout.storage.u.virt.list[index].source_file_name);
+ if(name && (size > 0))
+ (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_file_name, size);
+ ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_file_name);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_virtual_filename() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_virtual_dsetname
+ *
+ * Purpose: VDSINC
+ *
+ * Return: VDSINC
+ *
+ * Programmer: Neil Fortner
+ * Saturday, February 14, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name/*out*/,
+ size_t size)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_layout_t layout; /* Layout information */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("Zs", "izxz", dcpl_id, index, name, size);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Retrieve the layout property */
+ if(H5P_get(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout")
+ if(H5D_VIRTUAL != layout.type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout")
+
+ /* Get the virtual filename */
+ if(index >= layout.storage.u.virt.list_nused)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)")
+ HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
+ HDassert(layout.storage.u.virt.list[index].source_dset_name);
+ if(name && (size > 0))
+ (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_dset_name, size);
+ ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_dset_name);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_virtual_dsetname() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_external
*
* Purpose: Adds an external file to the list of external files. PLIST_ID
@@ -2302,6 +3068,10 @@ H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time)
alloc_time = H5D_ALLOC_TIME_INCR;
break;
+ case H5D_VIRTUAL:
+ alloc_time = H5D_ALLOC_TIME_INCR;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default: