summaryrefslogtreecommitdiffstats
path: root/src/H5R.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5R.c')
-rw-r--r--src/H5R.c189
1 files changed, 159 insertions, 30 deletions
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 <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 */