diff options
Diffstat (limited to 'src/H5R.c')
-rw-r--r-- | src/H5R.c | 189 |
1 files changed, 159 insertions, 30 deletions
@@ -22,6 +22,7 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5Eprivate.h> /* Error handling */ #include <H5Fprivate.h> /* Files */ #include <H5Gprivate.h> /* Groups */ +#include <H5HGprivate.h> /* Global Heaps */ #include <H5MMprivate.h> /* Memory Management */ #include <H5Rprivate.h> /* References */ #include <H5Sprivate.h> /* 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; u<H5R_DSET_REG_REF_BUF_SIZE; u++) + if(ref->heapid[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_type<H5R_MAXTYPE); + assert(dset); - /* - * Switch on object type, when we implement that feature, always try to - * open a dataset for now - */ /* Initialize the symbol table entry */ HDmemset(&ent,0,sizeof(H5G_entry_t)); ent.type=H5G_NOTHING_CACHED; ent.file=H5D_get_file(dset); - p=(uint8_t *)ref->oid; - 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 */ |