diff options
34 files changed, 1307 insertions, 360 deletions
diff --git a/src/H5Ddbg.c b/src/H5Ddbg.c index a7c6dc1..adec71b 100644 --- a/src/H5Ddbg.c +++ b/src/H5Ddbg.c @@ -116,6 +116,8 @@ H5Ddebug(hid_t dset_id) (void)H5D__chunk_dump_index(dset, H5AC_dxpl_id, stdout); else if(H5D_CONTIGUOUS == dset->shared->layout.type) HDfprintf(stdout, " %-10s %a\n", "Address:", dset->shared->layout.storage.u.contig.addr); + else if(H5D_VIRTUAL == dset->shared->layout.type) + HDassert(0 && "Not yet implemented...");//VDSINC done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Dint.c b/src/H5Dint.c index ee346f3..61a2ed7 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1296,6 +1296,10 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id) fill_prop->alloc_time = H5D_ALLOC_TIME_INCR; break; + case H5D_VIRTUAL: + fill_prop->alloc_time = H5D_ALLOC_TIME_INCR; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1310,7 +1314,8 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id) alloc_time_state = 0; if((dataset->shared->layout.type == H5D_COMPACT && fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY) || (dataset->shared->layout.type == H5D_CONTIGUOUS && fill_prop->alloc_time == H5D_ALLOC_TIME_LATE) - || (dataset->shared->layout.type == H5D_CHUNKED && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR)) + || (dataset->shared->layout.type == H5D_CHUNKED && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR) + || (dataset->shared->layout.type == H5D_VIRTUAL && fill_prop->alloc_time == H5D_ALLOC_TIME_INCR)) alloc_time_state = 1; /* Set revised fill value properties, if they are different from the defaults */ @@ -1437,6 +1442,10 @@ H5D_close(H5D_t *dataset) dataset->shared->layout.storage.u.compact.buf = H5MM_xfree(dataset->shared->layout.storage.u.compact.buf); break; + case H5D_VIRTUAL: + /* Close datasets here? VDSINC */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1681,6 +1690,10 @@ H5D__alloc_storage(const H5D_t *dset, hid_t dxpl_id, H5D_time_alloc_t time_alloc } /* end if */ break; + case H5D_VIRTUAL: + /* No-op for now VDSINC */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1800,6 +1813,9 @@ H5D__init_storage(const H5D_t *dset, hbool_t full_overwrite, hsize_t old_dim[], break; } /* end block */ + case H5D_VIRTUAL: + /* No-op for now VDSINC */ + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1856,6 +1872,10 @@ H5D__get_storage_size(H5D_t *dset, hid_t dxpl_id, hsize_t *storage_size) *storage_size = dset->shared->layout.storage.u.compact.size; break; + case H5D_VIRTUAL: + /* Just set to 0 until private data is implemented VDSINC */ + *storage_size = 0; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1894,6 +1914,7 @@ H5D__get_offset(const H5D_t *dset) switch(dset->shared->layout.type) { case H5D_CHUNKED: case H5D_COMPACT: + case H5D_VIRTUAL: break; case H5D_CONTIGUOUS: diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index 5929163..0dbe4db 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -174,6 +174,7 @@ H5D__layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t includ break; case H5D_VIRTUAL: + HDassert((layout->storage.u.virt.list_nused > 0) && "checking code coverage...");//VDSINC ret_value += H5F_SIZEOF_ADDR(f); /* Address of global heap */ ret_value += 4; /* Global heap index */ break; diff --git a/src/H5Doh.c b/src/H5Doh.c index abf76d0..a688fe7 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -398,6 +398,9 @@ H5O__dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) if(H5D__chunk_bh_info(f, dxpl_id, &layout, &pline, &(bh_info->index_size)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine chunked dataset btree info") } /* end if */ + else if(layout.type == H5D_VIRTUAL && H5D__virtual_is_space_alloc(&layout.storage)) { + HDassert(0 && "Not yet implemented...");//VDSINC + } /* end if */ /* Check for External File List message in the object header */ if((exists = H5O_msg_exists_oh(oh, H5O_EFL_ID)) < 0) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 1a659a1..ac6896f 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -174,14 +174,14 @@ typedef struct { } H5D_compact_storage_t; typedef struct { -} H5D_virtual_storage_t; +} H5D_virtual_storage_t; /* Either fill out or remove VDSINC */ typedef union H5D_storage_t { H5D_contig_storage_t contig; /* Contiguous information for dataset */ H5D_chunk_storage_t chunk; /* Chunk information for dataset */ H5D_compact_storage_t compact; /* Compact information for dataset */ H5O_efl_t efl; /* External file list information for dataset */ - H5D_virtual_storage_t virtual; /* Virtual dataset information */ + H5D_virtual_storage_t virt; /* Virtual dataset information */ } H5D_storage_t; /* Typedef for raw data I/O operation info */ @@ -653,6 +653,13 @@ H5_DLL herr_t H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src H5F_t *f_dst, H5O_storage_compact_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id); +/* Functions that operate on virtual dataset storage */ +H5_DLL herr_t H5D__virtual_copy(H5F_t *f_src, + const H5O_storage_virtual_t *storage_src, H5F_t *f_dst, + H5O_storage_virtual_t *storage_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, + hid_t dxpl_id); +H5_DLL hbool_t H5D__virtual_is_space_alloc(const H5O_storage_t *storage); + /* Functions that operate on EFL (External File List)*/ H5_DLL hbool_t H5D__efl_is_space_alloc(const H5O_storage_t *storage); H5_DLL herr_t H5D__efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 804afd1..11c9fac 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -106,6 +106,9 @@ #define H5D_VLEN_FREE NULL #define H5D_VLEN_FREE_INFO NULL +/* Default virtual dataset list size */ +#define H5D_VIRTUAL_DEF_LIST_SIZE 8 + /****************************/ /* Library Private Typedefs */ @@ -176,8 +179,8 @@ H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_ad /* Functions that operate on virtual storage */ herr_t H5D_virtual_copy_layout(H5O_layout_t *layout); -herr_t H5D__virtual_delete(H5F_t *f, hid_t dxpl_id, - const H5O_storage_t *storage); +herr_t H5D_virtual_reset_layout(H5O_layout_t *layout); +herr_t H5D_virtual_delete(H5F_t *f, hid_t dxpl_id, H5O_storage_t *storage); /* Functions that operate on indexed storage */ H5_DLL herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 003e357..fb936d2 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -52,7 +52,7 @@ typedef enum H5D_layout_t { H5D_CONTIGUOUS = 1, /*the default */ H5D_CHUNKED = 2, /*slow and fancy */ H5D_VIRTUAL = 3, /*actual data is stored in other datasets */ - H5D_NLAYOUTS = 3 /*this one must be last! */ + H5D_NLAYOUTS = 4 /*this one must be last! */ } H5D_layout_t; /* Types of chunk index data structures */ diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index 3053690..5e9decd 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -36,6 +36,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ #include "H5HGprivate.h" /* Global Heaps */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* Object headers */ #include "H5Sprivate.h" /* Dataspaces */ @@ -119,34 +120,35 @@ H5D_virtual_copy_layout(H5O_layout_t *layout) size_t i; herr_t ret_value = SUCCEED; - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) HDassert(layout); + HDassert(layout->type == H5D_VIRTUAL); - if(mesg->storage.u.virtual.list_nused > 0) { + if(layout->storage.u.virt.list_nused > 0) { HDassert(0 && "checking code coverage...");//VDSINC - HDassert(layout->storage.u.virtual.list); + HDassert(layout->storage.u.virt.list); /* Save original entry list for use as the "source" */ - orig_list = layout->storage.u.virtual.list; + orig_list = layout->storage.u.virt.list; /* Allocate memory for the list */ - if(NULL == (layout->storage.u.virtual.list = (H5O_storage_virtual_ent_t *)H5MM_calloc(layout->storage.u.virtual.list_nused * sizeof(H5O_storage_virtual_ent_t)))) + if(NULL == (layout->storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc(layout->storage.u.virt.list_nused * sizeof(H5O_storage_virtual_ent_t)))) HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "unable to allocate memory for virtual dataset entry list") - layout->storage.u.virtual.list_nalloc = layout->storage.u.virtual.list_nused; + layout->storage.u.virt.list_nalloc = layout->storage.u.virt.list_nused; /* Copy the list entries */ - for(i = 0; i < layout->storage.u.virtual.nused; i++) { - if(NULL == (layout->storage.u.virtual.list[i].source_file - = HDstrdup(orig_list[i].source_file))) + for(i = 0; i < layout->storage.u.virt.list_nused; i++) { + if(NULL == (layout->storage.u.virt.list[i].source_file_name + = HDstrdup(orig_list[i].source_file_name))) HGOTO_ERROR(H5E_DATASET, H5E_RESOURCE, FAIL, "unable to duplicate source file name") - if(NULL == (layout->storage.u.virtual.list[i].source_dset - = HDstrdup(orig_list[i].source_dset))) + if(NULL == (layout->storage.u.virt.list[i].source_dset_name + = HDstrdup(orig_list[i].source_dset_name))) HGOTO_ERROR(H5E_DATASET, H5E_RESOURCE, FAIL, "unable to duplicate source dataset name") - if(NULL == (layout->storage.u.virtual.list[i].source_select + if(NULL == (layout->storage.u.virt.list[i].source_select = H5S_copy(orig_list[i].source_select, FALSE, TRUE))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy source selection") - if(NULL == (layout->storage.u.virtual.list[i].virtual_select + if(NULL == (layout->storage.u.virt.list[i].virtual_select = H5S_copy(orig_list[i].virtual_select, FALSE, TRUE))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") } /* end for */ @@ -154,38 +156,74 @@ H5D_virtual_copy_layout(H5O_layout_t *layout) else { HDassert(0 && "checking code coverage...");//VDSINC /* Zero out other fields related to list, just to be sure */ - layout->storage.u.virtual.list = NULL; - layout->storage.u.virtual.list_nalloc = 0; + layout->storage.u.virt.list = NULL; + layout->storage.u.virt.list_nalloc = 0; } /* end else */ done: /* Release allocated resources on failure */ if((ret_value < 0) && orig_list - && (orig_list != layout->storage.u.virtual.list)) { - /* Free the list entries */ - for(i = 0; i < layout->storage.u.virtual.nused; i++) { - layout->storage.u.virtual.list[i].source_file = H5MM_xfree(layout->storage.u.virtual.list[i].source_file); - layout->storage.u.virtual.list[i].source_dset = H5MM_xfree(layout->storage.u.virtual.list[i].source_dset); - if(layout->storage.u.virtual.list[i].source_select - && H5S_close(layout->storage.u.virtual.list[i].source_select) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") - mesg->storage.u.virtual.list[i].source_select = NULL; - if(layout->storage.u.virtual.list[i].virtual_select - && H5S_close(layout->storage.u.virtual.list[i].virtual_select) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection") - mesg->storage.u.virtual.list[i].virtual_select = NULL; - } /* end for */ - - /* Free the list */ - layout->storage.u.virtual.list = H5MM_xfree(layout->storage.u.virtual.list); - } /* end if */ + && (orig_list != layout->storage.u.virt.list)) + if(H5D_virtual_reset_layout(layout) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset virtual layout") FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_virtual_copy_layout() */ /*------------------------------------------------------------------------- - * Function: H5D__virtual_delete + * Function: H5D_virtual_reset_layout + * + * Purpose: Frees internal structures in a virtual storage layout + * message in memory. This function is safe to use on + * incomplete structures (for recovery from failure) provided + * the internal structures are initialized with all bytes set + * to 0. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * February 11, 2015 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_virtual_reset_layout(H5O_layout_t *layout) +{ + size_t i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(layout); + HDassert(layout->type == H5D_VIRTUAL); + + /* Free the list entries. Note we always attempt to free everything even in + * the case of a failure. */ + for(i = 0; i < layout->storage.u.virt.list_nused; i++) { + layout->storage.u.virt.list[i].source_file_name = (char *)H5MM_xfree(layout->storage.u.virt.list[i].source_file_name); + layout->storage.u.virt.list[i].source_dset_name = (char *)H5MM_xfree(layout->storage.u.virt.list[i].source_dset_name); + if(layout->storage.u.virt.list[i].source_select + && H5S_close(layout->storage.u.virt.list[i].source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + layout->storage.u.virt.list[i].source_select = NULL; + if(layout->storage.u.virt.list[i].virtual_select + && H5S_close(layout->storage.u.virt.list[i].virtual_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection") + layout->storage.u.virt.list[i].virtual_select = NULL; + /* Close dataset here? VDSINC */ + } /* end for */ + + /* Free the list */ + layout->storage.u.virt.list = (H5O_storage_virtual_ent_t *)(layout->storage.u.virt.list); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_virtual_reset_layout() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_virtual_delete * * Purpose: Delete the file space for a virtual dataset * @@ -197,25 +235,30 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D__virtual_delete(H5F_t *f, hid_t dxpl_id, const H5O_storage_t *storage) +H5D_virtual_delete(H5F_t *f, hid_t dxpl_id, H5O_storage_t *storage) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) /* check args */ HDassert(f); HDassert(storage); + HDassert(storage->type == H5D_VIRTUAL); /* Need to add stuff for private data here VDSINC */ /* Delete the global heap block */ - if(H5HG_remove(f, dxpl_id, &(storage->u.virtual.serial_list_hobjid)) < 0) + if(H5HG_remove(f, dxpl_id, (H5HG_t *)&(storage->u.virt.serial_list_hobjid)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "Unable to remove heap object") + /* Clear global heap ID in storage */ + storage->u.virt.serial_list_hobjid.addr = HADDR_UNDEF; + storage->u.virt.serial_list_hobjid.idx = 0; + done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__virtual_delete */ +} /* end H5D_virtual_delete */ /*------------------------------------------------------------------------- @@ -257,15 +300,18 @@ H5D__virtual_construct(H5F_t UNUSED *f, H5D_t UNUSED *dset) *------------------------------------------------------------------------- */ hbool_t -H5D__virtual_is_space_alloc(const H5O_storage_t UNUSED *storage) +H5D__virtual_is_space_alloc(const H5O_storage_t *storage) { hbool_t ret_value; /* Return value */ FUNC_ENTER_PACKAGE_NOERR - /* Need to decide what to do here. For now just return true. VDSINC */ + HDassert(0 && "checking code coverage...");//VDSINC + /* Need to decide what to do here. For now just return TRUE if the global + * heap block has been allocated. VDSINC */ + ret_value = storage->u.virt.serial_list_hobjid.addr != HADDR_UNDEF; - FUNC_LEAVE_NOAPI(TRUE) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_is_space_alloc() */ @@ -381,8 +427,8 @@ H5D__virtual_flush(H5D_t UNUSED *dset, hid_t UNUSED dxpl_id) *------------------------------------------------------------------------- */ herr_t -H5D__virtual_copy(H5F_t UNUSED *f_src, const H5O_storage_contig_t UNUSED *storage_src, - H5F_t UNUSED *f_dst, H5O_storage_contig_t UNUSED *storage_dst, H5T_t UNUSED *dt_src, +H5D__virtual_copy(H5F_t UNUSED *f_src, const H5O_storage_virtual_t UNUSED *storage_src, + H5F_t UNUSED *f_dst, H5O_storage_virtual_t UNUSED *storage_dst, H5T_t UNUSED *dt_src, H5O_copy_t UNUSED *cpy_info, hid_t UNUSED dxpl_id) { FUNC_ENTER_PACKAGE_NOERR diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 2b12a97..0e43824 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -244,55 +244,62 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, case H5D_VIRTUAL: /* Heap information */ - H5F_addr_decode(f, &p, &(mesg->storage.u.virtual.serial_list_hobjid.addr)); - UINT32DECODE(p, mesg->storage.u.virtual.serial_list_hobjid.idx); + H5F_addr_decode(f, &p, &(mesg->storage.u.virt.serial_list_hobjid.addr)); + UINT32DECODE(p, mesg->storage.u.virt.serial_list_hobjid.idx); /* Initialize other fields */ - mesg->storage.u.virtual.list_nused = 0; - mesg->storage.u.virtual.list = NULL; - mesg->storage.u.virtual.list_nalloc = 0; + mesg->storage.u.virt.list_nused = 0; + mesg->storage.u.virt.list = NULL; + mesg->storage.u.virt.list_nalloc = 0; /* Decode heap block if it exists */ - if(mesg->storage.u.virtual.serial_list_hobjid.addr != HADDR_UNDEF) { - uint8_t *heap_block_p; + if(mesg->storage.u.virt.serial_list_hobjid.addr != HADDR_UNDEF) { + const uint8_t *heap_block_p; size_t block_size = 0; + size_t tmp_size; hsize_t tmp_hsize; uint32_t stored_chksum; uint32_t computed_chksum; size_t i; /* Read heap */ - if(NULL == (heap_block = (uint8_t *)H5HG_read(f, dxpl_id, &(mesg->storage.u.virtual.serial_list_hobjid), NULL, &block_size))) + if(NULL == (heap_block = (uint8_t *)H5HG_read(f, dxpl_id, &(mesg->storage.u.virt.serial_list_hobjid), NULL, &block_size))) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "Unable to read global heap block") - heap_block_p = heap_block; + heap_block_p = (const uint8_t *)heap_block; /* Number of entries */ H5F_DECODE_LENGTH(f, heap_block_p, tmp_hsize) /* Allocate entry list */ - if(NULL == (mesg->storage.u.virtual.list = (H5O_storage_virtual_ent_t *)H5MM_malloc((size_t)tmp_hsize * sizeof(H5O_storage_virtual_ent_t)))) + if(NULL == (mesg->storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc((size_t)tmp_hsize * sizeof(H5O_storage_virtual_ent_t)))) HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate heap block") - mesg->storage.u.virtual.list_nalloc = (size_t)tmp_hsize; - mesg->storage.u.virtual.list_nused = (size_t)tmp_hsize; + mesg->storage.u.virt.list_nalloc = (size_t)tmp_hsize; + mesg->storage.u.virt.list_nused = (size_t)tmp_hsize; /* Decode each entry */ - for(i = 0; i < mesg->storage.u.virtual.list_nused; i++) { + for(i = 0; i < mesg->storage.u.virt.list_nused; i++) { /* Source file name */ - if(NULL == (mesg->storage.u.virtual.list[i].source_file = HDstrdup(heap_block_p))) - HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to duplicate source file name") - heap_block_p += HDstrlen(heap_block_p) + 1; + tmp_size = HDstrlen((const char *)heap_block_p) + 1; + if(NULL == (mesg->storage.u.virt.list[i].source_file_name = (char *)H5MM_malloc(tmp_size))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate memory for source file name") + (void)HDmemcpy(mesg->storage.u.virt.list[i].source_file_name, heap_block_p, tmp_size); + heap_block_p += tmp_size; /* Source dataset name */ - if(NULL == (mesg->storage.u.virtual.list[i].source_dset = HDstrdup(heap_block_p))) - HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to duplicate source dataset name") - heap_block_p += HDstrlen(heap_block_p) + 1; + tmp_size = HDstrlen((const char *)heap_block_p) + 1; + if(NULL == (mesg->storage.u.virt.list[i].source_dset_name = (char *)H5MM_malloc(tmp_size))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate memory for source dataset name") + (void)HDmemcpy(mesg->storage.u.virt.list[i].source_dset_name, heap_block_p, tmp_size); + heap_block_p += tmp_size; /* Source selection */ - H5S_SELECT_DESERIALIZE(&(mesg->storage.u.virtual.list[i].source_select), &heap_block_p) + if(H5S_SELECT_DESERIALIZE(&(mesg->storage.u.virt.list[i].source_select), &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode source space selection") /* Virtual selection */ - H5S_SELECT_SERIALIZE(&(mesg->storage.u.virtual.list[i].virtual_select), &heap_block_p) + if(H5S_SELECT_DESERIALIZE(&(mesg->storage.u.virt.list[i].virtual_select), &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode virtual space selection") } /* end for */ /* Read stored checksum */ @@ -304,6 +311,10 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, /* Verify checksum */ if(stored_chksum != computed_chksum) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect metadata checksum for global heap block") + + /* Verify that the heap block size is correct */ + if((size_t)(heap_block_p - heap_block) != block_size) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect heap block size") } /* end if */ break; @@ -322,10 +333,12 @@ done: if(ret_value == NULL) if(mesg) { if(mesg->type == H5D_VIRTUAL) - mesg-> + if(H5D_virtual_reset_layout(mesg) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "unable to reset virtual layout") mesg = H5FL_FREE(H5O_layout_t, mesg); + } /* end if */ - heap_block = H5MM_xfree(heap_block); + heap_block = (uint8_t *)H5MM_xfree(heap_block); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_decode() */ @@ -366,6 +379,7 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; uint8_t *heap_block = NULL; + size_t *str_size = NULL; unsigned u; herr_t ret_value = SUCCEED; /* Return value */ @@ -421,8 +435,8 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi /* Note that we assume here that the contents of the heap block * cannot change! If this ever stops being the case we must change * this code to allow overwrites of the heap block. -NAF */ - if((mesg->storage.u.virtual.serial_list_hobjid.addr == HADDR_UNDEF) - && (mesg->storage.u.virtual.list_nused > 0)) { + if((mesg->storage.u.virt.serial_list_hobjid.addr == HADDR_UNDEF) + && (mesg->storage.u.virt.list_nused > 0)) { uint8_t *heap_block_p; size_t block_size; hssize_t select_serial_size; @@ -430,6 +444,10 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi uint32_t chksum; size_t i; + /* Allocate array for caching results of strlen */ + if(NULL == (str_size = (size_t *)H5MM_malloc(2 * mesg->storage.u.virt.list_nused *sizeof(size_t)))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate string length array") + /* * Calculate heap block size */ @@ -437,25 +455,27 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi block_size = H5F_SIZEOF_SIZE(f); /* Calculate size of each entry */ - for(i = 0; i < mesg->storage.u.virtual.list_nused; i++) { - HDassert(mesg->storage.u.virtual.list[i].source_file); - HDassert(mesg->storage.u.virtual.list[i].source_dset); - HDassert(mesg->storage.u.virtual.list[i].source_select); - HDassert(mesg->storage.u.virtual.list[i].virtual_select); + for(i = 0; i < mesg->storage.u.virt.list_nused; i++) { + HDassert(mesg->storage.u.virt.list[i].source_file_name); + HDassert(mesg->storage.u.virt.list[i].source_dset_name); + HDassert(mesg->storage.u.virt.list[i].source_select); + HDassert(mesg->storage.u.virt.list[i].virtual_select); /* Source file name */ - block_size += HDstrlen(mesg->storage.u.virtual.list[i].source_file) + (size_t)1; + str_size[2 * i] = HDstrlen(mesg->storage.u.virt.list[i].source_file_name) + (size_t)1; + block_size += str_size[2 * i]; /* Source dset name */ - block_size += HDstrlen(mesg->storage.u.virtual.list[i].source_dset) + (size_t)1; + str_size[(2 * i) + 1] = HDstrlen(mesg->storage.u.virt.list[i].source_dset_name) + (size_t)1; + block_size += str_size[(2 * i) + 1]; /* Source selection */ - if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virtual.list[i].source_select)) < 0) + if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virt.list[i].source_select)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size") block_size += (size_t)select_serial_size; /* Virtual dataset selection */ - if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virtual.list[i].virtual_select)) < 0) + if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virt.list[i].virtual_select)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size") block_size += (size_t)select_serial_size; } /* end for */ @@ -464,7 +484,7 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi block_size += 4; /* Allocate heap block */ - if(NULL == (heap_block = (uint8_t *)H5MM_malloc((size_t)mesg->storage.u.virtual.serial_list_size))) + if(NULL == (heap_block = (uint8_t *)H5MM_malloc(block_size))) HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate heap block") /* @@ -473,26 +493,26 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi heap_block_p = heap_block; /* Number of entries */ - tmp_hsize = (hsize_t)mesg->storage.u.virtual.list_nused; + tmp_hsize = (hsize_t)mesg->storage.u.virt.list_nused; H5F_ENCODE_LENGTH(f, heap_block_p, tmp_hsize) /* Encode each entry */ - for(i = 0; i < mesg->storage.u.virtual.list_nused; i++) { + for(i = 0; i < mesg->storage.u.virt.list_nused; i++) { /* Source file name */ - (void)HDstrcpy(heap_block_p, mesg->storage.u.virtual.list[i].source_file); - heap_block_p += HDstrlen(heap_block_p) + 1; + (void)HDstrcpy((char *)heap_block_p, mesg->storage.u.virt.list[i].source_file_name); + heap_block_p += str_size[2 * i]; /* Source dataset name */ - (void)HDstrcpy(heap_block_p, mesg->storage.u.virtual.list[i].source_dset); - heap_block_p += HDstrlen(heap_block_p) + 1; + (void)HDstrcpy((char *)heap_block_p, mesg->storage.u.virt.list[i].source_dset_name); + heap_block_p += str_size[(2 * i) + 1]; /* Source selection */ - if(H5S_SELECT_SERIALIZE(mesg->storage.u.virtual.list[i].source_select, &heap_block_p) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to serialize selection") + if(H5S_SELECT_SERIALIZE(mesg->storage.u.virt.list[i].source_select, &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to serialize source selection") /* Virtual selection */ - if(H5S_SELECT_SERIALIZE(mesg->storage.u.virtual.list[i].virtual_select, &heap_block_p) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to serialize selection") + if(H5S_SELECT_SERIALIZE(mesg->storage.u.virt.list[i].virtual_select, &heap_block_p) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to serialize virtual selection") } /* end for */ /* Checksum */ @@ -501,13 +521,15 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi /* Insert block into global heap */ /* Casting away const OK --NAF */ - if(H5HG_insert(f, H5AC_ind_dxpl_id, block_size, heap_block, &((H5O_layout_t *)mesg)->storage.u.virtual.serial_list_hobjid) < 0) + if(H5HG_insert(f, H5AC_ind_dxpl_id, block_size, heap_block, &((H5O_layout_t *)mesg)->storage.u.virt.serial_list_hobjid) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to insert virtual dataset heap block") } /* end if */ + HDassert((mesg->storage.u.virt.list_nused > 0) && "checking code coverage...");//VDSINC + /* Heap information */ - H5F_addr_encode(f, &p, mesg->storage.u.virtual.serial_list_hobjid.addr); - UINT32ENCODE(p, mesg->storage.u.virtual.serial_list_hobjid.idx); + H5F_addr_encode(f, &p, mesg->storage.u.virt.serial_list_hobjid.addr); + UINT32ENCODE(p, mesg->storage.u.virt.serial_list_hobjid.idx); break; @@ -518,7 +540,8 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi } /* end switch */ done: - heap_block = H5MM_xfree(heap_block); + heap_block = (uint8_t *)H5MM_xfree(heap_block); + str_size = (size_t *)H5MM_xfree(str_size); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_encode() */ @@ -573,9 +596,11 @@ H5O_layout_copy(const void *_mesg, void *_dest) H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE); /* Deep copy the entry list for virtual datasets */ - if(mesg->type == H5D_VIRTUAL) + if(mesg->type == H5D_VIRTUAL) { + HDassert((mesg->storage.u.virt.list_nused > 0) && "checking code coverage...");//VDSINC if(H5D_virtual_copy_layout(dest) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy virtual layout") + } //VDSINC /* Set return value */ ret_value = dest; @@ -650,28 +675,10 @@ H5O_layout_reset(void *_mesg) /* Free the compact storage buffer */ if(H5D_COMPACT == mesg->type) mesg->storage.u.compact.buf = H5MM_xfree(mesg->storage.u.compact.buf); - - /* Free the virtual entry list */ - if(H5D_VIRTUAL == mesg->type) { - if(mesg->storage.u.virtual.list_nused > 0) { - size_t i; - HDassert(mesg->storage.u.virtual.list); - - /* Free the list entries */ - for(i = 0; i < mesg->storage.u.virtual.nused; i++) { - mesg->storage.u.virtual.list[i].source_file = H5MM_xfree(mesg->storage.u.virtual.list[i].source_file); - mesg->storage.u.virtual.list[i].source_dset = H5MM_xfree(mesg->storage.u.virtual.list[i].source_dset); - if(H5S_close(mesg->storage.u.virtual.list[i].source_select) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CLOSEERROR, FAIL, "unable to release source selection") - mesg->storage.u.virtual.list[i].source_select = NULL; - if(H5S_close(mesg->storage.u.virtual.list[i].virtual_select) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CLOSEERROR, FAIL, "unable to release virtual selection") - mesg->storage.u.virtual.list[i].virtual_select = NULL; - } /* end for */ - - /* Free the list */ - mesg->storage.u.virtual.list = H5MM_xfree(mesg->storage.u.virtual.list); - } /* end if */ + else if(H5D_VIRTUAL == mesg->type) + /* Free the virtual entry list */ + if(H5D_virtual_reset_layout(mesg) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to reset virtual layout") /* Reset the message */ mesg->type = H5D_CONTIGUOUS; @@ -761,7 +768,7 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg) case H5D_VIRTUAL: /* Virtual dataset */ HDassert(0 && "checking code coverage...");//VDSINC /* Free the file space virtual dataset */ - if(H5D__virtual_delete(f, dxpl_id, &mesg->storage) < 0) + if(H5D_virtual_delete(f, dxpl_id, &mesg->storage) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") break; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index b3d6237..ac8d02f 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -37,6 +37,7 @@ /* Private headers needed by this file */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5Fprivate.h" /* File access */ +#include "H5HGprivate.h" /* Global Heaps */ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatype functions */ #include "H5Zprivate.h" /* I/O pipeline filters */ @@ -413,21 +414,21 @@ typedef struct H5O_storage_compact_t { typedef struct H5O_storage_virtual_ent_t { /* Stored */ - char *source_file; - char *source_dset; - H5S_t *source_select; - H5S_t *virtual_select; + char *source_file_name; /* Source file name used for virtual dataset mapping */ + char *source_dset_name; /* Source dataset name used for virtual dataset mapping */ + struct H5S_t *source_select; /* Selection in the source dataset for mapping */ + struct H5S_t *virtual_select; /* Selection in the virtual dataset that is mapped to source_select */ /* Not stored */ - H5D_t *source_dset; + struct H5D_t *source_dset; /* Source dataset */ } H5O_storage_virtual_ent_t; typedef struct H5O_storage_virtual_t { /* Stored in message */ - H5HG_t serial_list_hobjid; + H5HG_t serial_list_hobjid; /* Global heap ID for the list of virtual mapping entries stored on disk */ /* Stored in heap */ - size_t list_nused; /* Number of slots used */ + size_t list_nused; /* Number of array elements used in list */ H5O_storage_virtual_ent_t *list; /* Array of virtual dataset mapping entries */ /* Not stored */ @@ -440,7 +441,7 @@ typedef struct H5O_storage_t { H5O_storage_contig_t contig; /* Information for contiguous storage */ H5O_storage_chunk_t chunk; /* Information for chunked storage */ H5O_storage_compact_t compact; /* Information for compact storage */ - H5O_storage_virtual_t virtual; /* Information for virtual storage */ + H5O_storage_virtual_t virt; /* Information for virtual storage */ } u; } H5O_storage_t; diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index e9bd9bf..6abe17d 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -61,8 +61,8 @@ #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_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }} -#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_VIRTUAL} +#define H5D_DEF_STORAGE_VIRTUAL {H5D_CHUNKED, { .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} @@ -136,7 +136,10 @@ 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 herr_t H5P__dcrt_layout_copy(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); @@ -324,6 +327,10 @@ H5P__dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) 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; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -568,7 +575,7 @@ done: * Purpose: Frees memory used to store the layout property * * Return: Success: Non-negative - * Failure: Never fails + * Failure: Negative * * Programmer: Neil Fortner * Tuesday, Feb 10, 2015 @@ -578,13 +585,21 @@ done: static herr_t H5P__dcrt_layout_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSED size, void *value) { - FUNC_ENTER_STATIC_NOERR + H5O_layout_t *layout = (H5O_layout_t *)value; /* Create local aliases for values */ + herr_t ret_value = SUCCEED; /* Return value */ - HDassert(value); + FUNC_ENTER_STATIC - (void)H5O_msg_free(H5O_LAYOUT_ID, value) + /* Sanity check */ + HDassert(layout); - FUNC_LEAVE_NOAPI(SUCCEED) + /* Reset the old layout befopre overwriting it if necessary */ + if(layout->type == H5D_VIRTUAL) + if(H5D_virtual_reset_layout(layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to reset virtual layout") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__dcrt_layout_del() */ @@ -604,12 +619,12 @@ H5P__dcrt_layout_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSE static herr_t H5P__dcrt_layout_copy(const char UNUSED *name, size_t UNUSED size, void *value) { - H5O_layout_t *layout; + H5O_layout_t *layout = (H5O_layout_t *)value; /* Create local aliases for values */ herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC - HDassert(value); + HDassert(layout); layout = (H5O_layout_t *)value; @@ -703,7 +718,7 @@ done: * Purpose: Frees memory used to store the layout property * * Return: Success: Non-negative - * Failure: Never fails + * Failure: Negative * * Programmer: Neil Fortner * Tuesday, Feb 10, 2015 @@ -713,13 +728,21 @@ done: static herr_t H5P__dcrt_layout_close(const char UNUSED *name, size_t UNUSED size, void *value) { - FUNC_ENTER_STATIC_NOERR + H5O_layout_t *layout = (H5O_layout_t *)value; /* Create local aliases for values */ + herr_t ret_value = SUCCEED; /* Return value */ - HDassert(value); + FUNC_ENTER_STATIC - (void)H5O_msg_free(H5O_LAYOUT_ID, value) + /* Sanity check */ + HDassert(layout); - FUNC_LEAVE_NOAPI(SUCCEED) + /* Reset the old layout befopre overwriting it if necessary */ + if(layout->type == H5D_VIRTUAL) + if(H5D_virtual_reset_layout(layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to reset virtual layout") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__dcrt_layout_close() */ @@ -1217,6 +1240,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 */ @@ -1263,6 +1287,17 @@ 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 necessary */ + if(old_layout.type == H5D_VIRTUAL) { + HDassert((layout->storage.u.virt.list_nused > 0) && "checking code coverage...");//VDSINC + if(H5D_virtual_reset_layout(&old_layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "unable to reset virtual layout") + } //VDSINC + /* Set layout value */ if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, layout) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout") @@ -1278,7 +1313,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 @@ -1300,7 +1336,7 @@ H5P__init_def_layout(void) 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.u.chunk = def_store_chunk; - H5D_def_layout_virtual_g.storage.u.virtual = def_store_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; @@ -1579,6 +1615,354 @@ 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 */ + hbool_t new_layout = FALSE; /* Whether we are adding a new virtual layout message to plist */ + hbool_t adding_entry = FALSE; /* Whether we are in the middle of adding an entry */ + 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") + +#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) { + new_layout = TRUE; + HDmemcpy(&layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g)); + } /* end if */ + + /* 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") + } /* 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") + (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 */ + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name = HDstrdup(src_file_name))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") + adding_entry = TRUE; + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name = HDstrdup(src_dset_name))) + HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select = H5S_copy(src_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection") + if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_select = H5S_copy(vspace, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") + layout.storage.u.virt.list_nused++; + adding_entry = FALSE; + + /* Set chunk information in property list if we are adding a new layout */ + if(new_layout) + if(H5P__set_layout(plist, &layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") + +done: + if(adding_entry) { + HDassert(ret_value < 0); + + /* Free incomplete entry */ + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name = (char *)H5MM_xfree(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name); + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name = (char *)H5MM_xfree(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name); + if(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select + && H5S_close(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select = NULL; + HDassert(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_select == NULL); + } /* 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); + HDassert(0 && "checking code coverage...");//VDSINC + + 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; /* Dataspace pointer */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("i", "iz", dcpl_id, index); + HDassert(0 && "checking code coverage...");//VDSINC + + /* 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_nalloc) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") + if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].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: + 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; /* Dataspace pointer */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("i", "iz", dcpl_id, index); + HDassert(0 && "checking code coverage...");//VDSINC + + /* 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_nalloc) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") + 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: + 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); + HDassert(0 && "checking code coverage...");//VDSINC + + /* 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 */ + 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); + HDassert(0 && "checking code coverage...");//VDSINC + + /* 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 */ + 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 @@ -2419,6 +2803,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: diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index f56692c..c1c6f17 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -354,6 +354,15 @@ 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[/*ndims*/]); H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/); +H5_DLL 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); +H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count/*out*/); +H5_DLL hid_t H5Pget_virtual_vspace(hid_t dcpl_id, size_t index); +H5_DLL hid_t H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index); +H5_DLL ssize_t H5Pget_virtual_filename(hid_t dcpl_id, size_t index, + char *name/*out*/, size_t size); +H5_DLL ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, + char *name/*out*/, size_t size); H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size); H5_DLL int H5Pget_external_count(hid_t plist_id); diff --git a/src/H5Sall.c b/src/H5Sall.c index a9e72fb..6ac00d2 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -39,8 +39,8 @@ static herr_t H5S_all_get_seq_list(const H5S_t *space, unsigned flags, static herr_t H5S_all_release(H5S_t *space); static htri_t H5S_all_is_valid(const H5S_t *space); 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_serialize(const H5S_t *space, uint8_t **p); +static herr_t H5S_all_deserialize(H5S_t *space, const uint8_t **p); 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); @@ -496,9 +496,11 @@ H5S_all_serial_size (const H5S_t UNUSED *space) PURPOSE Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_all_serialize(space, buf) - H5S_t *space; IN: Dataspace pointer of selection to serialize - uint8 *buf; OUT: Buffer to put serialized selection into + herr_t H5S_all_serialize(space, p) + const H5S_t *space; IN: Dataspace with selection to serialize + uint8_t **p; OUT: Pointer to buffer to put serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -534,9 +536,12 @@ H5S_all_serialize (const H5S_t *space, uint8_t **p) PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_all_deserialize(space, buf) - H5S_t *space; IN/OUT: Dataspace pointer to place selection into - uint8 *buf; IN: Buffer to retrieve serialized selection from + herr_t H5S_all_deserialize(space, p) + H5S_t *space; IN/OUT: Dataspace pointer to place + selection into + uint8 **p; OUT: Pointer to buffer holding serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -548,9 +553,8 @@ H5S_all_serialize (const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_all_deserialize(H5S_t **space, const uint8_t **p) +H5S_all_deserialize(H5S_t *space, const uint8_t **p) { - H5S_t *tmp_space; herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI(FAIL) @@ -559,31 +563,11 @@ H5S_all_deserialize(H5S_t **space, const uint8_t **p) HDassert(p); HDassert(*p); - /* Allocate space if not provided */ - if(!*space) { - if(NULL == (tmp_space = H5S_create(H5S_SIMPLE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace") - } /* end if */ - else - tmp_space = *space; - - - /* Skip over the remainder of the header */ - *p += 12; - /* Change to "all" selection */ - if(H5S_select_all(tmp_space, TRUE) < 0) + if(H5S_select_all(space, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") - if(!*space) - *space = tmp_space; - done: - /* Free temporary space if not passed to caller (only happens on error) */ - if(!*space && tmp_space) - if(H5S_close(tmp_space) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace") - FUNC_LEAVE_NOAPI(ret_value) } /* H5S_all_deserialize() */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 02d9359..91f31d2 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -54,8 +54,8 @@ static herr_t H5S_hyper_get_seq_list(const H5S_t *space, unsigned flags, static herr_t H5S_hyper_release(H5S_t *space); static htri_t H5S_hyper_is_valid(const H5S_t *space); 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_serialize(const H5S_t *space, uint8_t **p); +static herr_t H5S_hyper_deserialize(H5S_t *space, const uint8_t **p); 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); @@ -2055,9 +2055,11 @@ done: PURPOSE Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_hyper_serialize(space, buf) - H5S_t *space; IN: Dataspace pointer of selection to serialize - uint8 *buf; OUT: Buffer to put serialized selection into + herr_t H5S_hyper_serialize(space, p) + const H5S_t *space; IN: Dataspace with selection to serialize + uint8_t **p; OUT: Pointer to buffer to put serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -2096,7 +2098,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t **p) *p += 4; /* skip over space for length */ /* Encode number of dimensions */ - UINT32ENCODE(buf, (uint32_t)space->extent.rank); + UINT32ENCODE(*p, (uint32_t)space->extent.rank); len += 4; /* Check for a "regular" hyperslab selection */ @@ -2197,7 +2199,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t **p) /* Add 8 bytes times the rank for each hyperslab selected */ H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, size_t); - len += (size_t)(8 * space->extent.rank * block_count); + len += (uint32_t)(8 * space->extent.rank * block_count); /* Encode each hyperslab in selection */ H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, p); @@ -2216,9 +2218,12 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t **p) PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_hyper_deserialize(space, buf) - H5S_t *space; IN/OUT: Dataspace pointer to place selection into - uint8 *buf; IN: Buffer to retrieve serialized selection from + herr_t H5S_hyper_deserialize(space, p) + H5S_t *space; IN/OUT: Dataspace pointer to place + selection into + uint8 **p; OUT: Pointer to buffer holding serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -2230,10 +2235,9 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_deserialize (H5S_t **space, const uint8_t **p) +H5S_hyper_deserialize (H5S_t *space, const uint8_t **p) { - H5S_t *tmp_space; - uint32_t rank; /* rank of points */ + unsigned rank; /* rank of points */ size_t num_elem=0; /* number of elements in selection */ hsize_t start[H5O_LAYOUT_NDIMS]; /* hyperslab start information */ hsize_t end[H5O_LAYOUT_NDIMS]; /* hyperslab end information */ @@ -2256,26 +2260,10 @@ H5S_hyper_deserialize (H5S_t **space, const uint8_t **p) HDassert(*p); /* Deserialize slabs to select */ - *p+=12; /* Skip over remainder of selection header */ - UINT32DECODE(*p,rank); /* decode the rank of the point selection */ + /* The header and rank have already beed decoded */ + rank = space->extent.rank; /* Retrieve rank from space */ UINT32DECODE(*p,num_elem); /* decode the number of points */ - /* Allocate space if not provided */ - if(!*space) { - if(NULL == (tmp_space = H5S_create(H5S_SIMPLE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace") - - /* Set rank of dataspace */ - tmp_space->extent.rank = rank; - } /* end if */ - else { - tmp_space = *space; - - /* Verify rank of dataspace */ - if(rank!=tmp_space->extent.rank) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace") - } /* end else */ - /* Set the count & stride for all blocks */ for(tcount=count,tstride=stride,j=0; j<rank; j++,tstride++,tcount++) { *tcount=1; @@ -2293,23 +2281,15 @@ H5S_hyper_deserialize (H5S_t **space, const uint8_t **p) UINT32DECODE(*p, *tend); /* Change the ending points into blocks */ - for(tblock=block,tstart=start,tend=end,j=0; j<(unsigned)rank; j++,tstart++,tend++,tblock++) + for(tblock=block,tstart=start,tend=end,j=0; j<rank; j++,tstart++,tend++,tblock++) *tblock=(*tend-*tstart)+1; /* Select or add the hyperslab to the current selection */ - if((ret_value=H5S_select_hyperslab(tmp_space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,stride,count,block))<0) + if((ret_value=H5S_select_hyperslab(space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,stride,count,block))<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") } /* end for */ - if(!*space) - *space = tmp_space; - done: - /* Free temporary space if not passed to caller (only happens on error) */ - if(!*space && tmp_space) - if(H5S_close(tmp_space) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace") - FUNC_LEAVE_NOAPI(ret_value) } /* H5S_hyper_deserialize() */ diff --git a/src/H5Snone.c b/src/H5Snone.c index a6c870a..94d41a9 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -40,8 +40,8 @@ static herr_t H5S_none_get_seq_list(const H5S_t *space, unsigned flags, static herr_t H5S_none_release(H5S_t *space); static htri_t H5S_none_is_valid(const H5S_t *space); 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_serialize(const H5S_t *space, uint8_t **p); +static herr_t H5S_none_deserialize(H5S_t *space, const uint8_t **p); 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); @@ -464,9 +464,11 @@ H5S_none_serial_size(const H5S_t UNUSED *space) PURPOSE Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_none_serialize(space, buf) - H5S_t *space; IN: Dataspace pointer of selection to serialize - uint8 *buf; OUT: Buffer to put serialized selection into + herr_t H5S_none_serialize(space, p) + const H5S_t *space; IN: Dataspace with selection to serialize + uint8_t **p; OUT: Pointer to buffer to put serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -500,9 +502,12 @@ H5S_none_serialize(const H5S_t *space, uint8_t **p) PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_none_deserialize(space, buf) - H5S_t *space; IN/OUT: Dataspace pointer to place selection into - uint8 *buf; IN: Buffer to retrieve serialized selection from + herr_t H5S_none_deserialize(space, p) + H5S_t *space; IN/OUT: Dataspace pointer to place + selection into + uint8 **p; OUT: Pointer to buffer holding serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -514,9 +519,8 @@ H5S_none_serialize(const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_deserialize(H5S_t **space, const uint8_t **p) +H5S_none_deserialize(H5S_t *space, const uint8_t **p) { - H5S_t *tmp_space; herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI_NOINIT @@ -525,30 +529,11 @@ H5S_none_deserialize(H5S_t **space, const uint8_t **p) HDassert(p); HDassert(*p); - /* Allocate space if not provided */ - if(!*space) { - if(NULL == (tmp_space = H5S_create(H5S_SIMPLE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace") - } /* end if */ - else - tmp_space = *space; - - /* Skip over the remainder of the header */ - *p += 12; - /* Change to "none" selection */ - if(H5S_select_none(tmp_space) < 0) + if(H5S_select_none(space) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") - if(!*space) - *space = tmp_space; - done: - /* Free temporary space if not passed to caller (only happens on error) */ - if(!*space && tmp_space) - if(H5S_close(tmp_space) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace") - FUNC_LEAVE_NOAPI(ret_value) } /* H5S_none_deserialize() */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 91f3ed1..5f84717 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -130,9 +130,9 @@ typedef htri_t (*H5S_sel_is_valid_func_t)(const H5S_t *space); /* Method to determine number of bytes required to store current selection */ typedef hssize_t (*H5S_sel_serial_size_func_t)(const H5S_t *space); /* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */ -typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t *buf); +typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t **p); /* 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 **p); +typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t *space, const uint8_t **p); /* 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 */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index e55834d..e6a4a39 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -41,8 +41,8 @@ static herr_t H5S_point_get_seq_list(const H5S_t *space, unsigned flags, static herr_t H5S_point_release(H5S_t *space); static htri_t H5S_point_is_valid(const H5S_t *space); 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_serialize(const H5S_t *space, uint8_t **p); +static herr_t H5S_point_deserialize(H5S_t *space, const uint8_t **p); 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); @@ -804,9 +804,11 @@ H5S_point_serial_size (const H5S_t *space) PURPOSE Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_point_serialize(space, buf) - H5S_t *space; IN: Dataspace pointer of selection to serialize - uint8 *buf; OUT: Buffer to put serialized selection into + herr_t H5S_point_serialize(space, p) + const H5S_t *space; IN: Dataspace with selection to serialize + uint8_t **p; OUT: Pointer to buffer to put serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -848,7 +850,7 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) curr=space->select.sel_info.pnt_lst->head; while(curr!=NULL) { /* Add 4 bytes times the rank for each element selected */ - *p+=4*space->extent.rank; + len+=4*space->extent.rank; /* Encode each point */ for(u=0; u<space->extent.rank; u++) @@ -870,9 +872,12 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_point_deserialize(space, buf) - H5S_t *space; IN/OUT: Dataspace pointer to place selection into - uint8 *buf; IN: Buffer to retrieve serialized selection from + herr_t H5S_point_deserialize(space, p) + H5S_t *space; IN/OUT: Dataspace pointer to place + selection into + uint8 **p; OUT: Pointer to buffer holding serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -884,11 +889,10 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_deserialize (H5S_t **space, const uint8_t **p) +H5S_point_deserialize (H5S_t *space, const uint8_t **p) { - H5S_t *tmp_space; H5S_seloper_t op=H5S_SELECT_SET; /* Selection operation */ - uint32_t rank; /* Rank of points */ + unsigned rank; /* Rank of points */ size_t num_elem=0; /* Number of elements in selection */ hsize_t *coord=NULL, *tcoord; /* Pointer to array of elements */ unsigned i, j; /* local counting variables */ @@ -902,25 +906,9 @@ H5S_point_deserialize (H5S_t **space, const uint8_t **p) HDassert(*p); /* Deserialize points to select */ - *p += 12; /* Skip over remaining selection header */ - UINT32DECODE(*p, rank); /* decode the rank of the point selection */ - UINT32DECODE(*p, num_elem); /* decode the number of points */ - - /* Allocate space if not provided */ - if(!*space) { - if(NULL == (tmp_space = H5S_create(H5S_SIMPLE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace") - - /* Set rank of dataspace */ - tmp_space->extent.rank = rank; - } /* end if */ - else { - tmp_space = *space; - - /* Verify rank of dataspace */ - if(rank!=tmp_space->extent.rank) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace") - } /* end else */ + /* The header and rank have already beed decoded */ + rank = space->extent.rank; /* Retrieve rank from space */ + UINT32DECODE(*p, num_elem); /* decode the number of points */ /* Allocate space for the coordinates */ if(NULL == (coord = (hsize_t *)H5MM_malloc(num_elem * rank * sizeof(hsize_t)))) @@ -932,18 +920,10 @@ H5S_point_deserialize (H5S_t **space, const uint8_t **p) UINT32DECODE(*p, *tcoord); /* Select points */ - if(H5S_select_elements(tmp_space, op, num_elem, (const hsize_t *)coord) < 0) + if(H5S_select_elements(space, op, num_elem, (const hsize_t *)coord) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") - if(!*space) - *space = tmp_space; - done: - /* Free temporary space if not passed to caller (only happens on error) */ - if(!*space && tmp_space) - if(H5S_close(tmp_space) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace") - /* Free the coordinate array if necessary */ if(coord != NULL) H5MM_xfree(coord); diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 44cd6c3..7b7b8c6 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -206,7 +206,7 @@ H5_DLL int H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t H5_DLL htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2); /* Operations on selections */ -H5_DLL herr_t H5S_select_deserialize(H5S_t *space, const uint8_t *buf); +H5_DLL herr_t H5S_select_deserialize(H5S_t **space, const uint8_t **p); H5_DLL H5S_sel_type H5S_get_select_type(const H5S_t *space); H5_DLL herr_t H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t op, void *operator_data); @@ -227,7 +227,7 @@ H5_DLL herr_t H5S_select_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); H5_DLL hssize_t H5S_select_serial_size(const H5S_t *space); -H5_DLL herr_t H5S_select_serialize(const H5S_t *space, uint8_t *buf); +H5_DLL herr_t H5S_select_serialize(const H5S_t *space, uint8_t **p); H5_DLL htri_t H5S_select_is_contiguous(const H5S_t *space); H5_DLL htri_t H5S_select_is_single(const H5S_t *space); H5_DLL htri_t H5S_select_is_regular(const H5S_t *space); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 7d22f08..34e9473 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -239,9 +239,11 @@ H5S_select_serial_size(const H5S_t *space) PURPOSE Serialize the selection for a dataspace into a buffer USAGE - herr_t H5S_select_serialize(space, buf) + herr_t H5S_select_serialize(space, p) const H5S_t *space; IN: Dataspace with selection to serialize - uint8_t **p; OUT: Buffer to put serialized selection + uint8_t **p; OUT: Pointer to buffer to put serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -263,7 +265,7 @@ H5S_select_serialize(const H5S_t *space, uint8_t **p) FUNC_ENTER_NOAPI_NOINIT_NOERR HDassert(space); - HDassert(buf); + HDassert(p); /* Call the selection type's serialize function */ ret_value=(*space->select.type->serialize)(space,p); @@ -428,9 +430,13 @@ H5S_select_valid(const H5S_t *space) Deserialize the current selection from a user-provided buffer into a real selection in the dataspace. USAGE - herr_t H5S_select_deserialize(space, buf) - H5S_t *space; IN/OUT: Dataspace pointer to place selection into - uint8 *buf; IN: Buffer to retrieve serialized selection from + herr_t H5S_select_deserialize(space, p) + H5S_t **space; IN/OUT: Dataspace pointer to place + selection into. Will be allocated if not + provided. + uint8 **p; OUT: Pointer to buffer holding serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -446,38 +452,78 @@ H5S_select_valid(const H5S_t *space) herr_t H5S_select_deserialize (H5S_t **space, const uint8_t **p) { - uint32_t sel_type; /* Pointer to the selection type */ + H5S_t *tmp_space; /* Pointer to actual dataspace to use, either + *space or a newly allocated one */ + uint32_t sel_type; /* Pointer to the selection type */ herr_t ret_value=FAIL; /* return value */ FUNC_ENTER_NOAPI(FAIL) HDassert(space); + /* Allocate space if not provided */ + if(!*space) { + if(NULL == (tmp_space = H5S_create(H5S_SIMPLE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace") + } /* end if */ + else + tmp_space = *space; + + /* Decode selection type */ UINT32DECODE(*p, sel_type); + + /* Skip over the remainder of the header */ + *p += 12; + + /* Decode and check or patch rank for point and hyperslab selections */ + if((sel_type == H5S_SEL_POINTS) || (sel_type == H5S_SEL_HYPERSLABS)) { + uint32_t rank; /* Rank of dataspace */ + + /* Decode the rank of the point selection */ + UINT32DECODE(*p,rank); + + if(!*space) + /* Patch the rank of the allocated dataspace */ + tmp_space->extent.rank = rank; + else + /* Verify the rank of the provided dataspace */ + if(rank != tmp_space->extent.rank) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of serialized selection does not match dataspace") + } /* end if */ + + /* Make routine for selection type */ switch(sel_type) { case H5S_SEL_POINTS: /* Sequence of points selected */ - ret_value=(*H5S_sel_point->deserialize)(space,p); + ret_value = (*H5S_sel_point->deserialize)(tmp_space, p); break; case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */ - ret_value=(*H5S_sel_hyper->deserialize)(space,p); + ret_value = (*H5S_sel_hyper->deserialize)(tmp_space, p); break; case H5S_SEL_ALL: /* Entire extent selected */ - ret_value=(*H5S_sel_all->deserialize)(space,p); + ret_value = (*H5S_sel_all->deserialize)(tmp_space, p); break; case H5S_SEL_NONE: /* Nothing selected */ - ret_value=(*H5S_sel_none->deserialize)(space,p); + ret_value = (*H5S_sel_none->deserialize)(tmp_space, p); break; default: break; } - if(ret_value<0) + if(ret_value < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection") + /* Return space to the caller if allocated */ + if(!*space) + *space = tmp_space; done: + /* Free temporary space if not passed to caller (only happens on error) */ + if(!*space && tmp_space) + if(H5S_close(tmp_space) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace") + FUNC_LEAVE_NOAPI(ret_value) } /* H5S_select_deserialize() */ diff --git a/src/H5trace.c b/src/H5trace.c index 3a84489..08641da 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -524,6 +524,10 @@ H5_trace(const double *returning, const char *func, const char *type, ...) fprintf(out, "H5D_CHUNKED"); break; + case H5D_VIRTUAL: + fprintf(out, "H5D_VIRTUAL"); + break; + case H5D_NLAYOUTS: fprintf(out, "H5D_NLAYOUTS"); break; diff --git a/src/Makefile.in b/src/Makefile.in index 1933734..14ed2af 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -155,50 +155,51 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Dbtree.lo H5Dchunk.lo H5Dcompact.lo H5Dcontig.lo H5Ddbg.lo \ H5Ddeprec.lo H5Defl.lo H5Dfill.lo H5Dint.lo H5Dio.lo \ H5Dlayout.lo H5Dmpio.lo H5Doh.lo H5Dscatgath.lo H5Dselect.lo \ - H5Dtest.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo \ - H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo \ - H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo \ - H5F.lo H5Fint.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo H5Fdeprec.lo \ - H5Fefc.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ - H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo \ - H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo \ - H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5FD.lo \ - H5FDcore.lo H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo \ - H5FDmpi.lo H5FDmpio.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \ - H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ - H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo \ - H5Gcache.lo H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo \ - H5Gint.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo \ - H5Goh.lo H5Groot.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 H5HGcache.lo H5HGdbg.lo H5HGquery.lo \ - H5HL.lo H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo \ - H5Itest.lo H5L.lo H5Lexternal.lo H5lib_settings.lo H5MF.lo \ - H5MFaggr.lo H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo \ - H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ - H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ - H5Ochunk.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo \ - H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Ofsinfo.lo H5Oginfo.lo \ - H5Olayout.lo H5Olinfo.lo H5Olink.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 H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo \ - H5Pdxpl.lo H5Pencdec.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo \ - H5Pgcpl.lo H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \ - H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5PL.lo H5R.lo \ - H5Rdeprec.lo H5UC.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 \ - H5SMmessage.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 H5VM.lo H5WB.lo H5Z.lo \ - H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ - H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo + H5Dtest.lo H5Dvirtual.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo \ + H5EAcache.lo H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo \ + H5EAhdr.lo H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo \ + H5EAtest.lo H5F.lo H5Fint.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo \ + H5Fdeprec.lo H5Fefc.lo H5Ffake.lo H5Fio.lo H5Fmount.lo \ + H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.lo \ + H5Fsuper_cache.lo H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo \ + H5FAdblock.lo H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo \ + H5FAtest.lo H5FD.lo H5FDcore.lo H5FDdirect.lo H5FDfamily.lo \ + H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo H5FDmulti.lo \ + H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo \ + H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \ + H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ + H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ + H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.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 \ + H5HGcache.lo H5HGdbg.lo H5HGquery.lo H5HL.lo H5HLcache.lo \ + H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5Itest.lo H5L.lo \ + H5Lexternal.lo H5lib_settings.lo H5MF.lo H5MFaggr.lo \ + H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ + H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \ + H5Obtreek.lo H5Ocache.lo H5Ochunk.lo H5Ocont.lo H5Ocopy.lo \ + H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo \ + H5Ofsinfo.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.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 \ + H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pencdec.lo \ + H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \ + H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \ + H5Ptest.lo H5PL.lo H5R.lo H5Rdeprec.lo H5UC.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 H5SMmessage.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 \ + H5VM.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) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -756,7 +757,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Defl.c H5Dfill.c H5Dint.c \ H5Dio.c H5Dlayout.c \ - H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \ + H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c H5Dvirtual.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ @@ -1007,6 +1008,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dscatgath.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dselect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dtest.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dvirtual.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5E.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EA.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAcache.Plo@am__quote@ diff --git a/test/Makefile.am b/test/Makefile.am index b5ebcf3..f698282 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -46,7 +46,7 @@ TEST_PROG= testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \ big mtime fillval mount flush1 flush2 app_ref enum \ set_extent ttsafe enc_dec_plist enc_dec_plist_with_endianess\ getname vfd ntypes dangle dtransform reserved cross_read \ - freespace mf farray earray btree2 fheap file_image unregister + freespace mf vds farray earray btree2 fheap file_image unregister # List programs to be built when testing here. error_test and err_compat are # built at the same time as the other tests, but executed by testerror.sh. @@ -150,7 +150,8 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse earray.h5 efc[0-5].h5 log_vfd_out.log \ new_multi_file_v16-r.h5 new_multi_file_v16-s.h5 \ split_get_file_image_test-m.h5 split_get_file_image_test-r.h5 \ - file_image_core_test.h5.copy unregister_filter_1.h5 unregister_filter_2.h5 + file_image_core_test.h5.copy unregister_filter_1.h5 unregister_filter_2.h5 \ + vds_[1-4].h5 # Sources for testhdf5 executable testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ diff --git a/test/Makefile.in b/test/Makefile.in index 2a43aaf..3e4fd38 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -193,9 +193,9 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \ enc_dec_plist_with_endianess$(EXEEXT) getname$(EXEEXT) \ vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \ dtransform$(EXEEXT) reserved$(EXEEXT) cross_read$(EXEEXT) \ - freespace$(EXEEXT) mf$(EXEEXT) farray$(EXEEXT) earray$(EXEEXT) \ - btree2$(EXEEXT) fheap$(EXEEXT) file_image$(EXEEXT) \ - unregister$(EXEEXT) + freespace$(EXEEXT) mf$(EXEEXT) vds$(EXEEXT) farray$(EXEEXT) \ + earray$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT) \ + file_image$(EXEEXT) unregister$(EXEEXT) @HAVE_SHARED_CONDITIONAL_TRUE@am__EXEEXT_2 = plugin$(EXEEXT) am__EXEEXT_3 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \ gen_cross$(EXEEXT) gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \ @@ -518,6 +518,10 @@ unregister_SOURCES = unregister.c unregister_OBJECTS = unregister.$(OBJEXT) unregister_LDADD = $(LDADD) unregister_DEPENDENCIES = libh5test.la $(LIBHDF5) +vds_SOURCES = vds.c +vds_OBJECTS = vds.$(OBJEXT) +vds_LDADD = $(LDADD) +vds_DEPENDENCIES = libh5test.la $(LIBHDF5) vfd_SOURCES = vfd.c vfd_OBJECTS = vfd.$(OBJEXT) vfd_LDADD = $(LDADD) @@ -573,7 +577,7 @@ SOURCES = $(libdynlib1_la_SOURCES) $(libdynlib2_la_SOURCES) \ mount.c mtime.c ntypes.c objcopy.c ohdr.c plugin.c pool.c \ reserved.c set_extent.c space_overflow.c stab.c \ tcheck_version.c $(testhdf5_SOURCES) testmeta.c \ - $(ttsafe_SOURCES) unlink.c unregister.c vfd.c + $(ttsafe_SOURCES) unlink.c unregister.c vds.c vfd.c DIST_SOURCES = $(am__libdynlib1_la_SOURCES_DIST) \ $(am__libdynlib2_la_SOURCES_DIST) \ $(am__libdynlib3_la_SOURCES_DIST) $(libh5test_la_SOURCES) \ @@ -592,7 +596,7 @@ DIST_SOURCES = $(am__libdynlib1_la_SOURCES_DIST) \ mount.c mtime.c ntypes.c objcopy.c ohdr.c plugin.c pool.c \ reserved.c set_extent.c space_overflow.c stab.c \ tcheck_version.c $(testhdf5_SOURCES) testmeta.c \ - $(ttsafe_SOURCES) unlink.c unregister.c vfd.c + $(ttsafe_SOURCES) unlink.c unregister.c vds.c vfd.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -1101,7 +1105,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog accum.h5 cmpd_dset.h5 \ earray.h5 efc[0-5].h5 log_vfd_out.log new_multi_file_v16-r.h5 \ new_multi_file_v16-s.h5 split_get_file_image_test-m.h5 \ split_get_file_image_test-r.h5 file_image_core_test.h5.copy \ - unregister_filter_1.h5 unregister_filter_2.h5 + unregister_filter_1.h5 unregister_filter_2.h5 vds_[1-4].h5 # Test script for error_test and err_compat TEST_SCRIPT = testerror.sh testlibinfo.sh testcheck_version.sh \ @@ -1123,7 +1127,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \ big mtime fillval mount flush1 flush2 app_ref enum \ set_extent ttsafe enc_dec_plist enc_dec_plist_with_endianess\ getname vfd ntypes dangle dtransform reserved cross_read \ - freespace mf farray earray btree2 fheap file_image unregister + freespace mf vds farray earray btree2 fheap file_image unregister # These programs generate test files for the tests. They don't need to be @@ -1609,6 +1613,10 @@ unregister$(EXEEXT): $(unregister_OBJECTS) $(unregister_DEPENDENCIES) $(EXTRA_un @rm -f unregister$(EXEEXT) $(AM_V_CCLD)$(LINK) $(unregister_OBJECTS) $(unregister_LDADD) $(LIBS) +vds$(EXEEXT): $(vds_OBJECTS) $(vds_DEPENDENCIES) $(EXTRA_vds_DEPENDENCIES) + @rm -f vds$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(vds_OBJECTS) $(vds_LDADD) $(LIBS) + vfd$(EXEEXT): $(vfd_OBJECTS) $(vfd_DEPENDENCIES) $(EXTRA_vfd_DEPENDENCIES) @rm -f vfd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vfd_OBJECTS) $(vfd_LDADD) $(LIBS) @@ -1728,6 +1736,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tvltypes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unregister.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vfd.Po@am__quote@ .c.o: @@ -2254,6 +2263,13 @@ mf.log: mf$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +vds.log: vds$(EXEEXT) + @p='vds$(EXEEXT)'; \ + b='vds'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) farray.log: farray$(EXEEXT) @p='farray$(EXEEXT)'; \ b='farray'; \ diff --git a/test/vds.c b/test/vds.c new file mode 100644 index 0000000..0e4997e --- /dev/null +++ b/test/vds.c @@ -0,0 +1,452 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: Neil Fortner <nfortne2@hdfgroup.org> + * Monday, February 16, 2015 + * + * Purpose: Tests datasets with virtual layout. + */ +#include "h5test.h" +#include "H5srcdir.h" + +const char *FILENAME[] = { + "vds_1", + "vds_2", + "vds_3", + "vds_4", + NULL +}; + + +/*------------------------------------------------------------------------- + * Function: test_api + * + * Purpose: Tests API functions related to virtual datasets. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Monday, February 16, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_api(void) +{ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t src_space[4] = {-1, -1, -1, -1}; /* Source dataspaces */ + hid_t vspace[4] = {-1, -1, -1, -1}; /* Virtual dset dataspaces */ + char *src_file[4] = {"src_file1", "src_file2.", "src_file3..", "src_file4..."}; /* Source file names (different lengths) */ + char *src_dset[4] = {"src_dset1....", "src_dset2.....", "src_dset3......", "src_dset4......."}; /* Source dataset names (different lengths) */ + hsize_t dims[2] = {10, 20}; /* Data space current size */ + hsize_t start[2]; /* Hyperslab start */ + hsize_t stride[2]; /* Hyperslab stride */ + hsize_t count[2]; /* Hyperslab count */ + hsize_t block[2]; /* Hyperslab block */ + size_t size_out; + ssize_t ssize_out; + hid_t space_out = -1; + char name_out[32]; + unsigned i; + + TESTING("virtual dataset API functions"); + + /* Create DCPL */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + /* + * Test 1: All - all selection + */ + /* Create source dataspace */ + if((src_space[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(src_space[0]) < 0) + TEST_ERROR + if(H5Sselect_all(vspace[0]) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], src_space[0]) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != 1) + TEST_ERROR + + /* Test H5Pget_virtual_vspace */ + if((space_out = H5Pget_virtual_vspace(dcpl, 0)) < 0) + TEST_ERROR + if(H5Sget_select_type(space_out) != H5S_SEL_ALL) + TEST_ERROR + if(H5Sclose(space_out) < 0) + TEST_ERROR + space_out = -1; + + /* Test H5Pget_virtual_srcspace */ + if((space_out = H5Pget_virtual_srcspace(dcpl, 0)) < 0) + TEST_ERROR + if(H5Sget_select_type(space_out) != H5S_SEL_ALL) + TEST_ERROR + if(H5Sclose(space_out) < 0) + TEST_ERROR + space_out = -1; + + /* Test H5Pget_virtual_filename */ + if((ssize_out = H5Pget_virtual_filename(dcpl, 0, NULL, 0)) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_file[0])) + TEST_ERROR + HDassert((size_t)ssize_out < sizeof(name_out)); + if((ssize_out = H5Pget_virtual_filename(dcpl, 0, name_out, sizeof(name_out))) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_file[0])) + TEST_ERROR + if(HDstrncmp(name_out, src_file[0], (size_t)ssize_out + 1) != 0) + TEST_ERROR + + /* Test H5Pget_virtual_dsetname */ + if((ssize_out = H5Pget_virtual_dsetname(dcpl, 0, NULL, 0)) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_dset[0])) + TEST_ERROR + HDassert((size_t)ssize_out < sizeof(name_out)); + if((ssize_out = H5Pget_virtual_dsetname(dcpl, 0, name_out, sizeof(name_out))) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_dset[0])) + TEST_ERROR + if(HDstrncmp(name_out, src_dset[0], (size_t)ssize_out + 1) != 0) + TEST_ERROR + + /* Close */ + if(H5Sclose(src_space[0]) < 0) + TEST_ERROR + src_space[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (sizeof(src_space) / sizeof(src_space[0])); i++) { + if(src_space[i] >= 0) + (void)H5Sclose(src_space[i]); + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(space_out >= 0) + (void)H5Sclose(space_out); + if(dcpl >= 0) + (void)H5Pclose(dcpl); + } H5E_END_TRY; + + return 1; +} /* end test_api() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Tests datasets with virtual layout + * + * Return: Success: exit(0) + * + * Failure: exit(1) + * + * Programmer: Neil Fortner + * Tuesday, February 17, 2015 + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + char filename[FILENAME_BUF_SIZE]; + hid_t file, grp, fapl; + int nerrors = 0; + + /* Testing setup */ + h5_reset(); + fapl = h5_fileaccess(); + + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + nerrors += test_api(); + + /* Verify symbol table messages are cached */ + //nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); VDSINC + + if(nerrors) + goto error; + printf("All virtual dataset tests passed.\n"); + //h5_cleanup(FILENAME, fapl); VDSINC + + return 0; + +error: + nerrors = MAX(1, nerrors); + printf("***** %d VIRTUAL DATASET TEST%s FAILED! *****\n", + nerrors, 1 == nerrors ? "" : "S"); + return 1; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: Neil Fortner <nfortne2@hdfgroup.org> + * Monday, February 16, 2015 + * + * Purpose: Tests datasets with virtual layout. + */ +#include "h5test.h" +#include "H5srcdir.h" + +const char *FILENAME[] = { + "vds_1", + "vds_2", + "vds_3", + "vds_4", + NULL +}; + + +/*------------------------------------------------------------------------- + * Function: test_api + * + * Purpose: Tests API functions related to virtual datasets. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Monday, February 16, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_api(void) +{ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t src_space[4] = {-1, -1, -1, -1}; /* Source dataspaces */ + hid_t vspace[4] = {-1, -1, -1, -1}; /* Virtual dset dataspaces */ + char *src_file[4] = {"src_file1", "src_file2.", "src_file3..", "src_file4..."}; /* Source file names (different lengths) */ + char *src_dset[4] = {"src_dset1....", "src_dset2.....", "src_dset3......", "src_dset4......."}; /* Source dataset names (different lengths) */ + hsize_t dims[2] = {10, 20}; /* Data space current size */ + hsize_t start[2]; /* Hyperslab start */ + hsize_t stride[2]; /* Hyperslab stride */ + hsize_t count[2]; /* Hyperslab count */ + hsize_t block[2]; /* Hyperslab block */ + size_t size_out; + ssize_t ssize_out; + hid_t space_out = -1; + char name_out[32]; + unsigned i; + + TESTING("virtual dataset API functions"); + + /* Create DCPL */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + /* + * Test 1: All - all selection + */ + /* Create source dataspace */ + if((src_space[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(src_space[0]) < 0) + TEST_ERROR + if(H5Sselect_all(vspace[0]) < 0) + TEST_ERROR + + /* Add virtual layout mapping */ + if(H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], src_space[0]) < 0) + TEST_ERROR + + /* Test H5Pget_virtual_count */ + if(H5Pget_virtual_count(dcpl, &size_out) < 0) + TEST_ERROR + if(size_out != 1) + TEST_ERROR + + /* Test H5Pget_virtual_vspace */ + if((space_out = H5Pget_virtual_vspace(dcpl, 0)) < 0) + TEST_ERROR + if(H5Sget_select_type(space_out) != H5S_SEL_ALL) + TEST_ERROR + if(H5Sclose(space_out) < 0) + TEST_ERROR + space_out = -1; + + /* Test H5Pget_virtual_srcspace */ + if((space_out = H5Pget_virtual_srcspace(dcpl, 0)) < 0) + TEST_ERROR + if(H5Sget_select_type(space_out) != H5S_SEL_ALL) + TEST_ERROR + if(H5Sclose(space_out) < 0) + TEST_ERROR + space_out = -1; + + /* Test H5Pget_virtual_filename */ + if((ssize_out = H5Pget_virtual_filename(dcpl, 0, NULL, 0)) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_file[0])) + TEST_ERROR + HDassert((size_t)ssize_out < sizeof(name_out)); + if((ssize_out = H5Pget_virtual_filename(dcpl, 0, name_out, sizeof(name_out))) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_file[0])) + TEST_ERROR + if(HDstrncmp(name_out, src_file[0], (size_t)ssize_out + 1) != 0) + TEST_ERROR + + /* Test H5Pget_virtual_dsetname */ + if((ssize_out = H5Pget_virtual_dsetname(dcpl, 0, NULL, 0)) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_dset[0])) + TEST_ERROR + HDassert((size_t)ssize_out < sizeof(name_out)); + if((ssize_out = H5Pget_virtual_dsetname(dcpl, 0, name_out, sizeof(name_out))) < 0) + TEST_ERROR + if((size_t)ssize_out != HDstrlen(src_dset[0])) + TEST_ERROR + if(HDstrncmp(name_out, src_dset[0], (size_t)ssize_out + 1) != 0) + TEST_ERROR + + /* Close */ + if(H5Sclose(src_space[0]) < 0) + TEST_ERROR + src_space[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (sizeof(src_space) / sizeof(src_space[0])); i++) { + if(src_space[i] >= 0) + (void)H5Sclose(src_space[i]); + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(space_out >= 0) + (void)H5Sclose(space_out); + if(dcpl >= 0) + (void)H5Pclose(dcpl); + } H5E_END_TRY; + + return 1; +} /* end test_api() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Tests datasets with virtual layout + * + * Return: Success: exit(0) + * + * Failure: exit(1) + * + * Programmer: Neil Fortner + * Tuesday, February 17, 2015 + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + char filename[FILENAME_BUF_SIZE]; + hid_t file, grp, fapl; + int nerrors = 0; + + /* Testing setup */ + h5_reset(); + fapl = h5_fileaccess(); + + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + nerrors += test_api(); + + /* Verify symbol table messages are cached */ + //nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); VDSINC + + if(nerrors) + goto error; + printf("All virtual dataset tests passed.\n"); + //h5_cleanup(FILENAME, fapl); VDSINC + + return 0; + +error: + nerrors = MAX(1, nerrors); + printf("***** %d VIRTUAL DATASET TEST%s FAILED! *****\n", + nerrors, 1 == nerrors ? "" : "S"); + return 1; +} + diff --git a/tools/h5stat/h5stat.c b/tools/h5stat/h5stat.c index e9fa0fa..1310fd5 100644 --- a/tools/h5stat/h5stat.c +++ b/tools/h5stat/h5stat.c @@ -1342,8 +1342,8 @@ print_dataset_info(const iter_t *iter) printf("Dataset layout information:\n"); for(u = 0; u < H5D_NLAYOUTS; u++) - printf("\tDataset layout counts[%s]: %lu\n", (u == 0 ? "COMPACT" : - (u == 1 ? "CONTIG" : "CHUNKED")), iter->dset_layouts[u]); + printf("\tDataset layout counts[%s]: %lu\n", (u == H5D_COMPACT ? "COMPACT" : + (u == H5D_CONTIGUOUS ? "CONTIG" : (u == H5D_CHUNKED ? "CHUNKED" : "VIRTUAL"))), iter->dset_layouts[u]); printf("\tNumber of external files : %lu\n", iter->nexternal); printf("Dataset filters information:\n"); diff --git a/tools/h5stat/testfiles/h5stat_dims1.ddl b/tools/h5stat/testfiles/h5stat_dims1.ddl index c285ea4..07b2900 100644 --- a/tools/h5stat/testfiles/h5stat_dims1.ddl +++ b/tools/h5stat/testfiles/h5stat_dims1.ddl @@ -31,6 +31,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_dims2.ddl b/tools/h5stat/testfiles/h5stat_dims2.ddl index 769749e..dbccd05 100644 --- a/tools/h5stat/testfiles/h5stat_dims2.ddl +++ b/tools/h5stat/testfiles/h5stat_dims2.ddl @@ -22,6 +22,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_filters-d.ddl b/tools/h5stat/testfiles/h5stat_filters-d.ddl index 2e0bd64..6e6dd61 100644 --- a/tools/h5stat/testfiles/h5stat_filters-d.ddl +++ b/tools/h5stat/testfiles/h5stat_filters-d.ddl @@ -18,6 +18,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 Dataset layout counts[CHUNKED]: 12 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 2 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_filters-dT.ddl b/tools/h5stat/testfiles/h5stat_filters-dT.ddl index 9ef3e82..b14ca9f 100644 --- a/tools/h5stat/testfiles/h5stat_filters-dT.ddl +++ b/tools/h5stat/testfiles/h5stat_filters-dT.ddl @@ -18,6 +18,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 Dataset layout counts[CHUNKED]: 12 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 2 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_filters.ddl b/tools/h5stat/testfiles/h5stat_filters.ddl index 24522cd..1a4fd72 100644 --- a/tools/h5stat/testfiles/h5stat_filters.ddl +++ b/tools/h5stat/testfiles/h5stat_filters.ddl @@ -56,6 +56,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 1 Dataset layout counts[CONTIG]: 2 Dataset layout counts[CHUNKED]: 12 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 2 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_links2.ddl b/tools/h5stat/testfiles/h5stat_links2.ddl index 09bf937..4622884 100644 --- a/tools/h5stat/testfiles/h5stat_links2.ddl +++ b/tools/h5stat/testfiles/h5stat_links2.ddl @@ -64,6 +64,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_newgrat.ddl b/tools/h5stat/testfiles/h5stat_newgrat.ddl index 33d756b..e305f58 100644 --- a/tools/h5stat/testfiles/h5stat_newgrat.ddl +++ b/tools/h5stat/testfiles/h5stat_newgrat.ddl @@ -54,6 +54,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 1 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_numattrs2.ddl b/tools/h5stat/testfiles/h5stat_numattrs2.ddl index 1313aec..ccb23c1 100644 --- a/tools/h5stat/testfiles/h5stat_numattrs2.ddl +++ b/tools/h5stat/testfiles/h5stat_numattrs2.ddl @@ -65,6 +65,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 23 Dataset layout counts[CHUNKED]: 0 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: diff --git a/tools/h5stat/testfiles/h5stat_tsohm.ddl b/tools/h5stat/testfiles/h5stat_tsohm.ddl index 37de79b..4cf33fc 100644 --- a/tools/h5stat/testfiles/h5stat_tsohm.ddl +++ b/tools/h5stat/testfiles/h5stat_tsohm.ddl @@ -53,6 +53,7 @@ Dataset layout information: Dataset layout counts[COMPACT]: 0 Dataset layout counts[CONTIG]: 0 Dataset layout counts[CHUNKED]: 3 + Dataset layout counts[VIRTUAL]: 0 Number of external files : 0 Dataset filters information: Number of datasets with: |