summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJerome Soumagne <jsoumagne@hdfgroup.org>2015-09-28 01:15:20 (GMT)
committerJerome Soumagne <jsoumagne@hdfgroup.org>2016-11-29 23:42:31 (GMT)
commitf5324cdd959149816ddca13adad121c3be5bb64f (patch)
tree211c0c079cd8adf6b7217110b72f01bc18bb9bbf /src
parentdcc46c56f6cdbfebbf33fbf48d82931d5d0b60a2 (diff)
downloadhdf5-f5324cdd959149816ddca13adad121c3be5bb64f.zip
hdf5-f5324cdd959149816ddca13adad121c3be5bb64f.tar.gz
hdf5-f5324cdd959149816ddca13adad121c3be5bb64f.tar.bz2
Modify attribute references to use variable length ref type
Clean up H5R
Diffstat (limited to 'src')
-rw-r--r--src/H5D.c43
-rw-r--r--src/H5Dint.c41
-rw-r--r--src/H5Dprivate.h4
-rw-r--r--src/H5Dpublic.h1
-rw-r--r--src/H5R.c182
-rw-r--r--src/H5Rpublic.h16
-rw-r--r--src/H5T.c27
-rw-r--r--src/H5Tconv.c4
-rw-r--r--src/H5Tprivate.h1
-rw-r--r--src/H5Tref.c159
10 files changed, 331 insertions, 147 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 475b828..715358a 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -738,6 +738,49 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Diterate() */
+/*-------------------------------------------------------------------------
+ * Function: H5Dref_reclaim
+ *
+ * Purpose: Frees the buffers allocated for storing variable-length reference
+ * in memory. Only frees the VL data in the selection defined in the
+ * dataspace. The dataset transfer property list is required to find the
+ * correct allocation/free methods for the VL data in the buffer.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dref_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
+{
+ H5S_t *space; /* Dataspace for iteration */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "iii*x", type_id, space_id, plist_id, buf);
+
+ /* Check args */
+ if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
+ if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
+ if(!(H5S_has_extent(space)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if(H5P_DEFAULT == plist_id)
+ plist_id = H5P_DATASET_XFER_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
+
+ /* Call internal routine */
+ ret_value = H5D_ref_reclaim(type_id, space, plist_id, buf);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dref_reclaim() */
+
/*-------------------------------------------------------------------------
* Function: H5Dvlen_reclaim
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 7d18005..f3927e2 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -2184,6 +2184,47 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__get_offset() */
+/*-------------------------------------------------------------------------
+ * Function: H5D_ref_reclaim
+ *
+ * Purpose: Frees the buffers allocated for storing variable-length reference
+ * in memory. Only frees the VL data in the selection defined in the
+ * dataspace. The dataset transfer property list is required to find the
+ * correct allocation/free methods for the VL data in the buffer.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_ref_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, void *buf)
+{
+ H5T_t *type; /* Datatype */
+ H5S_sel_iter_op_t dset_op; /* Operator for iteration */
+ herr_t ret_value = FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(H5I_DATATYPE == H5I_get_type(type_id));
+ HDassert(space);
+ HDassert(H5P_isa_class(plist_id, H5P_DATASET_XFER));
+ HDassert(buf);
+
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
+
+ /* Call H5S_select_iterate with args, etc. */
+ dset_op.op_type = H5S_SEL_ITER_OP_APP;
+ dset_op.u.app_op.op = H5T_ref_reclaim;
+ dset_op.u.app_op.type_id = type_id;
+
+ ret_value = H5S_select_iterate(buf, type, space, &dset_op, NULL);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_ref_reclaim() */
+
/*-------------------------------------------------------------------------
* Function: H5D_vlen_reclaim
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index 983ca71..121da08 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -188,6 +188,10 @@ H5_DLL herr_t H5D_get_index_size(H5D_t *dset, hsize_t *idx_size);
H5_DLL H5S_t *H5D_query(H5D_t *dset, const H5S_t *file_space, const H5Q_t *query,
hid_t xapl_id, hid_t xxpl_id);
+/* Functions that operate on reference data */
+H5_DLL herr_t H5D_ref_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
+ void *buf);
+
/* Functions that operate on vlen data */
H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
void *buf);
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index 8cbba89..f62e38c 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -144,6 +144,7 @@ H5_DLL herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
hid_t file_space_id, hid_t plist_id, const void *buf);
H5_DLL herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id,
H5D_operator_t op, void *operator_data);
+H5_DLL herr_t H5Dref_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf);
H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf);
H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size);
H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
diff --git a/src/H5R.c b/src/H5R.c
index fbed9f1..59b1250 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -415,13 +415,10 @@ H5R_create(void *_ref, H5R_type_t ref_type, ...)
H5G_loc_t *loc;
const char *name;
hid_t dxpl_id;
- H5HG_t hobjid; /* Heap object ID */
hattr_ref_t *ref = (hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */
- size_t buf_size; /* Size of buffer needed to serialize selection */
+ size_t buf_size; /* Size of buffer needed to serialize attribute */
size_t attr_name_len; /* Length of the attribute name */
uint8_t *p; /* Pointer to OID to store */
- hbool_t heapid_found; /* Flag for non-zero heap ID found */
- unsigned u; /* local index */
const char *attr_name;
/* Get arguments */
@@ -440,25 +437,6 @@ H5R_create(void *_ref, H5R_type_t ref_type, ...)
HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found")
obj_found = TRUE;
- /* Set up information for attribute */
-
- /* Return any previous heap block to the free list if we are garbage collecting */
- if(H5F_GC_REF(loc->oloc->file)) {
- /* Check for an existing heap ID in the reference */
- for(u = 0, heapid_found = FALSE, p = (uint8_t *)ref; u < H5R_ATTR_REF_BUF_SIZE; u++)
- if(p[u] != 0) {
- heapid_found = TRUE;
- break;
- } /* end if */
-
- if(heapid_found) {
-/* 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, 0, H5R_ATTR_REF_BUF_SIZE);
-
/* Get the amount of space required to serialize the attribute name */
attr_name_len = HDstrlen(attr_name);
if(attr_name_len >= H5R_MAX_ATTR_REF_NAME_LEN)
@@ -468,33 +446,24 @@ H5R_create(void *_ref, H5R_type_t ref_type, ...)
buf_size = attr_name_len + 2 + sizeof(haddr_t);
/* Allocate the space to store the serialized information */
- if(NULL == (buf = (uint8_t *)H5MM_malloc(buf_size)))
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "memory allocation failed")
-
- /* Serialize information for object's OID into heap buffer */
- p = (uint8_t *)buf;
- H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);
-
- /* Serialize information for attribute name length into the buffer */
- UINT16ENCODE(p, attr_name_len);
-
- /* Copy the attribute name into the buffer */
- HDmemcpy(p, attr_name, attr_name_len);
+ if(!ref->buf || ref->buf_size < buf_size) {
+ ref->buf_size = buf_size;
+ } else {
+ /* Serialize information for object's OID into buffer */
+ p = (uint8_t *)ref->buf;
+ H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);
- /* Sanity check */
- HDassert((size_t)((p + attr_name_len) - buf) == buf_size);
+ /* Serialize information for attribute name length into the buffer */
+ UINT16ENCODE(p, attr_name_len);
- /* Save the serialized buffer for later */
- if(H5HG_insert(loc->oloc->file, dxpl_id, buf_size, buf, &hobjid) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection")
+ /* Copy the attribute name into the buffer */
+ HDmemcpy(p, attr_name, attr_name_len);
- /* Serialize the heap ID and index for storage in the file */
- p = (uint8_t *)ref;
- H5F_addr_encode(loc->oloc->file, &p, hobjid.addr);
- UINT32ENCODE(p, hobjid.idx);
-
- break;
+ /* Sanity check */
+ HDassert((size_t)((p + attr_name_len) - (uint8_t *)ref->buf) == buf_size);
+ }
}
+ break;
case H5R_BADTYPE:
case H5R_MAXTYPE:
@@ -726,27 +695,25 @@ H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type,
} /* end case */
break;
- case H5R_ATTR:
+ case H5R_REGION:
{
- H5HG_t hobjid; /* Heap object ID */
- uint8_t *buf; /* Buffer to store serialized selection in */
- const uint8_t *p; /* Pointer to OID to store */
- size_t attr_name_len; /* Length of the attribute name */
-
- /* Get the heap ID for the dataset region */
- p = (const uint8_t *)_ref;
- H5F_addr_decode(oloc.file, &p, &(hobjid.addr));
- UINT32DECODE(p, hobjid.idx);
+ const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ const uint8_t *p; /* Pointer to OID to store */
- if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer")
+ /* Get the object oid for the dataset */
+ p = (const uint8_t *)ref->buf;
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ } /* end case */
+ break;
- /* Get the dataset region from the heap (allocate inside routine) */
- if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)))
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
+ case H5R_ATTR:
+ {
+ const hattr_ref_t *ref = (const hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ const uint8_t *p; /* Pointer to OID to store */
+ size_t attr_name_len; /* Length of the attribute name */
/* Get the object oid for the dataset */
- p = buf;
+ p = (const uint8_t *)ref->buf;
H5F_addr_decode(oloc.file, &p, &(oloc.addr));
/* Get the attribute name length */
@@ -760,20 +727,6 @@ H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type,
/* Get the attribute name */
HDmemcpy(attr_name, p, attr_name_len);
attr_name[attr_name_len] = '\0';
-
- /* Free the buffer allocated in H5HG_read() */
- H5MM_xfree(buf);
- } /* end case */
- break;
-
- case H5R_REGION:
- {
- const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
- const uint8_t *p; /* Pointer to OID to store */
-
- /* Get the object oid for the dataset */
- p = (const uint8_t *)ref->buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
} /* end case */
break;
@@ -875,8 +828,7 @@ H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type,
} /* end else */
done:
- if(attr_name)
- H5MM_xfree(attr_name);
+ H5MM_xfree(attr_name);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5R_dereference() */
@@ -1139,27 +1091,27 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type,
break;
} /* end case */
- case H5R_ATTR:
+ case H5R_REGION:
{
- H5HG_t hobjid; /* Heap object ID */
+ const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
const uint8_t *p; /* Pointer to reference to decode */
- uint8_t *buf; /* Buffer to store serialized selection in */
- /* Get the heap ID for the dataset region */
- p = (const uint8_t *)_ref;
- H5F_addr_decode(oloc.file, &p, &(hobjid.addr));
- UINT32DECODE(p, hobjid.idx);
+ /* Get the object oid for the dataset */
+ p = (const uint8_t *)ref->buf;
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
- /* Get the dataset region from the heap (allocate inside routine) */
- if((buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL)
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read attribute reference information")
+ break;
+ } /* end case */
+
+ case H5R_ATTR:
+ {
+ const hattr_ref_t *ref = (const hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ const uint8_t *p; /* Pointer to reference to decode */
/* Get the object oid for the dataset */
- p = buf;
+ p = (const uint8_t *)ref->buf;
H5F_addr_decode(oloc.file, &p, &(oloc.addr));
- /* Free the buffer allocated in H5HG_read() */
- H5MM_xfree(buf);
break;
} /* end case */
@@ -1305,10 +1257,40 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty
H5MM_xfree(buf);
} /* end case */
break;
+
+ case H5R_REGION:
+ {
+ const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ const uint8_t *p; /* Pointer to reference to decode */
+
+ /* Get the object oid for the dataset */
+ p = (const uint8_t *)ref->buf;
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+
+ } /* end case */
+ break;
+
case H5R_ATTR:
{
- /* TODO */
- }
+ const hattr_ref_t *ref = (const hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ const uint8_t *p; /* Pointer to OID to store */
+ size_t attr_name_len; /* Length of the attribute name */
+ size_t copy_len;
+
+ /* Get the object oid for the dataset */
+ p = (const uint8_t *)ref->buf;
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+
+ /* Get the attribute name length */
+ UINT16DECODE(p, attr_name_len);
+ HDassert(attr_name_len < H5R_MAX_ATTR_REF_NAME_LEN);
+ copy_len = MIN(attr_name_len, size - 1);
+
+ /* Get the attribute name */
+ HDmemcpy(name, p, copy_len);
+ name[copy_len] = '\0';
+ ret_value = (ssize_t)copy_len;
+ } /* end case */
break;
case H5R_BADTYPE:
case H5R_MAXTYPE:
@@ -1317,13 +1299,15 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
- /* Retrieve file ID for name search */
- if((file_id = H5I_get_file_id(id, FALSE)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID")
+ if (ref_type != H5R_ATTR) {
+ /* Retrieve file ID for name search */
+ if((file_id = H5I_get_file_id(id, FALSE)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID")
- /* Get name, length, etc. */
- if((ret_value = H5G_get_name_by_addr(file_id, lapl_id, dxpl_id, &oloc, name, size)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't determine name")
+ /* Get name, length, etc. */
+ if((ret_value = H5G_get_name_by_addr(file_id, lapl_id, dxpl_id, &oloc, name, size)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't determine name")
+ }
done:
/* Close file ID used for search */
diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h
index 2ee47cf..421b9c2 100644
--- a/src/H5Rpublic.h
+++ b/src/H5Rpublic.h
@@ -53,18 +53,20 @@ typedef haddr_t hobj_ref_t; /* Needs to be large enough to store largest haddr_t
typedef unsigned char hdset_reg_ref_t[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 */
-/* Variable length region reference struct in memory */
-typedef struct hreg_ref_t {
+/* Variable length reference struct in memory */
+struct href_var {
size_t buf_size;/* Size of serialized region reference */
void *buf; /* Pointer to serialized region reference */
-} hreg_ref_t;
+};
+
+typedef struct href_var hreg_ref_t;
#define H5R_REG_REF_INITIALIZER { 0, NULL }
-#define H5R_ATTR_REF_BUF_SIZE (2 * (sizeof(haddr_t) + 4))
-/* Attribute reference structure for user's code */
-typedef unsigned char hattr_ref_t[H5R_ATTR_REF_BUF_SIZE];/* Buffer to store two heap IDs and indices */
-/* Needs to be large enough to store 2x the largest haddr_t in a worst case machine (ie. 8 bytes currently) plus an int */
+/* Attribute reference structure for user's code (variable length) */
+typedef struct href_var hattr_ref_t;
+
+#define H5R_ATTR_REF_INITIALIZER { 0, NULL }
/* Publicly visible data structures */
diff --git a/src/H5T.c b/src/H5T.c
index 54c3974..36c5745 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -239,9 +239,11 @@
dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; \
}
-#define H5T_INIT_TYPE_ATTRREF_CORE { \
- H5T_INIT_TYPE_REF_COMMON \
- dt->shared->u.atomic.u.r.rtype = H5R_ATTR; \
+#define H5T_INIT_TYPE_ATTRREF_CORE { \
+ H5T_INIT_TYPE_REF_COMMON \
+ dt->shared->force_conv = TRUE; \
+ dt->shared->u.atomic.u.r.rtype = H5R_ATTR; \
+ dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; \
}
/* Define the code templates for the "SIZE_TMPL" in the H5T_INIT_TYPE macro */
@@ -736,6 +738,7 @@ H5T__init_package(void)
H5T_t *array=NULL; /* Datatype structure for array objects */
H5T_t *objref=NULL; /* Datatype structure for object reference objects */
H5T_t *regref=NULL; /* Datatype structure for region reference objects */
+ H5T_t *attrref=NULL; /* Datatype structure for attribute reference objects */
hsize_t dim[1]={1}; /* Dimension info for array datatype */
herr_t status;
unsigned copied_dtype=1; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */
@@ -998,11 +1001,15 @@ H5T__init_package(void)
H5T_INIT_TYPE(REGREF, H5T_STD_REF_REG_g, ALLOC, -, NOSET, -)
/* TODO put that in the macro */
if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
regref = dt; /* Keep type for later */
/* Attribute reference (i.e. object and attribute names in file) */
- H5T_INIT_TYPE(ATTRREF, H5T_STD_REF_ATTR_g, ALLOC, -, SET, H5R_ATTR_REF_BUF_SIZE)
+ H5T_INIT_TYPE(ATTRREF, H5T_STD_REF_ATTR_g, ALLOC, -, NOSET, -)
+ /* TODO put that in the macro */
+ if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
+ attrref = dt; /* Keep type for later */
/*
* Register conversion functions beginning with the most general and
@@ -1039,6 +1046,7 @@ H5T__init_package(void)
status |= H5T_register(H5T_PERS_SOFT, "array", array, array, H5T__conv_array, H5AC_ind_dxpl_id, FALSE);
status |= H5T_register(H5T_PERS_SOFT, "objref", objref, objref, H5T__conv_order_opt, H5AC_ind_dxpl_id, FALSE);
status |= H5T_register(H5T_PERS_SOFT, "regref", regref, regref, H5T__conv_ref, H5AC_ind_dxpl_id, FALSE);
+ status |= H5T_register(H5T_PERS_SOFT, "attrref", attrref, attrref, H5T__conv_ref, H5AC_ind_dxpl_id, FALSE);
/*
* Native conversions should be listed last since we can use hardware to
@@ -4355,8 +4363,10 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset)
break;
case H5R_REGION:
- /* Does this need more to distinguish it? -QAK 8/25/15 */
- /*void */
+ if (dt1->shared->u.atomic.u.r.loc < dt2->shared->u.atomic.u.r.loc)
+ HGOTO_DONE(-1);
+ if (dt1->shared->u.atomic.u.r.loc > dt2->shared->u.atomic.u.r.loc)
+ HGOTO_DONE(1);
break;
case H5R_ATTR:
@@ -5289,7 +5299,8 @@ H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
ret_value=TRUE;
} /* end if */
} /* end if */
- if(dt->shared->u.atomic.u.r.rtype == H5R_REGION) {
+ if((dt->shared->u.atomic.u.r.rtype == H5R_REGION) ||
+ (dt->shared->u.atomic.u.r.rtype == H5R_ATTR)) {
/* Mark this reference */
if((changed = H5T__ref_set_loc(dt, f, loc)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set reference location");
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 622d7a8..534ab99 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -3566,7 +3566,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5T__conv_ref
*
- * Purpose: Converts between region reference datatypes in memory and on disk.
+ * Purpose: Converts between reference datatypes in memory and on disk.
* This is a soft conversion function.
*
* Return: Non-negative on success/Negative on failure
@@ -3622,6 +3622,8 @@ H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if (src->shared->u.atomic.u.r.rtype == H5R_OBJECT) break;
+
/* Initialize source & destination strides */
if(buf_stride) {
HDassert(buf_stride >= src->shared->size);
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index d5250ae..4ed0887 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -141,6 +141,7 @@ H5_DLL htri_t H5T_is_variable_str(const H5T_t *dt);
/* Reference specific functions */
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
+H5_DLL herr_t H5T_ref_reclaim(void *elem, hid_t type_id, unsigned ndim, const hsize_t *point, void *_op_data);
/* Operations on named datatypes */
H5_DLL H5T_t *H5T_open(const H5G_loc_t *loc, hid_t dxpl_id);
diff --git a/src/H5Tref.c b/src/H5Tref.c
index def5cb1..a55c2e4 100644
--- a/src/H5Tref.c
+++ b/src/H5Tref.c
@@ -31,9 +31,11 @@
#include "H5Tpkg.h" /* Datatypes */
/* Local functions */
-static size_t H5T__ref_reg_mem_getsize(const void *_ref);
-static herr_t H5T__ref_reg_mem_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, size_t buf_size);
-static herr_t H5T__ref_reg_mem_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size);
+static herr_t H5T__ref_reclaim_recurse(void *elem, const H5T_t *dt);
+
+static size_t H5T__ref_mem_getsize(const void *_ref);
+static herr_t H5T__ref_mem_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, size_t buf_size);
+static herr_t H5T__ref_mem_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size);
static size_t H5T__ref_disk_getsize(const void *_ref);
static herr_t H5T__ref_disk_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, size_t buf_size);
@@ -75,15 +77,16 @@ H5T__ref_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Mark this type as being stored in memory */
dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY;
- if(dt->shared->u.atomic.u.r.rtype == H5R_REGION) {
+ if((dt->shared->u.atomic.u.r.rtype == H5R_REGION) ||
+ (dt->shared->u.atomic.u.r.rtype == H5R_ATTR)) {
/* size in memory, disk size is different */
- dt->shared->size = sizeof(hreg_ref_t);
+ dt->shared->size = sizeof(struct href_var);
/* Set up the function pointers to access the region
* reference in memory */
- dt->shared->u.atomic.u.r.getsize = H5T__ref_reg_mem_getsize;
- dt->shared->u.atomic.u.r.read = H5T__ref_reg_mem_read;
- dt->shared->u.atomic.u.r.write = H5T__ref_reg_mem_write;
+ dt->shared->u.atomic.u.r.getsize = H5T__ref_mem_getsize;
+ dt->shared->u.atomic.u.r.read = H5T__ref_mem_read;
+ dt->shared->u.atomic.u.r.write = H5T__ref_mem_write;
} else {
HDassert(0 && "Invalid reference type");
}
@@ -133,21 +136,21 @@ done:
} /* end H5T__ref_set_loc() */
/*-------------------------------------------------------------------------
- * Function: H5T__ref_reg_mem_getsize
+ * Function: H5T__ref_mem_getsize
*
- * Purpose: Retrieves the size of a memory based region reference.
+ * Purpose: Retrieves the size of a memory based reference.
*
* Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
static size_t
-H5T__ref_reg_mem_getsize(const void *_ref)
+H5T__ref_mem_getsize(const void *_ref)
{
#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
- const hreg_ref_t *ref = (const hreg_ref_t *)_ref;
+ const struct href_var *ref = (const struct href_var *)_ref;
#else
- hreg_ref_t ref;
+ struct href_var ref;
#endif
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -159,29 +162,29 @@ H5T__ref_reg_mem_getsize(const void *_ref)
FUNC_LEAVE_NOAPI(ref->buf_size)
#else
HDassert(_ref);
- HDmemcpy(&ref, _ref, sizeof(hreg_ref_t));
+ HDmemcpy(&ref, _ref, sizeof(struct href_var));
FUNC_LEAVE_NOAPI(ref.buf_size)
#endif
-} /* end H5T__ref_reg_mem_getsize() */
+} /* end H5T__ref_mem_getsize() */
/*-------------------------------------------------------------------------
- * Function: H5T__ref_reg_mem_read
+ * Function: H5T__ref_mem_read
*
- * Purpose: "Reads" the memory based region reference into a buffer
+ * Purpose: "Reads" the memory based reference into a buffer
*
* Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5T__ref_reg_mem_read(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id,
+H5T__ref_mem_read(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id,
void *_ref, void *buf, size_t buf_size)
{
#ifdef H5_NO_ALIGNMENT_RESTRICTIONS
- const hreg_ref_t *ref = (const hreg_ref_t *)_ref;
+ const struct href_var *ref = (const struct href_var *)_ref;
#else
- hreg_ref_t ref;
+ struct href_var ref;
#endif
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -194,29 +197,29 @@ H5T__ref_reg_mem_read(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id,
HDmemcpy(buf, ref->buf, buf_size);
#else
HDassert(_ref);
- HDmemcpy(&ref, _ref, sizeof(hreg_ref_t));
+ HDmemcpy(&ref, _ref, sizeof(struct href_var));
HDassert(ref.buf);
HDmemcpy(buf, ref.buf, buf_size);
#endif
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5T__ref_reg_mem_read() */
+} /* end H5T__ref_mem_read() */
/*-------------------------------------------------------------------------
- * Function: H5T__ref_reg_mem_write
+ * Function: H5T__ref_mem_write
*
- * Purpose: "Writes" the memory region reference from a buffer
+ * Purpose: "Writes" the memory reference from a buffer
*
* Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5T__ref_reg_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id,
+H5T__ref_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id,
void *_ref, void *buf, void H5_ATTR_UNUSED *_bg, size_t buf_size)
{
- hreg_ref_t ref;
+ struct href_var ref;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -239,16 +242,16 @@ H5T__ref_reg_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id,
ref.buf_size = buf_size;
/* Set pointer in user's buffer with memcpy, to avoid alignment issues */
- HDmemcpy(_ref, &ref, sizeof(hreg_ref_t));
+ HDmemcpy(_ref, &ref, sizeof(struct href_var));
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T__ref_reg_mem_write() */
+} /* end H5T__ref_mem_write() */
/*-------------------------------------------------------------------------
* Function: H5T__ref_disk_getsize
*
- * Purpose: Retrieves the length of a disk based reference element.
+ * Purpose: Retrieves the length of a disk based reference.
*
* Return: Non-negative on success/Negative on failure
*
@@ -273,7 +276,7 @@ H5T__ref_disk_getsize(const void *_ref)
/*-------------------------------------------------------------------------
* Function: H5T__ref_disk_read
*
- * Purpose: Reads the disk based region element into a buffer
+ * Purpose: Reads the disk based reference into a buffer
*
* Return: Non-negative on success/Negative on failure
*
@@ -303,7 +306,7 @@ H5T__ref_disk_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *buf,
/* Check if this sequence actually has any data */
if(hobjid.addr > 0) {
- /* Read the VL information from disk */
+ /* Read the information from disk */
if(H5HG_read(f, dxpl_id, &hobjid, buf, NULL) == NULL)
HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read reference information")
} /* end if */
@@ -315,7 +318,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5T__ref_disk_write
*
- * Purpose: Writes the disk based region element from a buffer
+ * Purpose: Writes the disk based reference from a buffer
*
* Return: Non-negative on success/Negative on failure
*
@@ -372,3 +375,95 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__ref_disk_write() */
+/*-------------------------------------------------------------------------
+ * Function: H5T__ref_reclaim_recurse
+ *
+ * Purpose: Internal recursive routine to free reference datatypes
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5T__ref_reclaim_recurse(void *elem, const H5T_t *dt)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(elem);
+ HDassert(dt);
+
+ /* Check the datatype of this element */
+ switch(dt->shared->type) {
+ case H5T_REFERENCE:
+ if((dt->shared->u.atomic.u.r.rtype == H5R_REGION) ||
+ (dt->shared->u.atomic.u.r.rtype == H5R_ATTR)) {
+ struct href_var *ref = (struct href_var *)elem;
+
+ if(ref->buf_size != 0) {
+ ref->buf = H5MM_xfree(ref->buf);
+ } /* end if */
+ } else {
+ HDassert(0 && "Invalid reference type");
+ } /* end else */
+ break;
+
+ /* Don't do anything for other types */
+ case H5T_ARRAY:
+ case H5T_COMPOUND:
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_TIME:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_ENUM:
+ case H5T_VLEN:
+ break;
+
+ /* Should never have these values */
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES:
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid datatype class")
+ break;
+
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__ref_reclaim_recurse() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T__ref_reclaim
+ *
+ * Purpose: Default method to reclaim any reference data for a buffer element
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_ref_reclaim(void *elem, hid_t type_id, unsigned H5_ATTR_UNUSED ndim, const hsize_t H5_ATTR_UNUSED *point, void H5_ATTR_UNUSED *op_data)
+{
+ H5T_t *dt;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(elem);
+ HDassert(H5I_DATATYPE == H5I_get_type(type_id));
+
+ /* Check args */
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+
+ /* Pull the free function and free info pointer out of the op_data and call the recurse datatype free function */
+ if(H5T__ref_reclaim_recurse(elem, dt) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim reference elements")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_ref_reclaim() */
+