From 14200fef675e0c1732d84ae7e06e81a812bd5e99 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Tue, 10 Feb 2015 14:58:09 -0500 Subject: [svn-r26153] INCOMPLETE, UNWORKING CODE Commit progress through 2/10/15 at 1500 CST --- MANIFEST | 1 + src/H5Dlayout.c | 12 +++ src/H5Dpkg.h | 5 ++ src/H5Dprivate.h | 5 ++ src/H5Dpublic.h | 1 + src/H5Olayout.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/H5Oprivate.h | 27 ++++++- src/H5Pdcpl.c | 121 +++++++++++++++++++++++++++++- src/H5R.c | 4 +- src/H5S.c | 4 +- src/H5Sall.c | 41 ++++++++-- src/H5Shyper.c | 80 +++++++++++++------- src/H5Snone.c | 36 +++++++-- src/H5Spkg.h | 2 +- src/H5Spoint.c | 62 +++++++++++----- src/H5Sselect.c | 20 +++-- src/Makefile.am | 2 +- 17 files changed, 559 insertions(+), 86 deletions(-) diff --git a/MANIFEST b/MANIFEST index fbc4a1e..a0737ef 100644 --- a/MANIFEST +++ b/MANIFEST @@ -615,6 +615,7 @@ ./src/H5Dscatgath.c ./src/H5Dselect.c ./src/H5Dtest.c +./src/H5Dvirtual.c ./src/H5E.c ./src/H5Edefin.h ./src/H5Edeprec.c diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index d7d7b88..5929163 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -104,6 +104,10 @@ H5D__layout_set_io_ops(const H5D_t *dataset) dataset->shared->layout.ops = H5D_LOPS_COMPACT; break; + case H5D_VIRTUAL: + dataset->shared->layout.ops = H5D_LOPS_VIRTUAL; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -169,6 +173,11 @@ H5D__layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t includ ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */ break; + case H5D_VIRTUAL: + ret_value += H5F_SIZEOF_ADDR(f); /* Address of global heap */ + ret_value += 4; /* Global heap index */ + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -439,6 +448,9 @@ H5D__layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t case H5D_COMPACT: break; + case H5D_VIRTUAL: + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 5a785a3..1a659a1 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -173,11 +173,15 @@ typedef struct { hbool_t *dirty; /* Pointer to dirty flag to mark */ } H5D_compact_storage_t; +typedef struct { +} H5D_virtual_storage_t; + 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_storage_t; /* Typedef for raw data I/O operation info */ @@ -515,6 +519,7 @@ H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CONTIG[1]; H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_EFL[1]; H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_COMPACT[1]; H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CHUNK[1]; +H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1]; /* Chunked layout operations */ H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BTREE[1]; diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 0b8b76f..804afd1 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -174,6 +174,11 @@ H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, /* Functions that operate on chunked storage */ H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr); +/* 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); + /* 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, int indent, int fwidth, unsigned ndims); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index e7ae3ae..003e357 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -51,6 +51,7 @@ typedef enum H5D_layout_t { H5D_COMPACT = 0, /*raw data is very small */ 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_layout_t; diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 4c43873..2b12a97 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -96,10 +96,11 @@ H5FL_DEFINE(H5O_layout_t); *------------------------------------------------------------------------- */ static void * -H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, +H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p) { H5O_layout_t *mesg = NULL; + uint8_t *heap_block = NULL; unsigned u; void *ret_value; /* Return value */ @@ -241,6 +242,72 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, mesg->ops = H5D_LOPS_CHUNK; break; + 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); + + /* Initialize other fields */ + mesg->storage.u.virtual.list_nused = 0; + mesg->storage.u.virtual.list = NULL; + mesg->storage.u.virtual.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; + size_t block_size = 0; + 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))) + HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "Unable to read global heap block") + + heap_block_p = 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)))) + 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; + + /* Decode each entry */ + for(i = 0; i < mesg->storage.u.virtual.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; + + /* 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; + + /* Source selection */ + H5S_SELECT_DESERIALIZE(&(mesg->storage.u.virtual.list[i].source_select), &heap_block_p) + + /* Virtual selection */ + H5S_SELECT_SERIALIZE(&(mesg->storage.u.virtual.list[i].virtual_select), &heap_block_p) + } /* end for */ + + /* Read stored checksum */ + UINT32DECODE(heap_block_p, stored_chksum) + + /* Compute checksum */ + computed_chksum = H5_checksum_metadata(heap_block, block_size - (size_t)4, 0); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect metadata checksum for global heap block") + } /* end if */ + + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -253,9 +320,13 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, done: if(ret_value == NULL) - if(mesg) + if(mesg) { + if(mesg->type == H5D_VIRTUAL) + mesg-> mesg = H5FL_FREE(H5O_layout_t, mesg); + heap_block = H5MM_xfree(heap_block); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_decode() */ @@ -294,6 +365,7 @@ static herr_t H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; + uint8_t *heap_block = NULL; unsigned u; herr_t ret_value = SUCCEED; /* Return value */ @@ -344,6 +416,101 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi UINT32ENCODE(p, mesg->u.chunk.dim[u]); break; + case H5D_VIRTUAL: + /* Create heap block if it has not been created yet */ + /* 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)) { + uint8_t *heap_block_p; + size_t block_size; + hssize_t select_serial_size; + hsize_t tmp_hsize; + uint32_t chksum; + size_t i; + + /* + * Calculate heap block size + */ + /* Number of entries */ + 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); + + /* Source file name */ + block_size += HDstrlen(mesg->storage.u.virtual.list[i].source_file) + (size_t)1; + + /* Source dset name */ + block_size += HDstrlen(mesg->storage.u.virtual.list[i].source_dset) + (size_t)1; + + /* Source selection */ + if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virtual.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) + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size") + block_size += (size_t)select_serial_size; + } /* end for */ + + /* Checksum */ + block_size += 4; + + /* Allocate heap block */ + if(NULL == (heap_block = (uint8_t *)H5MM_malloc((size_t)mesg->storage.u.virtual.serial_list_size))) + HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate heap block") + + /* + * Encode heap block + */ + heap_block_p = heap_block; + + /* Number of entries */ + tmp_hsize = (hsize_t)mesg->storage.u.virtual.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++) { + /* Source file name */ + (void)HDstrcpy(heap_block_p, mesg->storage.u.virtual.list[i].source_file); + heap_block_p += HDstrlen(heap_block_p) + 1; + + /* Source dataset name */ + (void)HDstrcpy(heap_block_p, mesg->storage.u.virtual.list[i].source_dset); + heap_block_p += HDstrlen(heap_block_p) + 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") + + /* 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") + } /* end for */ + + /* Checksum */ + chksum = H5_checksum_metadata(heap_block, block_size - (size_t)4, 0); + UINT32ENCODE(heap_block_p, chksum) + + /* 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) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to insert virtual dataset heap block") + } /* end if */ + + /* 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); + + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -351,6 +518,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); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_encode() */ @@ -403,6 +572,11 @@ H5O_layout_copy(const void *_mesg, void *_dest) if(dest->type == H5D_CHUNKED && dest->storage.u.chunk.ops) H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE); + /* Deep copy the entry list for virtual datasets */ + if(mesg->type == H5D_VIRTUAL) + if(H5D_virtual_copy_layout(dest) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy virtual layout") + /* Set return value */ ret_value = dest; @@ -468,19 +642,43 @@ static herr_t H5O_layout_reset(void *_mesg) { H5O_layout_t *mesg = (H5O_layout_t *)_mesg; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT if(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 */ + /* Reset the message */ mesg->type = H5D_CONTIGUOUS; } /* end if */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_reset() */ @@ -560,6 +758,13 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") break; + 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) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -647,6 +852,10 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, } /* end if */ break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -745,6 +954,11 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, "Data Size:", mesg->storage.u.compact.size); break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index e3a2d33..b3d6237 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -372,7 +372,8 @@ typedef struct H5O_efl_t { * for larger chunk dimensions, stores chunk indices into their own * message (the "layout index" message), adds features for compact/dense * storage of elements and/or chunk records, adds features for abbreviating - * the storage used for partial chunks on boundaries, etc. + * the storage used for partial chunks on boundaries, adds the virtual + * layout type, etc. */ #define H5O_LAYOUT_VERSION_4 4 @@ -410,12 +411,36 @@ typedef struct H5O_storage_compact_t { void *buf; /* Buffer for compact dataset */ } 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; + + /* Not stored */ + H5D_t *source_dset; +} H5O_storage_virtual_ent_t; + +typedef struct H5O_storage_virtual_t { + /* Stored in message */ + H5HG_t serial_list_hobjid; + + /* Stored in heap */ + size_t list_nused; /* Number of slots used */ + H5O_storage_virtual_ent_t *list; /* Array of virtual dataset mapping entries */ + + /* Not stored */ + size_t list_nalloc; /* Number of slots allocated */ +} H5O_storage_virtual_t; + typedef struct H5O_storage_t { H5D_layout_t type; /* Type of layout */ union { 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 */ } u; } H5O_storage_t; diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index a753209..e9bd9bf 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -41,6 +41,7 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ +#include "H5Oprivate.h" /* Object headers */ #include "H5Ppkg.h" /* Property lists */ #include "H5Tprivate.h" /* Datatypes */ #include "H5Zpkg.h" /* Data filters */ @@ -55,13 +56,16 @@ #define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0} #define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_BTREE, HADDR_UNDEF, NULL, {{HADDR_UNDEF, NULL}}} #define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} +#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0} #ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER #define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }} #define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }} #define H5D_DEF_STORAGE_CHUNK {H5D_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }} -#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_COMPACT} +#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_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CONTIG} #define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CHUNK} +#define H5D_DEF_LAYOUT_VIRTUAL {H5D_VIRTUAL, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_VIRTUAL} #else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ /* Note that the compact & chunked layout initialization values are using the * contiguous layout initialization in the union, because the contiguous @@ -71,6 +75,7 @@ #define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} #define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} #define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} +#define H5D_DEF_LAYOUT_VIRTUAL {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}} #endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ /* ======== Dataset creation properties ======== */ @@ -79,7 +84,10 @@ #define H5D_CRT_LAYOUT_DEF H5D_DEF_LAYOUT_CONTIG #define H5D_CRT_LAYOUT_ENC H5P__dcrt_layout_enc #define H5D_CRT_LAYOUT_DEC H5P__dcrt_layout_dec +#define H5D_CRT_LAYOUT_DEL H5P__dcrt_layout_del +#define H5D_CRT_LAYOUT_COPY H5P__dcrt_layout_copy #define H5D_CRT_LAYOUT_CMP H5P__dcrt_layout_cmp +#define H5D_CRT_LAYOUT_CLOSE H5P__dcrt_layout_close /* Definitions for fill value. size=0 means fill value will be 0 as * library default; size=-1 means fill value is undefined. */ #define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t) @@ -183,10 +191,12 @@ static const H5O_efl_t H5D_def_efl_g = H5D_CRT_EXT_FILE_LIST_DEF; static const H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT; static const H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG; static const H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK; +static const H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_VIRTUAL; #else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ static H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT; static H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG; static H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK; +static H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_CHUNK; static hbool_t H5P_dcrt_def_layout_init_g = FALSE; #endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ @@ -213,7 +223,7 @@ H5P__dcrt_reg_prop(H5P_genclass_t *pclass) /* Register the storage layout property */ if(H5P_register_real(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &H5D_def_layout_g, NULL, NULL, NULL, H5D_CRT_LAYOUT_ENC, H5D_CRT_LAYOUT_DEC, - NULL, NULL, H5D_CRT_LAYOUT_CMP, NULL) < 0) + H5D_CRT_LAYOUT_DEL, H5D_CRT_LAYOUT_COPY, H5D_CRT_LAYOUT_CMP, H5D_CRT_LAYOUT_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the fill value property */ @@ -444,6 +454,9 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size) for(u = 0; u < layout->u.chunk.ndims; u++) UINT32ENCODE(*pp, layout->u.chunk.dim[u]) } /* end if */ + else if(H5D_VIRTUAL == layout->type) { + HDassert(0 && "Not yet implemented...");//VDSINC + } /* end else */ } /* end if */ /* Size of layout type */ @@ -531,6 +544,10 @@ H5P__dcrt_layout_dec(const void **_pp, void *value) } break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -546,6 +563,66 @@ done: /*------------------------------------------------------------------------- + * Function: H5P__dcrt_layout_del + * + * Purpose: Frees memory used to store the layout property + * + * Return: Success: Non-negative + * Failure: Never fails + * + * Programmer: Neil Fortner + * Tuesday, Feb 10, 2015 + * + *------------------------------------------------------------------------- + */ +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 + + HDassert(value); + + (void)H5O_msg_free(H5O_LAYOUT_ID, value) + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P__dcrt_layout_del() */ + + +/*-------------------------------------------------------------------------- + * Function: H5P__dcrt_layout_copy + * + * Purpose: Copy the layout property + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Monday, Feb 9, 2015 + * + *-------------------------------------------------------------------------- + */ +static herr_t +H5P__dcrt_layout_copy(const char UNUSED *name, size_t UNUSED size, void *value) +{ + H5O_layout_t *layout; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(value); + + layout = (H5O_layout_t *)value; + + if(layout->type == H5D_VIRTUAL) + if(H5D_virtual_copy_layout(layout) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual layout") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__dcrt_layout_copy() */ + + +/*------------------------------------------------------------------------- * Function: H5P__dcrt_layout_cmp * * Purpose: Callback routine which is called whenever the layout @@ -605,6 +682,10 @@ H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t UNUSED s } /* end case */ break; + case H5D_VIRTUAL: + HDassert(0 && "Not yet implemented...");//VDSINC + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -617,6 +698,32 @@ done: /*------------------------------------------------------------------------- + * Function: H5P__dcrt_layout_close + * + * Purpose: Frees memory used to store the layout property + * + * Return: Success: Non-negative + * Failure: Never fails + * + * Programmer: Neil Fortner + * Tuesday, Feb 10, 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__dcrt_layout_close(const char UNUSED *name, size_t UNUSED size, void *value) +{ + FUNC_ENTER_STATIC_NOERR + + HDassert(value); + + (void)H5O_msg_free(H5O_LAYOUT_ID, value) + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P__dcrt_layout_close() */ + + +/*------------------------------------------------------------------------- * Function: H5P__fill_value_enc * * Purpose: Callback routine which is called whenever the fill value @@ -1141,6 +1248,10 @@ H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout) fill.alloc_time = H5D_ALLOC_TIME_INCR; break; + case H5D_VIRTUAL: + fill.alloc_time = H5D_ALLOC_TIME_INCR; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: @@ -1181,6 +1292,7 @@ H5P__init_def_layout(void) const H5O_layout_chunk_t def_layout_chunk = H5D_DEF_LAYOUT_CHUNK_INIT; const H5O_storage_compact_t def_store_compact = H5D_DEF_STORAGE_COMPACT_INIT; const H5O_storage_chunk_t def_store_chunk = H5D_DEF_STORAGE_CHUNK_INIT; + const H5O_storage_virtual_t def_store_virtual = H5D_DEF_STORAGE_VIRTUAL_INIT; FUNC_ENTER_STATIC_NOERR @@ -1188,6 +1300,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; /* Note that we've initialized the default values */ H5P_dcrt_def_layout_init_g = TRUE; @@ -1257,6 +1370,10 @@ H5Pset_layout(hid_t plist_id, H5D_layout_t layout_type) layout = &H5D_def_layout_chunk_g; break; + case H5D_VIRTUAL: + layout = &H5D_def_layout_virtual_g; + break; + case H5D_LAYOUT_ERROR: case H5D_NLAYOUTS: default: diff --git a/src/H5R.c b/src/H5R.c index 8396dcc..f44b21f 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -291,7 +291,7 @@ H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5 H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); /* Serialize the selection into heap buffer */ - if(H5S_SELECT_SERIALIZE(space, p) < 0) + if(H5S_SELECT_SERIALIZE(space, &p) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") /* Save the serialized buffer for later */ @@ -659,7 +659,7 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref) HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found") /* Unserialize the selection */ - if(H5S_select_deserialize(ret_value, p) < 0) + if(H5S_select_deserialize(&ret_value, &p) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection") done: diff --git a/src/H5S.c b/src/H5S.c index 1146ab4..7798049 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -1536,7 +1536,7 @@ H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc) buf += extent_size; /* Encode the selection part of dataspace. */ - if(H5S_SELECT_SERIALIZE(obj, buf) < 0) + if(H5S_SELECT_SERIALIZE(obj, &buf) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode select space") } /* end else */ @@ -1655,7 +1655,7 @@ H5S_decode(const unsigned char *buf) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection") /* Decode the select part of dataspace. I believe this part always exists. */ - if(H5S_SELECT_DESERIALIZE(ds, buf) < 0) + if(H5S_SELECT_DESERIALIZE(&ds, &buf) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, NULL, "can't decode space selection") /* Set return value */ diff --git a/src/H5Sall.c b/src/H5Sall.c index 24caad2..a9e72fb 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -510,17 +510,19 @@ H5S_all_serial_size (const H5S_t UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_all_serialize (const H5S_t *space, uint8_t *buf) +H5S_all_serialize (const H5S_t *space, uint8_t **p) { FUNC_ENTER_NOAPI_NOINIT_NOERR HDassert(space); + HDassert(p); + HDassert(*p); /* Store the preamble information */ - UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ - UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */ - UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */ - UINT32ENCODE(buf, (uint32_t)0); /* Store the additional information length */ + UINT32ENCODE(*p, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ + UINT32ENCODE(*p, (uint32_t)1); /* Store the version number */ + UINT32ENCODE(*p, (uint32_t)0); /* Store the un-used padding */ + UINT32ENCODE(*p, (uint32_t)0); /* Store the additional information length */ FUNC_LEAVE_NOAPI(SUCCEED) } /* H5S_all_serialize() */ @@ -546,19 +548,42 @@ H5S_all_serialize (const H5S_t *space, uint8_t *buf) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_all_deserialize(H5S_t *space, const uint8_t UNUSED *buf) +H5S_all_deserialize(H5S_t **space, const uint8_t **p) { - herr_t ret_value; /* return value */ + H5S_t *tmp_space; + herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI(FAIL) HDassert(space); + 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((ret_value = H5S_select_all(space, TRUE)) < 0) + if(H5S_select_all(tmp_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 c97c9b6..02d9359 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -1994,7 +1994,7 @@ H5S_hyper_serial_size(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **buf) +H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **p) { H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ hsize_t u; /* Index variable */ @@ -2007,7 +2007,7 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, HDassert(start); HDassert(end); HDassert(rank < H5O_LAYOUT_NDIMS); - HDassert(buf && *buf); + HDassert(p && *p); /* Walk through the list of spans, recursing or outputing them */ curr=spans->head; @@ -2019,7 +2019,7 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, end[rank]=curr->high; /* Recurse down to the next dimension */ - if(H5S_hyper_serialize_helper(curr->down,start,end,rank+1,buf)<0) + if(H5S_hyper_serialize_helper(curr->down,start,end,rank+1,p)<0) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") } /* end if */ else { @@ -2027,17 +2027,17 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, /* Encode previous starting points */ for(u=0; ulow); + UINT32ENCODE(*p, (uint32_t)curr->low); /* Encode previous ending points */ for(u=0; uhigh); + UINT32ENCODE(*p, (uint32_t)curr->high); } /* end else */ /* Advance to next node */ @@ -2069,7 +2069,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) +H5S_hyper_serialize (const H5S_t *space, uint8_t **p) { const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ @@ -2089,11 +2089,11 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) HDassert(space); /* Store the preamble information */ - UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ - UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */ - UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */ - lenp = buf; /* keep the pointer to the length location for later */ - buf += 4; /* skip over space for length */ + UINT32ENCODE(*p, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ + UINT32ENCODE(*p, (uint32_t)1); /* Store the version number */ + UINT32ENCODE(*p, (uint32_t)0); /* Store the un-used padding */ + lenp = *p; /* keep the pointer to the length location for later */ + *p += 4; /* skip over space for length */ /* Encode number of dimensions */ UINT32ENCODE(buf, (uint32_t)space->extent.rank); @@ -2114,7 +2114,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Encode number of hyperslabs */ H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); - UINT32ENCODE(buf, (uint32_t)block_count); + UINT32ENCODE(*p, (uint32_t)block_count); len+=4; /* Now serialize the information for the regular hyperslab */ @@ -2137,11 +2137,11 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Encode hyperslab starting location */ for(u = 0; u < ndims; u++) - UINT32ENCODE(buf, (uint32_t)offset[u]); + UINT32ENCODE(*p, (uint32_t)offset[u]); /* Encode hyperslab ending location */ for(u = 0; u < ndims; u++) - UINT32ENCODE(buf, (uint32_t)(offset[u] + (diminfo[u].block - 1))); + UINT32ENCODE(*p, (uint32_t)(offset[u] + (diminfo[u].block - 1))); /* Move the offset to the next sequence to start */ offset[fast_dim]+=diminfo[fast_dim].stride; @@ -2192,7 +2192,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Encode number of hyperslabs */ block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst); H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); - UINT32ENCODE(buf, (uint32_t)block_count); + UINT32ENCODE(*p, (uint32_t)block_count); len+=4; /* Add 8 bytes times the rank for each hyperslab selected */ @@ -2200,7 +2200,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) len += (size_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, &buf); + H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, p); } /* end else */ /* Encode length */ @@ -2230,8 +2230,9 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf) +H5S_hyper_deserialize (H5S_t **space, const uint8_t **p) { + H5S_t *tmp_space; uint32_t rank; /* rank of points */ size_t num_elem=0; /* number of elements in selection */ hsize_t start[H5O_LAYOUT_NDIMS]; /* hyperslab start information */ @@ -2251,14 +2252,29 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf) /* Check args */ HDassert(space); - HDassert(buf); + HDassert(p); + HDassert(*p); /* Deserialize slabs to select */ - buf+=16; /* Skip over selection header */ - UINT32DECODE(buf,rank); /* decode the rank of the point selection */ - if(rank!=space->extent.rank) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace") - UINT32DECODE(buf,num_elem); /* decode the number of points */ + *p+=12; /* Skip over remainder of 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 */ /* Set the count & stride for all blocks */ for(tcount=count,tstride=stride,j=0; jextent.rank); + UINT32ENCODE(*p, (uint32_t)space->extent.rank); len+=4; /* Encode number of elements */ - UINT32ENCODE(buf, (uint32_t)space->select.num_elem); + UINT32ENCODE(*p, (uint32_t)space->select.num_elem); len+=4; /* Encode each point in selection */ curr=space->select.sel_info.pnt_lst->head; while(curr!=NULL) { /* Add 4 bytes times the rank for each element selected */ - len+=4*space->extent.rank; + *p+=4*space->extent.rank; /* Encode each point */ for(u=0; uextent.rank; u++) - UINT32ENCODE(buf, (uint32_t)curr->pnt[u]); + UINT32ENCODE(*p, (uint32_t)curr->pnt[u]); curr=curr->next; } /* end while */ @@ -884,8 +884,9 @@ H5S_point_serialize (const H5S_t *space, uint8_t *buf) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_deserialize (H5S_t *space, const uint8_t *buf) +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 */ size_t num_elem=0; /* Number of elements in selection */ @@ -897,14 +898,29 @@ H5S_point_deserialize (H5S_t *space, const uint8_t *buf) /* Check args */ HDassert(space); - HDassert(buf); + HDassert(p); + HDassert(*p); /* Deserialize points to select */ - buf += 16; /* Skip over selection header */ - UINT32DECODE(buf, rank); /* decode the rank of the point selection */ - if(rank != space->extent.rank) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace") - UINT32DECODE(buf, num_elem); /* decode the number of points */ + *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 */ /* Allocate space for the coordinates */ if(NULL == (coord = (hsize_t *)H5MM_malloc(num_elem * rank * sizeof(hsize_t)))) @@ -913,13 +929,21 @@ H5S_point_deserialize (H5S_t *space, const uint8_t *buf) /* Retrieve the coordinates from the buffer */ for(tcoord = coord, i = 0; i < num_elem; i++) for(j = 0; j < (unsigned)rank; j++, tcoord++) - UINT32DECODE(buf, *tcoord); + UINT32DECODE(*p, *tcoord); /* Select points */ - if(H5S_select_elements(space, op, num_elem, (const hsize_t *)coord) < 0) + if(H5S_select_elements(tmp_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/H5Sselect.c b/src/H5Sselect.c index 2cb4b38..7d22f08 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -241,7 +241,7 @@ H5S_select_serial_size(const H5S_t *space) USAGE herr_t H5S_select_serialize(space, buf) const H5S_t *space; IN: Dataspace with selection to serialize - uint8_t *buf; OUT: Buffer to put serialized selection + uint8_t **p; OUT: Buffer to put serialized selection RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -256,7 +256,7 @@ H5S_select_serial_size(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_select_serialize(const H5S_t *space, uint8_t *buf) +H5S_select_serialize(const H5S_t *space, uint8_t **p) { herr_t ret_value=SUCCEED; /* Return value */ @@ -266,7 +266,7 @@ H5S_select_serialize(const H5S_t *space, uint8_t *buf) HDassert(buf); /* Call the selection type's serialize function */ - ret_value=(*space->select.type->serialize)(space,buf); + ret_value=(*space->select.type->serialize)(space,p); FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_select_serialize() */ @@ -444,9 +444,8 @@ H5S_select_valid(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_select_deserialize (H5S_t *space, const uint8_t *buf) +H5S_select_deserialize (H5S_t **space, const uint8_t **p) { - const uint8_t *tbuf; /* Temporary pointer to the selection type */ uint32_t sel_type; /* Pointer to the selection type */ herr_t ret_value=FAIL; /* return value */ @@ -454,23 +453,22 @@ H5S_select_deserialize (H5S_t *space, const uint8_t *buf) HDassert(space); - tbuf=buf; - UINT32DECODE(tbuf, sel_type); + UINT32DECODE(*p, sel_type); switch(sel_type) { case H5S_SEL_POINTS: /* Sequence of points selected */ - ret_value=(*H5S_sel_point->deserialize)(space,buf); + ret_value=(*H5S_sel_point->deserialize)(space,p); break; case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */ - ret_value=(*H5S_sel_hyper->deserialize)(space,buf); + ret_value=(*H5S_sel_hyper->deserialize)(space,p); break; case H5S_SEL_ALL: /* Entire extent selected */ - ret_value=(*H5S_sel_all->deserialize)(space,buf); + ret_value=(*H5S_sel_all->deserialize)(space,p); break; case H5S_SEL_NONE: /* Nothing selected */ - ret_value=(*H5S_sel_none->deserialize)(space,buf); + ret_value=(*H5S_sel_none->deserialize)(space,p); break; default: diff --git a/src/Makefile.am b/src/Makefile.am index 4b55144..6a745e2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,7 +48,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 \ -- cgit v0.12