From 5d0938aba6d4b99640f57abc41441e7af68a1c2c Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 24 Nov 1998 19:29:09 -0500 Subject: [svn-r947] Lots of patches to enable dataset region references. The testing for these need to be finished and checked in still. --- src/H5F.c | 1 + src/H5Fprivate.h | 1 + src/H5P.c | 78 ++++++++++++++++ src/H5Ppublic.h | 3 + src/H5R.c | 189 +++++++++++++++++++++++++++++++------ src/H5Rpublic.h | 16 +++- src/H5Sall.c | 37 ++++++++ src/H5Shyper.c | 74 ++++++++++++++- src/H5Snone.c | 37 ++++++++ src/H5Spoint.c | 66 ++++++++++++- src/H5Sprivate.h | 8 ++ src/H5Sselect.c | 279 +++++++++++++++++++++++++++++++++++++++++-------------- src/H5T.c | 4 +- src/H5Tpkg.h | 1 + 14 files changed, 685 insertions(+), 109 deletions(-) diff --git a/src/H5F.c b/src/H5F.c index 1c7baae..de32941 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -164,6 +164,7 @@ H5F_init_interface(void) H5F_access_dflt.rdcc_w0 = 0.75; /*preempt fully read chunks*/ H5F_access_dflt.threshold = 1; /*alignment applies to everything*/ H5F_access_dflt.alignment = 1; /*no alignment*/ + H5F_access_dflt.gc_ref = 0; /* Don't garbage-collect references unless user chooses to */ H5F_access_dflt.driver = H5F_LOW_DFLT; #if (H5F_LOW_DFLT == H5F_LOW_SEC2) /* Nothing to initialize */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 2efea45..6b5f0df 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -245,6 +245,7 @@ typedef struct H5F_access_t { double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/ hsize_t threshold; /* Threshold for alignment */ hsize_t alignment; /* Alignment */ + uintn gc_ref; /* Garbage-collect references? */ H5F_driver_t driver; /* Low level file driver */ union { diff --git a/src/H5P.c b/src/H5P.c index 3f00ea2..c5b01c1 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -2977,6 +2977,84 @@ H5Pget_xfer(hid_t plist_id, H5D_transfer_t *data_xfer_mode) #endif /*HAVE_PARALLEL*/ +/*------------------------------------------------------------------------- + * Function: H5Pset_gc_references + * + * Purpose: Sets the flag for garbage collecting references for the file. + * Dataset region references (and other reference types probably) use + * space in the file heap. If garbage collection is on and the user + * passes in an uninitialized value in a reference structure, the heap + * might get corrupted. When garbage collection is off however and the + * user re-uses a reference, the previous heap block will be orphaned and + * not returned to the free heap space. When garbage collection is on, + * the user must initialize the reference structures to 0 or risk heap + * corruption. + * + * Default value for garbage collecting references is off, just to be + * on the safe side. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, November 13, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref) +{ + H5F_access_t *fapl = NULL; + + FUNC_ENTER (H5Pset_gc_references, FAIL); + + /* Check args */ + if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || NULL == (fapl = H5I_object (fapl_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + } + + /* Set values */ + fapl->gc_ref = (gc_ref!=0); + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_gc_refernces + * + * Purpose: Returns the current setting for the garbage collection refernces + * property from a file access property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Tuesday, June 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_gc_reference(hid_t fapl_id, unsigned *gc_ref/*out*/) +{ + H5F_access_t *fapl = NULL; + + FUNC_ENTER (H5Pget_alignment, FAIL); + + /* Check args */ + if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || NULL == (fapl = H5I_object (fapl_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + } + + /* Get values */ + if (gc_ref) *gc_ref = fapl->gc_ref; + + FUNC_LEAVE (SUCCEED); +} + + /*-------------------------------------------------------------------------- NAME H5Pcopy diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index c59b506..c2da3dd 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -124,6 +124,9 @@ herr_t H5Pset_xfer (hid_t plist_id, H5D_transfer_t data_xfer_mode); herr_t H5Pget_xfer (hid_t plist_id, H5D_transfer_t *data_xfer_mode/*out*/); #endif +herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref); +herr_t H5Pget_gc_reference(hid_t fapl_id, unsigned *gc_ref/*out*/); + #ifdef __cplusplus } #endif diff --git a/src/H5R.c b/src/H5R.c index c50f09d..ebde9a7 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -22,6 +22,7 @@ static char RcsId[] = "@(#)$Revision$"; #include /* Error handling */ #include /* Files */ #include /* Groups */ +#include /* Global Heaps */ #include /* Memory Management */ #include /* References */ #include /* Dataspaces */ @@ -36,7 +37,7 @@ static herr_t H5R_init_interface(void); static herr_t H5R_create(void *ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space); static hid_t H5R_dereference(H5D_t *dset, H5R_type_t ref_type, void *_ref); -static H5S_t * H5R_get_region(void *ref); +static H5S_t * H5R_get_region(H5D_t *dset, H5R_type_t ref_type, void *_ref); /*-------------------------------------------------------------------------- @@ -156,44 +157,79 @@ H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type, case H5R_DATASET_REGION: { haddr_t addr; + H5HG_t hobjid; /* Heap object ID */ hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ hssize_t buf_size; /* Size of buffer needed to serialize selection */ uint8_t *p; /* Pointer to OID to store */ uint8_t *buf; /* Buffer to store serialized selection in */ - - /* Set information for dataset OID */ - p=(uint8_t *)ref->oid; - H5F_addr_pack(loc->file,&addr,&sb.objno[0]); - H5F_addr_encode(loc->file,&p,&addr); + uintn heapid_found; /* Flag for non-zero heap ID found */ + uintn u; /* local index */ /* Set up information for dataset region */ - ref->region[0]=ref->region[1]=0; /* Zero the heap ID out, may leak heap space if user is re-using reference */ + + /* Return any previous heap block to the free list if we are garbage collecting */ + if(loc->file->shared->access_parms->gc_ref) { + /* Check for an existing heap ID in the reference */ + for(u=0, heapid_found=0; uheapid[u]!=0) { + heapid_found=1; + break; + } /* end if */ + + if(heapid_found!=0) { +/* Return heap block to free list */ + } /* end if */ + } /* end if */ + + /* Zero the heap ID out, may leak heap space if user is re-using reference and doesn't have garbage collection on */ + HDmemset(ref->heapid,H5R_DSET_REG_REF_BUF_SIZE,0); /* Get the amount of space required to serialize the selection */ if ((buf_size = H5S_select_serial_size(space)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection"); + /* Increase buffer size to allow for the dataset OID */ + buf_size+=sizeof(haddr_t); + /* Allocate the space to store the serialized information */ if (NULL==(buf = H5MM_malloc(buf_size))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } + /* Serialize information for dataset OID */ + p=(uint8_t *)buf; + H5F_addr_pack(loc->file,&addr,&sb.objno[0]); + H5F_addr_encode(loc->file,&p,&addr); + /* Serialize the selection */ - if (H5S_select_serialize(space,buf) < 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 */ + + /* Save the serialized buffer for later */ + if(H5HG_insert(loc->file,buf_size,buf,&hobjid)<0) + HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, + "Unable to serialize selection"); + + /* Serialize the heap ID and index for storage in the file */ + p=(uint8_t *)ref->heapid; + H5F_addr_encode(loc->file,&p,&hobjid.addr); + INT32ENCODE(p,hobjid.idx); + + /* Free the buffer we serialized data in */ + H5MM_xfree(buf); break; } case H5R_INTERNAL: HRETURN_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, - "Dataset region and internal references are not supported yet"); + "Internal references are not yet supported"); case H5R_BADTYPE: case H5R_MAXTYPE: + default: assert("unknown reference type" && 0); HRETURN_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)"); @@ -293,26 +329,71 @@ static hid_t H5R_dereference(H5D_t *dset, H5R_type_t ref_type, void *_ref) { H5D_t *dataset; /* Pointer to dataset to open */ - hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */ H5G_entry_t ent; /* Symbol table entry */ uint8_t *p; /* Pointer to OID to store */ hid_t ret_value = FAIL; FUNC_ENTER(H5R_dereference, FAIL); - assert(ref); - assert(ref_type==H5R_OBJECT); + assert(_ref); + assert(ref_type>H5R_BADTYPE || ref_typeoid; - H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header)); + + switch(ref_type) { + case H5R_OBJECT: + { + hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */ + /* + * Switch on object type, when we implement that feature, always try to + * open a dataset for now + */ + /* Get the object oid */ + p=(uint8_t *)ref->oid; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header)); + break; + } /* end case */ + + case H5R_DATASET_REGION: + { + hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + H5HG_t hobjid; /* Heap object ID */ + uint8_t *buf; /* Buffer to store serialized selection in */ + + /* Get the heap ID for the dataset region */ + p=(uint8_t *)ref->heapid; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr)); + INT32DECODE(p,hobjid.idx); + + /* Get the dataset region from the heap (allocate inside routine) */ + if((buf=H5HG_read(ent.file,&hobjid,NULL))==NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, + "Unable to read dataset region information"); + + /* Get the object oid for the dataset */ + p=(uint8_t *)buf; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header)); + + /* Free the buffer allocated in H5HG_read() */ + H5MM_xfree(buf); + break; + } /* end case */ + + case H5R_INTERNAL: + HRETURN_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, + "Internal references are not yet supported"); + + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + assert("unknown reference type" && 0); + HRETURN_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, + "internal error (unknown reference type)"); + } /* end switch */ /* Open the dataset object */ if ((dataset=H5D_open_oid(&ent)) == NULL) { @@ -399,17 +480,60 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static H5S_t * -H5R_get_region(void __unused__ *ref) +H5R_get_region(H5D_t *dset, H5R_type_t ref_type, void *_ref) { + H5D_t *dataset; /* Pointer to dataset to open */ + H5G_entry_t ent; /* Symbol table entry */ + uint8_t *p; /* Pointer to OID to store */ + hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + H5HG_t hobjid; /* Heap object ID */ + uint8_t *buf; /* Buffer to store serialized selection in */ H5S_t *ret_value = NULL; FUNC_ENTER(H5R_get_region, NULL); - assert(ref); + assert(_ref); + assert(ref_type==H5R_DATASET_REGION); + assert(dset); + + /* Initialize the symbol table entry */ + HDmemset(&ent,0,sizeof(H5G_entry_t)); + ent.type=H5G_NOTHING_CACHED; + ent.file=H5D_get_file(dset); + + /* Get the heap ID for the dataset region */ + p=(uint8_t *)ref->heapid; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr)); + INT32DECODE(p,hobjid.idx); + + /* Get the dataset region from the heap (allocate inside routine) */ + if((buf=H5HG_read(ent.file,&hobjid,NULL))==NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, + "Unable to read dataset region information"); + + /* Get the object oid for the dataset */ + p=(uint8_t *)buf; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header)); + + /* Open the dataset object */ + if ((dataset=H5D_open_oid(&ent)) == NULL) { + HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found"); + } + + /* Copy the dataspace object */ + if ((ret_value=H5D_get_space(dataset)) == NULL) { + HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found"); + } + +/* Unserialize the selection */ + + /* Free the buffer allocated in H5HG_read() */ + H5MM_xfree(buf); + +/* Close the dataset we opened */ + -#ifdef LATER done: -#endif /* LATER */ FUNC_LEAVE(ret_value); } /* end H5R_get_region() */ @@ -435,20 +559,25 @@ done: REVISION LOG --------------------------------------------------------------------------*/ hid_t -H5Rget_region(hid_t dset, H5R_type_t rtype, void *ref) +H5Rget_region(hid_t dataset, H5R_type_t ref_type, void *_ref) { - H5S_t *space = NULL; + H5D_t *dset = NULL; /* dataset object */ + H5S_t *space = NULL; /* dataspace object */ hid_t ret_value = FAIL; FUNC_ENTER(H5Rget_region, FAIL); - H5TRACE3("i","iRtx",dset,rtype,ref); + H5TRACE3("i","iRtx",dataset,ref_type,_ref); /* Check args */ - if(ref==NULL) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer"); + if (H5I_DATASET != H5I_get_type(dataset) || NULL == (dset = H5I_object(dataset))) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset"); + if(ref_type!=H5R_DATASET_REGION) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type"); + if(_ref==NULL) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer"); - /* Create reference */ - if ((space=H5R_get_region(ref))==NULL) + /* Get the dataspace with the correct region selected */ + if ((space=H5R_get_region(dset,ref_type,_ref))==NULL) HGOTO_ERROR (H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace"); /* Atomize */ diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index c92d201..6926d86 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -40,17 +40,23 @@ typedef struct { } href_t; #endif /* LATER */ +/* Note! Be careful with the sizes of the references because they should really + * depend on the run-time values in the file. Unfortunately, the arrays need + * to be defined at run-time, so we have to go with the worst case sizes for + * them. -QAK + */ +#define H5R_OBJ_REF_BUF_SIZE sizeof(hsize_t) /* Object reference structure for user's code */ typedef struct { - unsigned long oid[2]; /* OID of object referenced */ + unsigned char oid[H5R_OBJ_REF_BUF_SIZE]; /* Buffer to store OID of object referenced */ + /* Needs to be large enough to store largest haddr_t in a worst case machine (ie. 8 bytes currently) */ } hobj_ref_t; +#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(hsize_t)+sizeof(int)) /* Dataset Region reference structure for user's code */ typedef struct { - unsigned long oid[2]; /* OID of object referenced */ - unsigned long region[2]; /* heap ID of region in object */ - unsigned long bsize; /* Memory buffer size */ - unsigned char *buf; /* Serialized selection information */ + unsigned char heapid[H5R_DSET_REG_REF_BUF_SIZE]; /* Buffer to store heap ID and index */ + /* Needs to be large enough to store largest haddr_t in a worst case machine (ie. 8 bytes currently) plus an int (4 bytes typically, but could be 8 bytes) */ } hdset_reg_ref_t; /* Publicly visible datastructures */ diff --git a/src/H5Sall.c b/src/H5Sall.c index 1148594..ea6eda0 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -603,3 +603,40 @@ H5S_all_select_serialize (const H5S_t *space, uint8_t *buf) FUNC_LEAVE (ret_value); } /* H5S_all_select_serialize() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_all_select_deserialize + PURPOSE + Deserialize the current selection from a user-provided buffer. + USAGE + herr_t H5S_all_select_deserialize(space, buf) + H5S_t *space; IN/OUT: Dataspace pointer to place selection into + uint8 *buf; IN: Buffer to retrieve serialized selection from + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Deserializes the current selection into a buffer. (Primarily for retrieving + from disk). + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_all_select_deserialize (H5S_t *space, const uint8_t __unused__ *buf) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_all_select_deserialize, FAIL); + + assert(space); + + /* Change to "all" selection */ + if((ret_value=H5S_select_all(space))<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection"); + } /* end if */ + +done: + FUNC_LEAVE (ret_value); +} /* H5S_all_select_deserialize() */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 2392ea9..690c032 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -2774,7 +2774,7 @@ H5S_hyper_select_serialize (const H5S_t *space, uint8_t *buf) for(i=0; iextent.u.simple.rank; i++) UINT32ENCODE(buf, (uint32_t)curr->start[i]); - /* Encode starting point */ + /* Encode ending point */ for(i=0; iextent.u.simple.rank; i++) UINT32ENCODE(buf, (uint32_t)curr->end[i]); @@ -2789,3 +2789,75 @@ H5S_hyper_select_serialize (const H5S_t *space, uint8_t *buf) FUNC_LEAVE (ret_value); } /* H5S_hyper_select_serialize() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_select_deserialize + PURPOSE + Deserialize the current selection from a user-provided buffer. + USAGE + herr_t H5S_hyper_select_deserialize(space, buf) + H5S_t *space; IN/OUT: Dataspace pointer to place selection into + uint8 *buf; IN: Buffer to retrieve serialized selection from + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Deserializes the current selection into a buffer. (Primarily for retrieving + from disk). + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_hyper_select_deserialize (H5S_t *space, const uint8_t *buf) +{ + int32_t rank; /* Rank of points */ + size_t num_elem=0; /* Number of elements in selection */ + hsize_t *start=NULL,*count=NULL; /* hyperslab information */ + hsize_t *tstart,*tcount; /* temporary hyperslab pointers */ + uintn i,j; /* local counting variables */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_hyper_select_deserialize, FAIL); + + /* Check args */ + assert(space); + assert(buf); + + /* Deserialize slabs to select */ + buf+=16; /* Skip over selection header */ + INT32DECODE(buf,rank); /* decode the rank of the point selection */ + if(rank!=space->extent.u.simple.rank) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace"); + UINT32DECODE(buf,num_elem); /* decode the number of points */ + + /* Allocate space for the coordinates */ + if((start = H5MM_malloc(rank*sizeof(hssize_t)))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information"); + if((count = H5MM_malloc(rank*sizeof(hssize_t)))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information"); + + /* Retrieve the coordinates from the buffer */ + for(i=0; iextent.u.simple.rank); + INT32ENCODE(buf, (uint32_t)space->extent.u.simple.rank); len+=4; /* Encode number of elements */ @@ -946,3 +946,67 @@ H5S_point_select_serialize (const H5S_t *space, uint8_t *buf) FUNC_LEAVE (ret_value); } /* H5S_point_select_serialize() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_point_select_deserialize + PURPOSE + Deserialize the current selection from a user-provided buffer. + USAGE + herr_t H5S_point_select_deserialize(space, buf) + H5S_t *space; IN/OUT: Dataspace pointer to place selection into + uint8 *buf; IN: Buffer to retrieve serialized selection from + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Deserializes the current selection into a buffer. (Primarily for retrieving + from disk). + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_point_select_deserialize (H5S_t *space, const uint8_t *buf) +{ + H5S_seloper_t op=H5S_SELECT_SET; /* Selection operation */ + int32_t rank; /* Rank of points */ + size_t num_elem=0; /* Number of elements in selection */ + hssize_t *coord=NULL, *tcoord; /* Pointer to array of elements */ + uintn i,j; /* local counting variables */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_point_select_deserialize, FAIL); + + /* Check args */ + assert(space); + assert(buf); + + /* Deserialize points to select */ + buf+=16; /* Skip over selection header */ + INT32DECODE(buf,rank); /* decode the rank of the point selection */ + if(rank!=space->extent.u.simple.rank) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace"); + UINT32DECODE(buf,num_elem); /* decode the number of points */ + + /* Allocate space for the coordinates */ + if((coord = H5MM_malloc(num_elem*rank*sizeof(hssize_t)))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information"); + + /* Retrieve the coordinates from the buffer */ + for(tcoord=coord,i=0; iextent.u.simple.rank; i++) - slab[i]=count[i]*stride[i]; - - /* Add the contiguous hyperslab to the selection */ - if(H5S_hyper_add(space,start,(const hsize_t *)slab)<0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab"); - } - } else { - /* Build the slice sizes for each dimension */ - for(i=0, acc=1; iextent.u.simple.rank; i++) { - slice[i]=acc; - acc*=count[i]; - } /* end for */ - - /* Step through all the blocks to add */ - /* (reuse the count in ACC above) */ - for(i=0; i<(int)acc; i++) { - /* Build the location of the block */ - for(j=0; jextent.u.simple.rank; j++) - slab[j]=start[j]+((i/slice[j])%count[j])*stride[j]; - - /* Add the block to the list of hyperslab selections */ - if(H5S_hyper_add(space,(const hssize_t *)slab, (const hsize_t *)block)<0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab"); - } /* end if */ - } /* end for */ - } /* end if */ -#endif /* OLD_WAY */ /* Set selection type */ space->select.type=H5S_SEL_HYPERSLABS; @@ -468,15 +433,14 @@ done: if(_block!=NULL) H5TB_release_buf(block_id); FUNC_LEAVE (ret_value); } - /*-------------------------------------------------------------------------- NAME - H5Sselect_elements + H5S_select_elements PURPOSE Specify a series of elements in the dataspace to select USAGE - herr_t H5Sselect_elements(dsid, op, num_elem, coord) + herr_t H5S_select_elements(dsid, op, num_elem, coord) hid_t dsid; IN: Dataspace ID of selection to modify H5S_seloper_t op; IN: Operation to perform on current selection size_t num_elem; IN: Number of elements in COORD array. @@ -500,26 +464,18 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t H5Sselect_elements (hid_t spaceid, H5S_seloper_t op, size_t num_elem, +herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem, const hssize_t **coord) { - H5S_t *space = NULL; /* Dataspace to modify selection of */ - herr_t ret_value=FAIL; /* return value */ + herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER (H5Sselect_elements, FAIL); + FUNC_ENTER (H5S_select_elements, FAIL); /* Check args */ - if (H5I_DATASPACE != H5I_get_type(spaceid) || - NULL == (space=H5I_object(spaceid))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); - } - if(coord==NULL || num_elem==0) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "elements not specified"); - } /* end if */ - if(op!=H5S_SELECT_SET) { - HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, - "operations other than H5S_SELECT_SET not supported currently"); - } /* end if */ + assert(space); + assert(num_elem); + assert(coord); + assert(op==H5S_SELECT_SET); #ifdef QAK printf("%s: check 1.0\n",FUNC); @@ -553,7 +509,6 @@ herr_t H5Sselect_elements (hid_t spaceid, H5S_seloper_t op, size_t num_elem, /* Set selection type */ space->select.type=H5S_SEL_POINTS; - ret_value=SUCCEED; #ifdef QAK printf("%s: check 4.0\n",FUNC); #endif /* QAK */ @@ -564,11 +519,109 @@ done: /*-------------------------------------------------------------------------- NAME + H5Sselect_elements + PURPOSE + Specify a series of elements in the dataspace to select + USAGE + herr_t H5Sselect_elements(dsid, op, num_elem, coord) + hid_t dsid; IN: Dataspace ID of selection to modify + H5S_seloper_t op; IN: Operation to perform on current selection + size_t num_elem; IN: Number of elements in COORD array. + const hssize_t **coord; IN: The location of each element selected + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + This function selects array elements to be included in the selection for + the dataspace. The COORD array is a 2-D array of size + by NUM_ELEM (ie. a list of coordinates in the dataspace). The order of + the element coordinates in the COORD array specifies the order that the + array elements are iterated through when I/O is performed. Duplicate + coordinates are not checked for. The selection operator, OP, determines + how the new selection is to be combined with the existing selection for + the dataspace. Currently, only H5S_SELECT_SET is supported, which replaces + the existing selection with the one defined in this call. When operators + other than H5S_SELECT_SET are used to combine a new selection with an + existing selection, the selection ordering is reset to 'C' array ordering. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Sselect_elements (hid_t spaceid, H5S_seloper_t op, size_t num_elem, + const hssize_t **coord) +{ + H5S_t *space = NULL; /* Dataspace to modify selection of */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER (H5Sselect_elements, FAIL); + + /* Check args */ + if (H5I_DATASPACE != H5I_get_type(spaceid) || + NULL == (space=H5I_object(spaceid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); + } + if(coord==NULL || num_elem==0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "elements not specified"); + } /* end if */ + if(op!=H5S_SELECT_SET) { + HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, + "operations other than H5S_SELECT_SET not supported currently"); + } /* end if */ + + /* Call the real element selection routine */ + if((ret_value=H5S_select_elements(space,op,num_elem,coord))<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't select elements"); + } /* end if */ + +done: + FUNC_LEAVE (ret_value); +} /* H5Sselect_elements() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_select_all + PURPOSE + Specify the the entire extent is selected + USAGE + herr_t H5S_select_all(dsid) + hid_t dsid; IN: Dataspace ID of selection to modify + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + This function selects the entire extent for a dataspace. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5S_select_all (H5S_t *space) +{ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER (H5S_select_all, FAIL); + + /* Check args */ + assert(space); + + /* Remove current selection first */ + if(H5S_select_release(space)<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection"); + } /* end if */ + + /* Set selection type */ + space->select.type=H5S_SEL_ALL; + +done: + FUNC_LEAVE (ret_value); +} /* H5S_select_all() */ + +/*-------------------------------------------------------------------------- + NAME H5Sselect_all PURPOSE Specify the the entire extent is selected USAGE - herr_t H5Sselect_elements(dsid) + herr_t H5Sselect_all(dsid) hid_t dsid; IN: Dataspace ID of selection to modify RETURNS Non-negative on success/Negative on failure @@ -582,29 +635,62 @@ done: herr_t H5Sselect_all (hid_t spaceid) { H5S_t *space = NULL; /* Dataspace to modify selection of */ - herr_t ret_value=FAIL; /* return value */ + herr_t ret_value=SUCCEED; /* return value */ FUNC_ENTER (H5Sselect_all, FAIL); /* Check args */ - if (H5I_DATASPACE != H5I_get_type(spaceid) || - NULL == (space=H5I_object(spaceid))) { + if (H5I_DATASPACE != H5I_get_type(spaceid) || NULL == (space=H5I_object(spaceid))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); } /* Remove current selection first */ + if((ret_value=H5S_select_all(space))<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection"); + } /* end if */ + +done: + FUNC_LEAVE (ret_value); +} /* H5Sselect_all() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_select_none + PURPOSE + Specify that nothing is selected in the extent + USAGE + herr_t H5S_select_none(dsid) + hid_t dsid; IN: Dataspace ID of selection to modify + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + This function de-selects the entire extent for a dataspace. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5S_select_none (H5S_t *space) +{ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER (H5S_select_none, FAIL); + + /* Check args */ + assert(space); + + /* Remove current selection first */ if(H5S_select_release(space)<0) { HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab"); } /* end if */ /* Set selection type */ - space->select.type=H5S_SEL_ALL; - ret_value=SUCCEED; + space->select.type=H5S_SEL_NONE; done: FUNC_LEAVE (ret_value); -} /* H5Sselect_all() */ +} /* H5S_select_none() */ /*-------------------------------------------------------------------------- NAME @@ -612,7 +698,7 @@ done: PURPOSE Specify that nothing is selected in the extent USAGE - herr_t H5Sselect_elements(dsid) + herr_t H5Sselect_none(dsid) hid_t dsid; IN: Dataspace ID of selection to modify RETURNS Non-negative on success/Negative on failure @@ -636,16 +722,11 @@ herr_t H5Sselect_none (hid_t spaceid) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); } - /* Remove current selection first */ - if(H5S_select_release(space)<0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, - "can't release hyperslab"); + /* Change to "none" selection */ + if((ret_value=H5S_select_none(space))<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection"); } /* end if */ - /* Set selection type */ - space->select.type=H5S_SEL_NONE; - ret_value=SUCCEED; - done: FUNC_LEAVE (ret_value); } /* H5Sselect_none() */ @@ -989,3 +1070,61 @@ H5S_select_serialize (const H5S_t *space, uint8_t *buf) FUNC_LEAVE (ret_value); } /* H5S_select_serialize() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_select_deserialize + PURPOSE + 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 + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Deserializes the current selection into a buffer. (Primarily for retrieving + from disk). This routine just hands off to the appropriate routine for each + type of selection. The format of the serialized information is shown in + the H5S_select_serialize() header. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_select_deserialize (H5S_t *space, const uint8_t *buf) +{ + const uint32_t *sel_type; /* Pointer to the selection type */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_select_deserialize, FAIL); + + assert(space); + + sel_type=(const uint32_t *)buf; + switch(*sel_type) { + case H5S_SEL_POINTS: /* Sequence of points selected */ + ret_value=H5S_point_select_deserialize(space,buf); + break; + + case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */ + ret_value=H5S_hyper_select_deserialize(space,buf); + break; + + case H5S_SEL_ALL: /* Entire extent selected */ + ret_value=H5S_all_select_deserialize(space,buf); + break; + + case H5S_SEL_NONE: /* Nothing selected */ + ret_value=H5S_none_select_deserialize(space,buf); + break; + + case H5S_SEL_ERROR: + case H5S_SEL_N: + break; + } + + FUNC_LEAVE (ret_value); +} /* H5S_select_deserialize() */ diff --git a/src/H5T.c b/src/H5T.c index c964cad..0f25937 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -613,7 +613,7 @@ H5T_init_interface(void) dt->state = H5T_STATE_IMMUTABLE; H5F_addr_undef (&(dt->ent.header)); dt->type = H5T_REFERENCE; - dt->size = sizeof(haddr_t); + dt->size = H5R_OBJ_REF_BUF_SIZE; dt->u.atomic.order = H5T_ORDER_NONE; dt->u.atomic.offset = 0; dt->u.atomic.prec = 8 * dt->size; @@ -632,7 +632,7 @@ H5T_init_interface(void) dt->state = H5T_STATE_IMMUTABLE; H5F_addr_undef (&(dt->ent.header)); dt->type = H5T_REFERENCE; - dt->size = sizeof(haddr_t); + dt->size = H5R_DSET_REG_REF_BUF_SIZE; dt->u.atomic.order = H5T_ORDER_NONE; dt->u.atomic.offset = 0; dt->u.atomic.prec = 8 * dt->size; diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 2679b75..b451e3f 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -25,6 +25,7 @@ #include #include +#include /* Publicly accessible reference information needed also */ #include #define H5T_NAMELEN 10 /*length of debugging name buffer */ -- cgit v0.12