HDFFV-9724 Initial changes and test

This commit is contained in:
Allen Byrne 2017-12-11 14:44:30 -06:00
parent 9deb5267ca
commit 95e96246a6
9 changed files with 879 additions and 15 deletions

View File

@ -63,6 +63,8 @@ static herr_t H5D__update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset,
hid_t dapl_id);
static herr_t H5D_build_extfile_prefix(const H5D_t *dset, hid_t dapl_id,
char **extfile_prefix);
static herr_t H5D_build_vds_prefix(const H5D_t *dset, hid_t dapl_id,
char **vds_prefix);
static herr_t H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id);
static herr_t H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite,
hsize_t old_dim[]);
@ -1037,6 +1039,81 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_build_extfile_prefix() */
/*--------------------------------------------------------------------------
* Function: H5D_build_vds_prefix
*
* Purpose: Determine the vds file prefix to be used and store
* it in vds_prefix. Stores an empty string if no prefix
* should be used.
*
* Return: SUCCEED/FAIL
*--------------------------------------------------------------------------
*/
static herr_t
H5D_build_vds_prefix(const H5D_t *dset, hid_t dapl_id, char **vds_prefix /*out*/)
{
char *prefix = NULL; /* prefix used to look for the file */
char *vdspath = NULL; /* absolute path of directory the HDF5 file is in */
size_t vdspath_len; /* length of vdstpath */
size_t prefix_len; /* length of prefix */
size_t vds_prefix_len; /* length of expanded prefix */
H5P_genplist_t *plist = NULL; /* Property list pointer */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
HDassert(dset);
HDassert(dset->oloc.file);
vdspath = H5F_EXTPATH(dset->oloc.file);
HDassert(vdspath);
/* XXX: Future thread-safety note - getenv is not required
* to be reentrant.
*/
prefix = HDgetenv("HDF5_VDS_PREFIX");
if(prefix == NULL || *prefix == '\0') {
/* Set prefix to value of H5D_ACS_VDS_PREFIX_NAME property */
if(NULL == (plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
if(H5P_peek(plist, H5D_ACS_VDS_PREFIX_NAME, &prefix) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vds prefix")
} /* end if */
/* Prefix has to be checked for NULL / empty string again because the
* code above might have updated it.
*/
if(prefix == NULL || *prefix == '\0' || HDstrcmp(prefix, ".") == 0) {
/* filename is interpreted as relative to the current directory,
* does not need to be expanded
*/
if(NULL == (*vds_prefix = (char *)H5MM_strdup("")))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end if */
else {
if (HDstrncmp(prefix, "${ORIGIN}", HDstrlen("${ORIGIN}")) == 0) {
/* Replace ${ORIGIN} at beginning of prefix by directory of HDF5 file */
vdspath_len = HDstrlen(vdspath);
prefix_len = HDstrlen(prefix);
vds_prefix_len = vdspath_len + prefix_len - HDstrlen("${ORIGIN}") + 1;
if(NULL == (*vds_prefix = (char *)H5MM_malloc(vds_prefix_len)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate buffer")
HDsnprintf(*vds_prefix, vds_prefix_len, "%s%s", vdspath, prefix + HDstrlen("${ORIGIN}"));
} /* end if */
else {
if(NULL == (*vds_prefix = (char *)H5MM_strdup(prefix)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end else */
} /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_build_vds_prefix() */
/*-------------------------------------------------------------------------
* Function: H5D__create
@ -1220,6 +1297,10 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
if(H5D_build_extfile_prefix(new_dset, dapl_id, &new_dset->shared->extfile_prefix) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize external file prefix")
/* Set the vds file prefix */
if(H5D_build_vds_prefix(new_dset, dapl_id, &new_dset->shared->vds_prefix) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize vds prefix")
/* Add the dataset to the list of opened objects in the file */
if(H5FO_top_incr(new_dset->oloc.file, new_dset->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't incr object ref. count")
@ -1265,6 +1346,7 @@ done:
if(new_dset->shared->dcpl_id != 0 && H5I_dec_ref(new_dset->shared->dcpl_id) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "unable to decrement ref count on property list")
new_dset->shared->extfile_prefix = (char *)H5MM_xfree(new_dset->shared->extfile_prefix);
new_dset->shared->vds_prefix = (char *)H5MM_xfree(new_dset->shared->vds_prefix);
new_dset->shared = H5FL_FREE(H5D_shared_t, new_dset->shared);
} /* end if */
new_dset->oloc.file = NULL;
@ -1351,6 +1433,7 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id)
H5D_shared_t *shared_fo = NULL;
H5D_t *dataset = NULL;
char *extfile_prefix = NULL; /* Expanded external file prefix */
char *vds_prefix = NULL; /* Expanded vds prefix */
H5D_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@ -1374,6 +1457,10 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id)
if(H5D_build_extfile_prefix(dataset, dapl_id, &extfile_prefix) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize external file prefix")
/* Get the vds prefix */
if(H5D_build_vds_prefix(dataset, dapl_id, &vds_prefix) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize vds prefix")
/* Check if dataset was already open */
if(NULL == (shared_fo = (H5D_shared_t *)H5FO_opened(dataset->oloc.file, dataset->oloc.addr))) {
/* Clear any errors from H5FO_opened() */
@ -1399,6 +1486,11 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id)
/* Prevent string from being freed during done: */
extfile_prefix = NULL;
/* Set the vds file prefix */
dataset->shared->vds_prefix = vds_prefix;
/* Prevent string from being freed during done: */
vds_prefix = NULL;
} /* end if */
else {
/* Point to shared info */
@ -1430,12 +1522,14 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id)
done:
extfile_prefix = (char *)H5MM_xfree(extfile_prefix);
vds_prefix = (char *)H5MM_xfree(vds_prefix);
if(ret_value == NULL) {
/* Free the location--casting away const*/
if(dataset) {
if(shared_fo == NULL && dataset->shared) { /* Need to free shared fo */
dataset->shared->extfile_prefix = (char *)H5MM_xfree(dataset->shared->extfile_prefix);
dataset->shared->vds_prefix = (char *)H5MM_xfree(dataset->shared->vds_prefix);
dataset->shared = H5FL_FREE(H5D_shared_t, dataset->shared);
}
@ -1818,6 +1912,9 @@ H5D_close(H5D_t *dataset)
/* Free the external file prefix */
dataset->shared->extfile_prefix = (char *)H5MM_xfree(dataset->shared->extfile_prefix);
/* Free the vds file prefix */
dataset->shared->vds_prefix = (char *)H5MM_xfree(dataset->shared->vds_prefix);
/* Release layout, fill-value, efl & pipeline messages */
if(dataset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT)
free_failed |= (H5O_msg_reset(H5O_PLINE_ID, &dataset->shared->dcpl_cache.pline) < 0) ||
@ -3360,6 +3457,10 @@ H5D_get_access_plist(H5D_t *dset)
if(H5P_set(new_plist, H5D_ACS_VDS_PRINTF_GAP_NAME, &(dset->shared->layout.storage.u.virt.printf_gap)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set VDS printf gap")
/* Set the vds prefix option */
if(H5P_set(new_plist, H5D_ACS_VDS_PREFIX_NAME, &(dset->shared->vds_prefix)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set vds prefix")
/* Set the external file prefix option */
if(H5P_set(new_plist, H5D_ACS_EFILE_PREFIX_NAME, &(dset->shared->extfile_prefix)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set external file prefix")

View File

@ -476,6 +476,7 @@ typedef struct H5D_shared_t {
H5D_append_flush_t append_flush; /* Append flush property information */
char *extfile_prefix; /* expanded external file prefix */
char *vds_prefix; /* expanded vds prefix */
} H5D_shared_t;
struct H5D_t {
@ -598,7 +599,7 @@ H5_DLL herr_t H5D_set_io_info_dxpls(H5D_io_info_t *io_info, hid_t dxpl_id);
H5_DLL herr_t H5D__format_convert(H5D_t *dataset, hid_t dxpl_id);
/* Internal I/O routines */
H5_DLL herr_t H5D__pre_write(H5D_t *dset, hbool_t direct_write, hid_t mem_type_id,
H5_DLL herr_t H5D__pre_write(H5D_t *dset, hbool_t direct_write, hid_t mem_type_id,
const H5S_t *mem_space, const H5S_t *file_space, hid_t dxpl_id, const void *buf);
H5_DLL herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id,
const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist,

View File

@ -47,12 +47,13 @@
#define H5D_CRT_EXT_FILE_LIST_NAME "efl" /* External file list */
/* ======== Dataset access property names ======== */
#define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */
#define H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME "rdcc_nbytes" /* Size of raw data chunk cache(bytes) */
#define H5D_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */
#define H5D_ACS_VDS_VIEW_NAME "vds_view" /* VDS view option */
#define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */
#define H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME "rdcc_nbytes" /* Size of raw data chunk cache(bytes) */
#define H5D_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */
#define H5D_ACS_VDS_VIEW_NAME "vds_view" /* VDS view option */
#define H5D_ACS_VDS_PRINTF_GAP_NAME "vds_printf_gap" /* VDS printf gap size */
#define H5D_ACS_APPEND_FLUSH_NAME "append_flush" /* Append flush actions */
#define H5D_ACS_VDS_PREFIX_NAME "vds_prefix" /* VDS file prefix */
#define H5D_ACS_APPEND_FLUSH_NAME "append_flush" /* Append flush actions */
#define H5D_ACS_EFILE_PREFIX_NAME "external file prefix" /* External file prefix */
/* ======== Data transfer properties ======== */

View File

@ -731,6 +731,38 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__virtual_delete */
/*--------------------------------------------------------------------------
* Function: H5D__virtual_build_name
*
* Purpose: Prepend PREFIX to FILE_NAME and store in FULL_NAME
*
* Return: Non-negative on success/Negative on failure
*--------------------------------------------------------------------------*/
static herr_t
H5D__virtual_build_name(char *prefix, char *file_name, char **full_name/*out*/)
{
size_t prefix_len; /* length of prefix */
size_t fname_len; /* Length of external link file name */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
prefix_len = HDstrlen(prefix);
fname_len = HDstrlen(file_name);
/* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */
if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer")
/* Compose the full file name */
HDsnprintf(*full_name, (prefix_len + fname_len + 2), "%s%s%s", prefix,
(H5_CHECK_DELIMITER(prefix[prefix_len - 1]) ? "" : H5_DIR_SEPS), file_name);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D__virtual_build_name() */
/*-------------------------------------------------------------------------
* Function: H5D__virtual_open_source_dset
@ -750,9 +782,11 @@ H5D__virtual_open_source_dset(const H5D_t *vdset,
H5O_storage_virtual_srcdset_t *source_dset, hid_t dxpl_id)
{
H5F_t *src_file = NULL; /* Source file */
char *vds_prefix = NULL; /* Source file vds_prefix */
hbool_t src_file_open = FALSE; /* Whether we have opened and need to close src_file */
H5G_loc_t src_root_loc; /* Object location of source file root group */
herr_t ret_value = SUCCEED; /* Return value */
char *full_name = NULL; /* File name with prefix */
FUNC_ENTER_STATIC
@ -762,14 +796,27 @@ H5D__virtual_open_source_dset(const H5D_t *vdset,
HDassert(!source_dset->dset);
HDassert(source_dset->file_name);
HDassert(source_dset->dset_name);
vds_prefix = vdset->shared->vds_prefix;
/* Check if we need to open the source file */
if(HDstrcmp(source_dset->file_name, ".")) {
/* Open the source file */
if(NULL == (src_file = H5F_open(source_dset->file_name, H5F_INTENT(vdset->oloc.file) & (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ), H5P_FILE_CREATE_DEFAULT, vdset->shared->layout.storage.u.virt.source_fapl, dxpl_id)))
H5E_clear_stack(NULL); /* Quick hack until proper support for H5Fopen with missing file is implemented */
else
src_file_open = TRUE;
if(vds_prefix && HDstrlen(vds_prefix) > 0) {
if(H5D__virtual_build_name(vds_prefix, source_dset->file_name, &full_name/*out*/) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
/* Open the source file */
if(NULL == (src_file = H5F_open(full_name, H5F_INTENT(vdset->oloc.file) & (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ), H5P_FILE_CREATE_DEFAULT, vdset->shared->layout.storage.u.virt.source_fapl, dxpl_id)))
H5E_clear_stack(NULL); /* Quick hack until proper support for H5Fopen with missing file is implemented */
else
src_file_open = TRUE;
full_name = (char *)H5MM_xfree(full_name);
}
else {
/* Open the source file */
if(NULL == (src_file = H5F_open(source_dset->file_name, H5F_INTENT(vdset->oloc.file) & (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ), H5P_FILE_CREATE_DEFAULT, vdset->shared->layout.storage.u.virt.source_fapl, dxpl_id)))
H5E_clear_stack(NULL); /* Quick hack until proper support for H5Fopen with missing file is implemented */
else
src_file_open = TRUE;
}
} /* end if */
else
/* Source file is ".", use the virtual dataset's file */
@ -1407,7 +1454,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection")
} /* end if */
/* Update cached values unlim_extent_source and
/* Update cached values unlim_extent_source and
* clip_size_virtual */
storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source];
storage->list[i].clip_size_virtual = clip_size;
@ -1559,7 +1606,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
/* Mark the space as dirty, for later writing to the file */
if(H5F_INTENT(dset->oloc.file) & H5F_ACC_RDWR)
if(H5F_INTENT(dset->oloc.file) & H5F_ACC_RDWR)
if(H5D__mark(dset, dxpl_id, H5D_MARK_SPACE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to mark dataspace as dirty")
} /* end if */
@ -2246,7 +2293,7 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info,
HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "can't close projected memory space")
storage->list[i].sub_dset[j].projected_mem_space = NULL;
} /* end if */
else
else
*tot_nelmts += (hsize_t)select_nelmts;
} /* end if */
} /* end for */
@ -2506,7 +2553,7 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to clip fill selection")
/* Write fill values to memory buffer */
if(H5D__fill(io_info->dset->shared->dcpl_cache.fill.buf, io_info->dset->shared->type, io_info->u.rbuf,
if(H5D__fill(io_info->dset->shared->dcpl_cache.fill.buf, io_info->dset->shared->type, io_info->u.rbuf,
type_info->mem_type, fill_space, io_info->md_dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "filling buf failed")

View File

@ -489,6 +489,7 @@ typedef struct H5F_t H5F_t;
#define H5F_ACS_METADATA_READ_ATTEMPTS_NAME "metadata_read_attempts" /* # of metadata read attempts */
#define H5F_ACS_OBJECT_FLUSH_CB_NAME "object_flush_cb" /* Object flush callback */
#define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */
#define H5F_ACS_VDS_SIZE_NAME "vds_size" /* Size of vds file cache */
#define H5F_ACS_FILE_IMAGE_INFO_NAME "file_image_info" /* struct containing initial file image and callback info */
#define H5F_ACS_CLEAR_STATUS_FLAGS_NAME "clear_status_flags" /* Whether to clear superblock status_flags (private property only used by h5clear) */
#define H5F_ACS_USE_MDC_LOGGING_NAME "use_mdc_logging" /* Whether to use metadata cache logging */

View File

@ -71,6 +71,17 @@
#define H5D_ACS_VDS_PRINTF_GAP_DEF (hsize_t)0
#define H5D_ACS_VDS_PRINTF_GAP_ENC H5P__encode_hsize_t
#define H5D_ACS_VDS_PRINTF_GAP_DEC H5P__decode_hsize_t
/* Definitions for VDS file prefix */
#define H5D_ACS_VDS_PREFIX_SIZE sizeof(char *)
#define H5D_ACS_VDS_PREFIX_DEF NULL /*default is no prefix */
#define H5D_ACS_VDS_PREFIX_SET H5P__dapl_vds_file_pref_set
#define H5D_ACS_VDS_PREFIX_GET H5P__dapl_vds_file_pref_get
#define H5D_ACS_VDS_PREFIX_ENC H5P__dapl_vds_file_pref_enc
#define H5D_ACS_VDS_PREFIX_DEC H5P__dapl_vds_file_pref_dec
#define H5D_ACS_VDS_PREFIX_DEL H5P__dapl_vds_file_pref_del
#define H5D_ACS_VDS_PREFIX_COPY H5P__dapl_vds_file_pref_copy
#define H5D_ACS_VDS_PREFIX_CMP H5P__dapl_vds_file_pref_cmp
#define H5D_ACS_VDS_PREFIX_CLOSE H5P__dapl_vds_file_pref_close
/* Definition for append flush */
#define H5D_ACS_APPEND_FLUSH_SIZE sizeof(H5D_append_flush_t)
#define H5D_ACS_APPEND_FLUSH_DEF {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},NULL,NULL}
@ -112,6 +123,14 @@ static herr_t H5P__decode_chunk_cache_nbytes(const void **_pp, void *_value);
/* Property list callbacks */
static herr_t H5P__dacc_vds_view_enc(const void *value, void **pp, size_t *size);
static herr_t H5P__dacc_vds_view_dec(const void **pp, void *value);
static herr_t H5P__dapl_vds_file_pref_set(hid_t prop_id, const char* name, size_t size, void* value);
static herr_t H5P__dapl_vds_file_pref_get(hid_t prop_id, const char* name, size_t size, void* value);
static herr_t H5P__dapl_vds_file_pref_enc(const void *value, void **_pp, size_t *size);
static herr_t H5P__dapl_vds_file_pref_dec(const void **_pp, void *value);
static herr_t H5P__dapl_vds_file_pref_del(hid_t prop_id, const char* name, size_t size, void* value);
static herr_t H5P__dapl_vds_file_pref_copy(const char* name, size_t size, void* value);
static int H5P__dapl_vds_file_pref_cmp(const void *value1, const void *value2, size_t size);
static herr_t H5P__dapl_vds_file_pref_close(const char* name, size_t size, void* value);
/* Property list callbacks */
static herr_t H5P__dapl_efile_pref_set(hid_t prop_id, const char* name, size_t size, void* value);
@ -160,6 +179,7 @@ const H5P_libclass_t H5P_CLS_DACC[1] = {{
/* Property value defaults */
static const H5D_append_flush_t H5D_def_append_flush_g = H5D_ACS_APPEND_FLUSH_DEF; /* Default setting for append flush */
static const char *H5D_def_efile_prefix_g = H5D_ACS_EFILE_PREFIX_DEF; /* Default external file prefix string */
static const char *H5D_def_vds_prefix_g = H5D_ACS_VDS_PREFIX_DEF; /* Default vds prefix string */
/*-------------------------------------------------------------------------
@ -210,6 +230,12 @@ H5P__dacc_reg_prop(H5P_genclass_t *pclass)
NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register property for vds prefix */
if(H5P_register_real(pclass, H5D_ACS_VDS_PREFIX_NAME, H5D_ACS_VDS_PREFIX_SIZE, &H5D_def_vds_prefix_g,
NULL, H5D_ACS_VDS_PREFIX_SET, H5D_ACS_VDS_PREFIX_GET, H5D_ACS_VDS_PREFIX_ENC, H5D_ACS_VDS_PREFIX_DEC,
H5D_ACS_VDS_PREFIX_DEL, H5D_ACS_VDS_PREFIX_COPY, H5D_ACS_VDS_PREFIX_CMP, H5D_ACS_VDS_PREFIX_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register info for append flush */
/* (Note: this property should not have an encode/decode callback -QAK) */
if(H5P_register_real(pclass, H5D_ACS_APPEND_FLUSH_NAME, H5D_ACS_APPEND_FLUSH_SIZE, &H5D_def_append_flush_g,
@ -226,6 +252,254 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__dacc_reg_prop() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_set
*
* Purpose: Copies a vds file prefix property when it's set
* for a property list
*
* Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
H5P__dapl_vds_file_pref_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
size_t H5_ATTR_UNUSED size, void *value)
{
FUNC_ENTER_STATIC_NOERR
/* Sanity check */
HDassert(value);
/* Copy the prefix */
*(char **)value = H5MM_xstrdup(*(const char **)value);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__dapl_vds_file_pref_set() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_get
*
* Purpose: Copies a vds file prefix property when it's retrieved
* from a property list
*
* Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
H5P__dapl_vds_file_pref_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
size_t H5_ATTR_UNUSED size, void *value)
{
FUNC_ENTER_STATIC_NOERR
/* Sanity check */
HDassert(value);
/* Copy the prefix */
*(char **)value = H5MM_xstrdup(*(const char **)value);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__dapl_vds_file_pref_get() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_enc
*
* Purpose: Callback routine which is called whenever the vds file flags
* property in the dataset access property list is
* encoded.
*
* Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
H5P__dapl_vds_file_pref_enc(const void *value, void **_pp, size_t *size)
{
const char *vds_file_pref = *(const char * const *)value;
uint8_t **pp = (uint8_t **)_pp;
size_t len = 0;
uint64_t enc_value;
unsigned enc_size;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
/* calculate prefix length */
if(NULL != vds_file_pref)
len = HDstrlen(vds_file_pref);
enc_value = (uint64_t)len;
enc_size = H5VM_limit_enc_size(enc_value);
HDassert(enc_size < 256);
if(NULL != *pp) {
/* encode the length of the prefix */
*(*pp)++ = (uint8_t)enc_size;
UINT64ENCODE_VAR(*pp, enc_value, enc_size);
/* encode the prefix */
if(NULL != vds_file_pref) {
HDmemcpy(*(char **)pp, vds_file_pref, len);
*pp += len;
} /* end if */
} /* end if */
*size += (1 + enc_size);
if(NULL != vds_file_pref)
*size += len;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__dapl_vds_file_pref_enc() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_dec
*
* Purpose: Callback routine which is called whenever the vds file prefix
* property in the dataset access property list is
* decoded.
*
* Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
H5P__dapl_vds_file_pref_dec(const void **_pp, void *_value)
{
char **vds_file_pref = (char **)_value;
const uint8_t **pp = (const uint8_t **)_pp;
size_t len;
uint64_t enc_value; /* Decoded property value */
unsigned enc_size; /* Size of encoded property */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
HDassert(pp);
HDassert(*pp);
HDassert(vds_file_pref);
HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
/* Decode the size */
enc_size = *(*pp)++;
HDassert(enc_size < 256);
/* Decode the value */
UINT64DECODE_VAR(*pp, enc_value, enc_size);
len = (size_t)enc_value;
if(0 != len) {
/* Make a copy of the user's prefix string */
if(NULL == (*vds_file_pref = (char *)H5MM_malloc(len + 1)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for prefix")
HDstrncpy(*vds_file_pref, *(const char **)pp, len);
(*vds_file_pref)[len] = '\0';
*pp += len;
} /* end if */
else
*vds_file_pref = NULL;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__dapl_vds_file_pref_dec() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_del
*
* Purpose: Frees memory used to store the vds file prefix string
*
* Return: SUCCEED (Can't fail)
*-------------------------------------------------------------------------
*/
static herr_t
H5P__dapl_vds_file_pref_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
size_t H5_ATTR_UNUSED size, void *value)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(value);
H5MM_xfree(*(void **)value);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__dapl_vds_file_pref_del() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_copy
*
* Purpose: Creates a copy of the vds file prefix string
*
* Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
H5P__dapl_vds_file_pref_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(value);
*(char **)value = H5MM_xstrdup(*(const char **)value);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__dapl_vds_file_pref_copy() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_cmp
*
* Purpose: Callback routine which is called whenever the vds file prefix
* property in the dataset creation property list is
* compared.
*
* Return: zero if VALUE1 and VALUE2 are equal, non zero otherwise.
*-------------------------------------------------------------------------
*/
static int
H5P__dapl_vds_file_pref_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
{
const char *pref1 = *(const char * const *)value1;
const char *pref2 = *(const char * const *)value2;
int ret_value = 0;
FUNC_ENTER_NOAPI_NOINIT_NOERR
if(NULL == pref1 && NULL != pref2)
HGOTO_DONE(1);
if(NULL != pref1 && NULL == pref2)
HGOTO_DONE(-1);
if(NULL != pref1 && NULL != pref2)
ret_value = HDstrcmp(pref1, pref2);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__dapl_vds_file_pref_cmp() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_vds_file_pref_close
*
* Purpose: Frees memory used to store the vds file prefix string
*
* Return: SUCCEED/FAIL
*-------------------------------------------------------------------------
*/
static herr_t
H5P__dapl_vds_file_pref_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(value);
H5MM_xfree(*(void **)value);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__dapl_vds_file_pref_close() */
/*-------------------------------------------------------------------------
* Function: H5P__dapl_efile_pref_set
@ -1220,3 +1494,95 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_efile_prefix() */
/*-------------------------------------------------------------------------
* Function: H5Pset_virtual_prefix
*
* Purpose: Set a prefix to be applied to the path of any vds files
* traversed.
*
* If the prefix starts with ${ORIGIN}, this will be replaced by
* the absolute path of the directory of the HDF5 file containing
* the dataset.
*
* If the prefix is ".", no prefix will be applied.
*
* This property can be overwritten by the environment variable
* HDF5_VDS_PREFIX.
*
* Return: Non-negative on success/Negative on failure
*-------------------------------------------------------------------------
*/
herr_t
H5Pset_virtual_prefix(hid_t plist_id, const char *prefix)
{
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "i*s", plist_id, prefix);
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Set prefix */
if(H5P_set(plist, H5D_ACS_VDS_PREFIX_NAME, &prefix) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set prefix info")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pset_virtual_prefix() */
/*-------------------------------------------------------------------------
* Function: H5Pget_virtual_prefix
*
* Purpose: Gets the prefix to be applied to any vds file
* traversals made using this property list.
*
* If the pointer is not NULL, it points to a user-allocated
* buffer.
*
* Return: Non-negative on success/Negative on failure
*-------------------------------------------------------------------------
*/
ssize_t
H5Pget_virtual_prefix(hid_t plist_id, char *prefix, size_t size)
{
H5P_genplist_t *plist; /* Property list pointer */
char *my_prefix; /* Library's copy of the prefix */
size_t len; /* Length of prefix string */
ssize_t ret_value; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE3("Zs", "i*sz", plist_id, prefix, size);
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get the current prefix */
if(H5P_peek(plist, H5D_ACS_VDS_PREFIX_NAME, &my_prefix) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vds file prefix")
/* Check for prefix being set */
if(my_prefix) {
/* Copy to user's buffer, if given */
len = HDstrlen(my_prefix);
if(prefix) {
HDstrncpy(prefix, my_prefix, MIN(len + 1, size));
if(len >= size)
prefix[size - 1] = '\0';
} /* end if */
} /* end if */
else
len = 0;
/* Set return value */
ret_value = (ssize_t)len;
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_virtual_prefix() */

View File

@ -2461,6 +2461,75 @@ done:
} /* end H5Pget_elink_file_cache_size() */
/*-------------------------------------------------------------------------
* Function: H5Pset_vds_file_cache_size
*
* Purpose: Sets the number of files opened through vds links
* from the file associated with this fapl to be held open
* in that file's vds file cache. When the maximum
* number of files is reached, the least recently used file
* is closed (unless it is opened from somewhere else).
*
* Return: Non-negative on success/Negative on failure
*-------------------------------------------------------------------------
*/
herr_t
H5Pset_vds_file_cache_size(hid_t plist_id, unsigned vds_size)
{
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "iIu", plist_id, vds_size);
/* 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 value */
if(H5P_set(plist, H5F_ACS_VDS_SIZE_NAME, &vds_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set elink file cache size")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pset_vds_file_cache_size() */
/*-------------------------------------------------------------------------
* Function: H5Pget_vds_file_cache_size
*
* Purpose: Gets the number of files opened through vds links
* from the file associated with this fapl to be held open
* in that file's vds file cache. When the maximum
* number of files is reached, the least recently used file
* is closed (unless it is opened from somewhere else).
*
* Return: Non-negative on success/Negative on failure
*-------------------------------------------------------------------------
*/
herr_t
H5Pget_vds_file_cache_size(hid_t plist_id, unsigned *vds_size)
{
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "i*Iu", plist_id, vds_size);
/* 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(vds_size)
if(H5P_get(plist, H5F_ACS_VDS_SIZE_NAME, vds_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink file cache size")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_vds_file_cache_size() */
/*-------------------------------------------------------------------------
* Function: H5Pset_file_image
*

View File

@ -343,6 +343,8 @@ H5_DLL herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low,
H5F_libver_t *high);
H5_DLL herr_t H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size);
H5_DLL herr_t H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size);
H5_DLL herr_t H5Pset_vds_file_cache_size(hid_t plist_id, unsigned vds_size);
H5_DLL herr_t H5Pget_vds_file_cache_size(hid_t plist_id, unsigned *vds_size);
H5_DLL herr_t H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len);
H5_DLL herr_t H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr);
H5_DLL herr_t H5Pset_file_image_callbacks(hid_t fapl_id,
@ -420,6 +422,8 @@ H5_DLL herr_t H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view);
H5_DLL herr_t H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view);
H5_DLL herr_t H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size);
H5_DLL herr_t H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size);
H5_DLL herr_t H5Pset_virtual_prefix(hid_t dapl_id, const char* prefix);
H5_DLL ssize_t H5Pget_virtual_prefix(hid_t dapl_id, char* prefix /*out*/, size_t size);
H5_DLL herr_t H5Pset_append_flush(hid_t plist_id, unsigned ndims,
const hsize_t boundary[], H5D_append_cb_t func, void *udata);
H5_DLL herr_t H5Pget_append_flush(hid_t plist_id, unsigned dims,

View File

@ -36,6 +36,12 @@ const char *FILENAME[] = {
"vds_src_1",
"vds%%_src",
"vds_dapl",
"vds_virt_2",
"vds_virt_3",
"vds_src_2",
"vds_src_3",
"vds%%_src2",
"vds_dapl2",
NULL
};
@ -49,6 +55,8 @@ const char *FILENAME[] = {
#define FILENAME_BUF_SIZE 1024
#define TMPDIR "tmp/"
/*-------------------------------------------------------------------------
* Function: vds_select_equal
@ -1140,6 +1148,271 @@ error:
return 1;
} /* end test_api() */
/*-------------------------------------------------------------------------
* Function: vds_link_prefix
*
* Purpose: Set up vds link prefix via H5Pset_virtual_prefix() to be "tmp"
* Should be able to access the target source files in tmp directory via the prefix set
* by H5Pset_virtual_prefix()
*
* Return: Success: 0
* Failure: -1
*-------------------------------------------------------------------------
*/
static int
test_vds_prefix(unsigned config, hid_t fapl)
{
char srcfilename[FILENAME_BUF_SIZE];
char srcfilename_map[FILENAME_BUF_SIZE];
char vfilename[FILENAME_BUF_SIZE];
char vfilename2[FILENAME_BUF_SIZE];
char srcfilenamepct[FILENAME_BUF_SIZE];
char srcfilenamepct_map[FILENAME_BUF_SIZE];
const char *srcfilenamepct_map_orig = "vds%%%%_src";
hid_t srcfile[4] = {-1, -1, -1, -1}; /* Files with source dsets */
hid_t vfile = -1; /* File with virtual dset */
hid_t vfile2 = -1; /* File with copied virtual dset */
hid_t dcpl = -1; /* Dataset creation property list */
hid_t dapl = -1; /* Dataset access property list */
hid_t srcspace[4] = {-1, -1, -1, -1}; /* Source dataspaces */
hid_t vspace[4] = {-1, -1, -1, -1}; /* Virtual dset dataspaces */
hid_t memspace = -1; /* Memory dataspace */
hid_t srcdset[4] = {-1, -1, -1, -1}; /* Source datsets */
hid_t vdset = -1; /* Virtual dataset */
hsize_t dims[4] = {10, 26, 0, 0}; /* Data space current size */
hsize_t start[4]; /* Hyperslab start */
hsize_t stride[4]; /* Hyperslab stride */
hsize_t count[4]; /* Hyperslab count */
hsize_t block[4]; /* Hyperslab block */
hssize_t offset[2] = {0, 0}; /* Selection offset */
int buf[10][26]; /* Write and expected read buffer */
int rbuf[10][26]; /* Read buffer */
int rbuf99[9][9]; /* 9x9 Read buffer */
int evbuf[10][26]; /* Expected VDS "buffer" */
int erbuf[10][26]; /* Expected read buffer */
int fill = -1; /* Fill value */
herr_t ret; /* Generic return value */
int i, j;
char buffer[1024]; /* buffer to read vds_prefix */
TESTING("basic virtual dataset I/O via H5Pset_vds_prefix()")
h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename);
h5_fixname(FILENAME[7], fapl, vfilename2, sizeof vfilename2);
h5_fixname(FILENAME[8], fapl, srcfilename, sizeof srcfilename);
h5_fixname_printf(FILENAME[8], fapl, srcfilename_map, sizeof srcfilename_map);
h5_fixname(FILENAME[10], fapl, srcfilenamepct, sizeof srcfilenamepct);
h5_fixname_printf(srcfilenamepct_map_orig, fapl, srcfilenamepct_map, sizeof srcfilenamepct_map);
/* create tmp directory and get current working directory path */
if (HDmkdir(TMPDIR, (mode_t)0755) < 0 && errno != EEXIST)
TEST_ERROR
/* Create DCPL */
if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
TEST_ERROR
/* Set fill value */
if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fill) < 0)
TEST_ERROR
/* Initialize VDS prefix items */
if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
TEST_ERROR
if(H5Pset_virtual_prefix(dapl, TMPDIR) < 0)
TEST_ERROR
if(H5Pget_virtual_prefix(dapl, buffer, sizeof(buffer)) < 0)
TEST_ERROR
if(HDstrcmp(buffer, TMPDIR) != 0)
FAIL_PUTS_ERROR("vds prefix not set correctly");
/*
* Test 1: All - all selection
*/
/* Create source dataspace */
if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0)
TEST_ERROR
/* Create virtual dataspace */
if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0)
TEST_ERROR
/* Select all (should not be necessary, but just to be sure) */
if(H5Sselect_all(srcspace[0]) < 0)
TEST_ERROR
if(H5Sselect_all(vspace[0]) < 0)
TEST_ERROR
/* Add virtual layout mapping */
if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename_map : ".", "src_dset", srcspace[0]) < 0)
TEST_ERROR
/* Create virtual file */
if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
TEST_ERROR
/* Create source file if requested */
if(config & TEST_IO_DIFFERENT_FILE) {
HDgetcwd(buffer, 1024);
HDchdir(TMPDIR);
if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
TEST_ERROR
HDchdir(buffer);
} /* end if */
else {
srcfile[0] = vfile;
if(H5Iinc_ref(srcfile[0]) < 0)
TEST_ERROR
} /* end if */
/* Create source dataset */
if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR
/* Create virtual dataset */
if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, dapl)) < 0)
TEST_ERROR
/* Populate write buffer */
for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++)
for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++)
buf[i][j] = (i * (int)(sizeof(buf[0]) / sizeof(buf[0][0]))) + j;
/* Write data directly to source dataset */
if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0)
TEST_ERROR
/* Close srcdset and srcfile if config option specified */
if(config & TEST_IO_CLOSE_SRC) {
if(H5Dclose(srcdset[0]) < 0)
TEST_ERROR
srcdset[0] = -1;
if(config & TEST_IO_DIFFERENT_FILE) {
if(H5Fclose(srcfile[0]) < 0)
TEST_ERROR
srcfile[0] = -1;
} /* end if */
} /* end if */
/* Reopen virtual dataset and file if config option specified */
if(config & TEST_IO_REOPEN_VIRT) {
if(H5Dclose(vdset) < 0)
TEST_ERROR
vdset = -1;
if(H5Fclose(vfile) < 0)
TEST_ERROR
vfile = -1;
if((vfile = H5Fopen(vfilename, H5F_ACC_RDWR, fapl)) < 0)
TEST_ERROR
if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0)
TEST_ERROR
} /* end if */
/* Read data through virtual dataset */
HDmemset(rbuf[0], 0, sizeof(rbuf));
if(H5Dread(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0)
TEST_ERROR
/* Verify read data */
for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++) {
for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++)
if(rbuf[i][j] != buf[i][j]) {
TEST_ERROR
}
}
/* Adjust write buffer */
for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++)
for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++)
buf[i][j] += (int)(sizeof(buf) / sizeof(buf[0][0]));
/* Write data through virtual dataset */
if(H5Dwrite(vdset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf[0]) < 0)
TEST_ERROR
/* Reopen srcdset and srcfile if config option specified */
if(config & TEST_IO_CLOSE_SRC) {
if(config & TEST_IO_DIFFERENT_FILE) {
HDgetcwd(buffer, 1024);
HDchdir(TMPDIR);
if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, fapl)) < 0)
TEST_ERROR
HDchdir(buffer);
}
if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset", H5P_DEFAULT)) < 0)
TEST_ERROR
} /* end if */
/* Read data directly from source dataset */
HDmemset(rbuf[0], 0, sizeof(rbuf));
if(H5Dread(srcdset[0], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0)
TEST_ERROR
/* Verify read data */
for(i = 0; i < (int)(sizeof(buf) / sizeof(buf[0])); i++)
for(j = 0; j < (int)(sizeof(buf[0]) / sizeof(buf[0][0])); j++)
if(rbuf[i][j] != buf[i][j])
TEST_ERROR
/* Close */
if(H5Dclose(srcdset[0]) < 0)
TEST_ERROR
srcdset[0] = -1;
if(H5Dclose(vdset) < 0)
TEST_ERROR
vdset = -1;
if(H5Fclose(srcfile[0]) < 0)
TEST_ERROR
srcfile[0] = -1;
if(H5Fclose(vfile) < 0)
TEST_ERROR
vfile = -1;
if(H5Sclose(srcspace[0]) < 0)
TEST_ERROR
srcspace[0] = -1;
if(H5Sclose(vspace[0]) < 0)
TEST_ERROR
vspace[0] = -1;
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
for(i = 0; i < (int)(sizeof(srcdset) / sizeof(srcdset[0])); i++) {
if(srcdset[i] >= 0)
(void)H5Dclose(srcdset[i]);
} /* end for */
if(vdset >= 0)
(void)H5Dclose(vdset);
for(i = 0; i < (int)(sizeof(srcfile) / sizeof(srcfile[0])); i++) {
if(srcfile[i] >= 0)
(void)H5Fclose(srcfile[i]);
} /* end for */
if(vfile >= 0)
(void)H5Fclose(vfile);
if(vfile2 >= 0)
(void)H5Fclose(vfile2);
for(i = 0; i < (int)(sizeof(srcspace) / sizeof(srcspace[0])); i++) {
if(srcspace[i] >= 0)
(void)H5Sclose(srcspace[i]);
} /* end for */
for(i = 0; i < (int)(sizeof(vspace) / sizeof(vspace[0])); i++) {
if(vspace[i] >= 0)
(void)H5Sclose(vspace[i]);
} /* end for */
if(memspace >= 0)
(void)H5Sclose(memspace);
if(dcpl >= 0)
(void)H5Pclose(dcpl);
} H5E_END_TRY;
return 1;
} /* end vds_link_prefix() */
/*-------------------------------------------------------------------------
* Function: test_basic_io
@ -11299,6 +11572,7 @@ main(void)
for(bit_config = 0; bit_config < TEST_IO_NTESTS; bit_config++) {
printf("Config: %s%s%s\n", bit_config & TEST_IO_CLOSE_SRC ? "closed source dataset, " : "", bit_config & TEST_IO_DIFFERENT_FILE ? "different source file" : "same source file", bit_config & TEST_IO_REOPEN_VIRT ? ", reopen virtual file" : "");
nerrors += test_basic_io(bit_config, fapl);
nerrors += test_vds_prefix(bit_config, fapl);
nerrors += test_unlim(bit_config, fapl);
nerrors += test_printf(bit_config, fapl);
nerrors += test_all(bit_config, fapl);