summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-02-06 20:03:06 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-02-06 20:03:06 (GMT)
commit7320ccac2d5b254cf77bf4a45c35804c9a4c9ec0 (patch)
tree35f836d65184a72e96c1f765853e0a2ae4cf59a7
parentaffdaa04b57c6c598580fa615d64a7680fbda2e8 (diff)
downloadhdf5-7320ccac2d5b254cf77bf4a45c35804c9a4c9ec0.zip
hdf5-7320ccac2d5b254cf77bf4a45c35804c9a4c9ec0.tar.gz
hdf5-7320ccac2d5b254cf77bf4a45c35804c9a4c9ec0.tar.bz2
[svn-r13248] Description:
More progress on creation order for attribbutes - they are now basically working for "compact" attribute storage. Tested on: FreeBSD/32 6.2 (duty) Mac OS X/32 10.4.8 (amazon)
-rw-r--r--src/H5A.c96
-rw-r--r--src/H5Apkg.h2
-rw-r--r--src/H5Apublic.h14
-rw-r--r--src/H5FDmulti.c1
-rw-r--r--src/H5FDstdio.c6
-rw-r--r--src/H5Lpublic.h2
-rw-r--r--src/H5O.c5
-rw-r--r--src/H5Oattr.c16
-rw-r--r--src/H5Oattribute.c8
-rw-r--r--src/H5Ocache.c2
-rw-r--r--src/H5Omessage.c49
-rw-r--r--src/H5Opkg.h13
-rw-r--r--src/H5Oprivate.h3
-rw-r--r--src/H5Opublic.h3
-rw-r--r--src/H5Otest.c142
-rwxr-xr-xsrc/H5Pocpl.c4
-rw-r--r--test/links.c4
-rw-r--r--test/tattr.c301
18 files changed, 626 insertions, 45 deletions
diff --git a/src/H5A.c b/src/H5A.c
index ac41152..c980d06 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -74,6 +74,7 @@ static H5A_t *H5A_open_by_name(const H5G_loc_t *loc, const char *name,
static herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id);
static herr_t H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id);
static hsize_t H5A_get_storage_size(const H5A_t *attr);
+static herr_t H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo);
/*********************/
@@ -1106,7 +1107,7 @@ done:
hid_t
H5Aget_create_plist(hid_t attr_id)
{
- H5A_t *attr = NULL;
+ H5A_t *attr; /* Attribute object for ID */
H5P_genplist_t *plist; /* Default property list */
hid_t new_plist_id; /* ID of ACPL to return */
H5P_genplist_t *new_plist; /* ACPL to return */
@@ -1164,7 +1165,7 @@ done:
ssize_t
H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
{
- H5A_t *attr = NULL;
+ H5A_t *attr; /* Attribute object for ID */
size_t copy_len, nbytes;
ssize_t ret_value;
@@ -1220,7 +1221,7 @@ done:
hsize_t
H5Aget_storage_size(hid_t attr_id)
{
- H5A_t *attr = NULL;
+ H5A_t *attr; /* Attribute object for ID */
hsize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Aget_storage_size, 0)
@@ -1271,6 +1272,93 @@ H5A_get_storage_size(const H5A_t *attr)
/*-------------------------------------------------------------------------
+ * Function: H5Aget_info
+ *
+ * Purpose: Retrieve information about an attribute.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * February 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Aget_info(hid_t loc_id, const char *name, H5A_info_t *ainfo)
+{
+ H5G_loc_t loc; /* Object location */
+ H5A_t *attr = NULL; /* Attribute object for name */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Aget_info, FAIL)
+
+ /* Check args */
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ if(NULL == ainfo)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid info pointer")
+
+ /* Open the attribute on the object header */
+ if(NULL == (attr = H5A_open_by_name(&loc, name, H5AC_ind_dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
+
+ /* Get the attribute information */
+ if(H5A_get_info(attr, ainfo) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
+
+done:
+ /* Cleanup on failure */
+ if(attr && H5A_close(attr) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Aget_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_get_info
+ *
+ * Purpose: Retrieve information about an attribute.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * February 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_get_info)
+
+ /* Check args */
+ HDassert(attr);
+ HDassert(ainfo);
+
+ /* Set info for attribute */
+ ainfo->cset = attr->encoding;
+ ainfo->data_size = attr->data_size;
+ if(attr->crt_idx == H5O_MAX_CRT_ORDER_IDX) {
+ ainfo->corder_valid = FALSE;
+ ainfo->corder = 0;
+ } /* end if */
+ else {
+ ainfo->corder_valid = TRUE;
+ ainfo->corder = attr->crt_idx;
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5A_get_info() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Arename
*
* Purpose: Rename an attribute
@@ -1450,7 +1538,7 @@ H5Aclose(hid_t attr_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/* Decrement references to that atom (and close it) */
- if(H5I_dec_ref (attr_id) < 0)
+ if(H5I_dec_ref(attr_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute")
done:
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 7f95a70..eb2b11f 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -71,7 +71,7 @@ struct H5A_t {
size_t ds_size; /* Size of dataspace on disk */
void *data; /* Attribute data (on a temporary basis) */
size_t data_size; /* Size of data on disk */
- H5O_crt_idx_t crt_idx; /* Attribute's creation index in the object header */
+ H5O_msg_crt_idx_t crt_idx; /* Attribute's creation index in the object header */
};
/* Typedefs for "dense" attribute storage */
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index 21545ae..804ddea 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -19,12 +19,23 @@
#define _H5Apublic_H
/* Public headers needed by this file */
-#include "H5Ipublic.h"
+#include "H5Ipublic.h" /* IDs */
+#include "H5Opublic.h" /* Object Headers */
+#include "H5Tpublic.h" /* Datatypes */
#ifdef __cplusplus
extern "C" {
#endif
+/* Information struct for attribute (for H5Aget_info/H5Aget_info_by_idx) */
+typedef struct {
+ hbool_t corder_valid; /* Indicate if creation order is valid */
+ H5O_msg_crt_idx_t corder; /* Creation order */
+ H5T_cset_t cset; /* Character set of attribute name */
+ hsize_t data_size; /* Size of raw data */
+} H5A_info_t;
+
+/* Typedef for H5Aiterate() callback */
typedef herr_t (*H5A_operator_t)(hid_t location_id/*in*/,
const char *attr_name/*in*/, void *operator_data/*in,out*/);
@@ -41,6 +52,7 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id);
H5_DLL hid_t H5Aget_create_plist(hid_t attr_id);
H5_DLL ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf);
H5_DLL hsize_t H5Aget_storage_size(hid_t attr_id);
+H5_DLL herr_t H5Aget_info(hid_t loc_id, const char *name, H5A_info_t *ainfo /*out*/);
H5_DLL herr_t H5Arename(hid_t loc_id, const char *old_name, const char *new_name);
H5_DLL herr_t H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op,
void *op_data);
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index 6131db1..c1d4de9 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -1503,7 +1503,6 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type)
if (HADDR_UNDEF==eoa)
H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eoa", HADDR_UNDEF)
} else if (file->fa.relax) {
-int i;
/*
* The member is not open yet (maybe it doesn't exist). Make the
* best guess about the end-of-file.
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index 32466bc..9a3aff1 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -554,6 +554,9 @@ H5FD_stdio_get_eoa(const H5FD_t *_file, H5FD_mem_t /*unused*/ type)
/* Clear the error stack */
H5Eclear_stack(H5E_DEFAULT);
+ /* Shut compiler up */
+ type = type;
+
return(file->eoa);
}
@@ -588,6 +591,9 @@ H5FD_stdio_set_eoa(H5FD_t *_file, H5FD_mem_t /*unused*/ type, haddr_t addr)
/* Clear the error stack */
H5Eclear_stack(H5E_DEFAULT);
+ /* Shut compiler up */
+ type = type;
+
file->eoa = addr;
return(0);
diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h
index 42f5667..1029f0b 100644
--- a/src/H5Lpublic.h
+++ b/src/H5Lpublic.h
@@ -71,7 +71,7 @@ typedef enum {
#define H5L_TYPE_BUILTIN_MAX H5L_TYPE_SOFT /* Maximum value link value for "built-in" link types */
#define H5L_TYPE_UD_MIN H5L_TYPE_EXTERNAL /* Link ids at or above this value are "user-defined" link types. */
-/* Buffer for user query function */
+/* Information struct for link (for H5Lget_info/H5Lget_info_by_idx) */
typedef struct {
H5L_type_t type; /* Type of link */
hbool_t corder_valid; /* Indicate if creation order is valid */
diff --git a/src/H5O.c b/src/H5O.c
index 403639a..acba9dd 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -1934,10 +1934,15 @@ H5O_get_create_plist(const H5O_loc_t *oloc, hid_t dxpl_id, H5P_genplist_t *oc_pl
/* Set property values, if they were used for the object */
if(oh->version > H5O_VERSION_1) {
+ /* Set attribute storage values */
if(H5P_set(oc_plist, H5O_CRT_ATTR_MAX_COMPACT_NAME, &oh->max_compact) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set max. # of compact attributes in property list")
if(H5P_set(oc_plist, H5O_CRT_ATTR_MIN_DENSE_NAME, &oh->min_dense) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set min. # of dense attributes in property list")
+
+ /* Set object header flags */
+ if(H5P_set(oc_plist, H5O_CRT_OHDR_FLAGS_NAME, &oh->flags) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set object header flags")
} /* end if */
done:
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index ad617aa..5929769 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -38,8 +38,8 @@ static herr_t H5O_attr_pre_copy_file(H5F_t *file_src, const void *mesg_src,
static void *H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
void *native_src, H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info,
void *udata);
-static herr_t H5O_attr_get_crt_index(const void *_mesg, H5O_crt_idx_t *crt_idx);
-static herr_t H5O_attr_set_crt_index(void *_mesg, H5O_crt_idx_t crt_idx);
+static herr_t H5O_attr_get_crt_index(const void *_mesg, H5O_msg_crt_idx_t *crt_idx);
+static herr_t H5O_attr_set_crt_index(void *_mesg, H5O_msg_crt_idx_t crt_idx);
static herr_t H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -943,19 +943,19 @@ H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *mesg_type,
done:
if(buf_sid > 0)
if(H5I_dec_ref(buf_sid) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, NULL, "Can't decrement temporary dataspace ID")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary dataspace ID")
if(tid_src > 0)
/* Don't decrement ID, we want to keep underlying datatype */
if(H5I_remove(tid_src) == NULL)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
if(tid_dst > 0)
/* Don't decrement ID, we want to keep underlying datatype */
if(H5I_remove(tid_dst) == NULL)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
if(tid_mem > 0)
/* Decrement the memory datatype ID, it's transient */
if(H5I_dec_ref(tid_mem) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "Can't decrement temporary datatype ID")
if(buf)
buf = H5FL_BLK_FREE(attr_buf, buf);
if(reclaim_buf)
@@ -984,7 +984,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_attr_get_crt_index(const void *_mesg, H5O_crt_idx_t *crt_idx /*out*/)
+H5O_attr_get_crt_index(const void *_mesg, H5O_msg_crt_idx_t *crt_idx /*out*/)
{
const H5A_t *attr = (const H5A_t *)_mesg;
@@ -1014,7 +1014,7 @@ H5O_attr_get_crt_index(const void *_mesg, H5O_crt_idx_t *crt_idx /*out*/)
*-------------------------------------------------------------------------
*/
herr_t
-H5O_attr_set_crt_index(void *_mesg, H5O_crt_idx_t crt_idx)
+H5O_attr_set_crt_index(void *_mesg, H5O_msg_crt_idx_t crt_idx)
{
H5A_t *attr = (H5A_t *)_mesg;
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index a616943..9a7e352 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -240,15 +240,17 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
/* Increment attribute count */
oh->nattrs++;
- /* Check if the object is tracking creation order on attributes */
- if(oh->flags & H5P_CRT_ORDER_TRACKED) {
+ /* Later versions of the object header track the creation index on all messages */
+ if(oh->version > H5O_VERSION_1) {
/* Check for attribute creation order index on the object wrapping around */
if(oh->max_attr_crt_idx == H5O_MAX_CRT_ORDER_IDX)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINC, FAIL, "Attribute creation index can't be incremented")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINC, FAIL, "attribute creation index can't be incremented")
/* Set the creation order index on the attribute & incr. creation order index */
attr->crt_idx = oh->max_attr_crt_idx++;
} /* end if */
+ else
+ attr->crt_idx = H5O_MAX_CRT_ORDER_IDX;
/* Check for storing attribute with dense storage */
if(H5F_addr_defined(oh->attr_fheap_addr)) {
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index 64f23d5..878faf8 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -418,7 +418,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
size_t mesg_size; /* Size of message read in */
unsigned id; /* ID (type) of current message */
uint8_t flags; /* Flags for current message */
- H5O_crt_idx_t crt_idx = 0; /* Creation index for current message */
+ H5O_msg_crt_idx_t crt_idx = H5O_MAX_CRT_ORDER_IDX; /* Creation index for current message */
/* Decode message prefix info */
if(oh->version == H5O_VERSION_1)
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 0a1773b..5cf21ea 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -744,8 +744,6 @@ H5O_msg_count(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Object header to operate on */
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
- int acc; /* Count of the message type found */
- unsigned u; /* Local index variable */
int ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_msg_count, FAIL)
@@ -762,13 +760,8 @@ H5O_msg_count(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
- /* Loop over all messages, counting the ones of the type looked for */
- for(u = acc = 0; u < oh->nmesgs; u++)
- if(oh->mesg[u].type == type)
- acc++;
-
- /* Set return value */
- ret_value = acc;
+ /* Count the messages of the correct type */
+ ret_value = H5O_msg_count_real(oh, type);
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
@@ -779,6 +772,42 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_msg_count_real
+ *
+ * Purpose: Counts the number of messages in an object header which are a
+ * certain type.
+ *
+ * Return: Success: Number of messages of specified type.
+ *
+ * Failure: (can't fail)
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, February 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5O_msg_count_real(const H5O_t *oh, const H5O_msg_class_t *type)
+{
+ unsigned u; /* Local index variable */
+ unsigned ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_msg_count_real)
+
+ /* Check args */
+ HDassert(oh);
+ HDassert(type);
+
+ /* Loop over all messages, counting the ones of the type looked for */
+ for(u = ret_value = 0; u < oh->nmesgs; u++)
+ if(oh->mesg[u].type == type)
+ ret_value++;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_msg_count_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_msg_exists
*
* Purpose: Determines if a particular message exists in an object
@@ -843,7 +872,7 @@ done:
*-------------------------------------------------------------------------
*/
htri_t
-H5O_msg_exists_oh(H5O_t *oh, unsigned type_id)
+H5O_msg_exists_oh(const H5O_t *oh, unsigned type_id)
{
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
unsigned u; /* Local index variable */
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index b0c5c01..3b39640 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -196,8 +196,8 @@ struct H5O_msg_class_t {
herr_t (*pre_copy_file)(H5F_t *, const void *, hbool_t *, const H5O_copy_t *, void *); /*"pre copy" action when copying native value to file */
void *(*copy_file)(H5F_t *, void *, H5F_t *, hid_t, H5O_copy_t *, void *); /*copy native value to file */
herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, hid_t, H5O_copy_t *); /*"post copy" action when copying native value to file */
- herr_t (*get_crt_index)(const void *, H5O_crt_idx_t *); /* Get message's creation index */
- herr_t (*set_crt_index)(void *, H5O_crt_idx_t); /* Set message's creation index */
+ herr_t (*get_crt_index)(const void *, H5O_msg_crt_idx_t *); /* Get message's creation index */
+ herr_t (*set_crt_index)(void *, H5O_msg_crt_idx_t); /* Set message's creation index */
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
};
@@ -205,7 +205,7 @@ typedef struct H5O_mesg_t {
const H5O_msg_class_t *type; /*type of message */
hbool_t dirty; /*raw out of date wrt native */
uint8_t flags; /*message flags */
- H5O_crt_idx_t crt_idx; /*message creation index */
+ H5O_msg_crt_idx_t crt_idx; /*message creation index */
unsigned chunkno; /*chunk number for this mesg */
void *native; /*native format message */
uint8_t *raw; /*ptr to raw data */
@@ -245,7 +245,7 @@ struct H5O_t {
hsize_t nattrs; /* Number of attributes in the group */
haddr_t attr_fheap_addr; /* Address of fractal heap for storing "dense" attributes */
haddr_t name_bt2_addr; /* Address of v2 B-tree for indexing names of attributes */
- H5O_crt_idx_t max_attr_crt_idx; /* Maximum attribute creation index used */
+ H5O_msg_crt_idx_t max_attr_crt_idx; /* Maximum attribute creation index used */
/* Message management (stored, encoded in chunks) */
size_t nmesgs; /*number of messages */
@@ -438,7 +438,8 @@ H5_DLL void *H5O_msg_read_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
unsigned type_id, void *mesg);
H5_DLL void *H5O_msg_free_real(const H5O_msg_class_t *type, void *mesg);
H5_DLL herr_t H5O_msg_free_mesg(H5O_mesg_t *mesg);
-H5_DLL htri_t H5O_msg_exists_oh(struct H5O_t *oh, unsigned type_id);
+H5_DLL unsigned H5O_msg_count_real(const H5O_t *oh, const H5O_msg_class_t *type);
+H5_DLL htri_t H5O_msg_exists_oh(const H5O_t *oh, unsigned type_id);
H5_DLL void *H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, hbool_t *shared,
H5O_copy_t *cpy_info, void *udata);
@@ -493,7 +494,9 @@ H5_DLL herr_t H5O_dest(H5F_t *f, H5O_t *oh);
/* Testing functions */
#ifdef H5O_TESTING
+H5_DLL htri_t H5O_is_attr_empty_test(hid_t oid);
H5_DLL htri_t H5O_is_attr_dense_test(hid_t oid);
+H5_DLL herr_t H5O_num_attrs_test(hid_t oid, hsize_t *nattrs);
#endif /* H5O_TESTING */
/* Object header debugging routines */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index a3df7fb..811a048 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -87,9 +87,6 @@ typedef struct H5O_t H5O_t;
/* ========= Object Copy properties ============ */
#define H5O_CPY_OPTION_NAME "copy object" /* Copy options */
-/* Typedef for creation indexes */
-typedef uint32_t H5O_crt_idx_t;
-
/* Fractal heap ID type for shared message & attribute heap IDs. */
typedef uint64_t H5O_fheap_id_t;
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index 9ce8429..67e109f 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -110,6 +110,9 @@ typedef struct H5O_info_t {
/* (B-tree & heap for groups, B-tree for chunked dataset, etc.) */
} H5O_info_t;
+/* Typedef for message creation indexes */
+typedef uint32_t H5O_msg_crt_idx_t;
+
/********************/
/* Public Variables */
diff --git a/src/H5Otest.c b/src/H5Otest.c
index aeab284..b1b0751 100644
--- a/src/H5Otest.c
+++ b/src/H5Otest.c
@@ -22,6 +22,7 @@
/* Module Setup */
/****************/
+#define H5A_PACKAGE /*suppress error about including H5Apkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
#define H5O_TESTING /*suppress warning about H5O testing funcs*/
@@ -30,6 +31,7 @@
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
+#include "H5Apkg.h" /* Attributes */
#include "H5Eprivate.h" /* Error handling */
#include "H5Iprivate.h" /* IDs */
#include "H5Opkg.h" /* Object headers */
@@ -76,7 +78,7 @@
PURPOSE
Determine whether attributes for an object are stored "densely"
USAGE
- htri_t H5O_is_dense_test(oid)
+ htri_t H5O_is_attr_dense_test(oid)
hid_t oid; IN: object to check
RETURNS
Non-negative TRUE/FALSE on success, negative on failure
@@ -107,8 +109,12 @@ H5O_is_attr_dense_test(hid_t oid)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Check if dense storage is being used */
- if(H5F_addr_defined(oh->attr_fheap_addr))
+ if(H5F_addr_defined(oh->attr_fheap_addr)) {
+ /* Check for any messages in object header */
+ HDassert(H5O_msg_count_real(oh, H5O_MSG_ATTR) == 0);
+
ret_value = TRUE;
+ } /* end if */
else
ret_value = FALSE;
@@ -119,4 +125,136 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_is_attr_dense_test() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5O_is_attr_empty_test
+ PURPOSE
+ Determine whether there are any attributes for an object
+ USAGE
+ htri_t H5O_is_attr_empty_test(oid)
+ hid_t oid; IN: object to check
+ RETURNS
+ Non-negative TRUE/FALSE on success, negative on failure
+ DESCRIPTION
+ Checks to see if the object is storing any attributes.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5O_is_attr_empty_test(hid_t oid)
+{
+ H5O_t *oh = NULL; /* Object header */
+ H5O_loc_t *oloc; /* Pointer to object's location */
+ hsize_t nattrs; /* Number of attributes */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_is_attr_empty_test, FAIL)
+
+ /* Get object location for object */
+ if(NULL == (oloc = H5O_get_loc(oid)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
+
+ /* Get the object header */
+ if(NULL == (oh = H5AC_protect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* Retrieve the number of attribute messages in header */
+ nattrs = H5O_msg_count_real(oh, H5O_MSG_ATTR);
+
+ /* Check for later version of object header format */
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for using dense storage */
+ if(H5F_addr_defined(oh->attr_fheap_addr)) {
+ /* Check for any messages in object header */
+ HDassert(nattrs == 0);
+
+ /* Retrieve # of records in name index */
+ if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &nattrs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
+ } /* end if */
+
+ /* Verify that attribute count in object header is correct */
+ HDassert(nattrs == oh->nattrs);
+ } /* end if */
+
+ /* Set the return value */
+ ret_value = (nattrs == 0) ? TRUE : FALSE;
+
+done:
+ if(oh && H5AC_unprotect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_is_attr_empty_test() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5O_num_attrs_test
+ PURPOSE
+ Determine whether there are any attributes for an object
+ USAGE
+ herr_t H5O_num_attrs_test(oid, nattrs)
+ hid_t oid; IN: object to check
+ hsize_t *nattrs; OUT: Number of attributes on object
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Checks the # of attributes on an object
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5O_num_attrs_test(hid_t oid, hsize_t *nattrs)
+{
+ H5O_t *oh = NULL; /* Object header */
+ H5O_loc_t *oloc; /* Pointer to object's location */
+ hsize_t obj_nattrs; /* Number of attributes */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_num_attrs_test, FAIL)
+
+ /* Get object location for object */
+ if(NULL == (oloc = H5O_get_loc(oid)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
+
+ /* Get the object header */
+ if(NULL == (oh = H5AC_protect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* Retrieve the number of attribute messages in header */
+ obj_nattrs = H5O_msg_count_real(oh, H5O_MSG_ATTR);
+
+ /* Check for later version of object header format */
+ if(oh->version > H5O_VERSION_1) {
+ /* Check for using dense storage */
+ if(H5F_addr_defined(oh->attr_fheap_addr)) {
+ /* Check for any messages in object header */
+ HDassert(obj_nattrs == 0);
+
+ /* Retrieve # of records in name index */
+ if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &obj_nattrs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
+ } /* end if */
+
+ /* Verify that attribute count in object header is correct */
+ HDassert(obj_nattrs == oh->nattrs);
+ } /* end if */
+
+ /* Set the number of attributes */
+ *nattrs = obj_nattrs;
+
+done:
+ if(oh && H5AC_unprotect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_num_attrs_test() */
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index 2fa5f47..3917a61 100755
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
@@ -265,7 +265,7 @@ H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "tracking creation order is required for index")
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get object header flags */
@@ -317,7 +317,7 @@ H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags)
*crt_order_flags = 0;
/* Get the plist structure */
- if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE)))
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Get object header flags */
diff --git a/test/links.c b/test/links.c
index 1fd6e15..7d0ff68 100644
--- a/test/links.c
+++ b/test/links.c
@@ -5216,11 +5216,11 @@ corder_create_empty(hid_t fapl)
if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) TEST_ERROR
if(crt_order_flags != 0) TEST_ERROR
- /* Creating a group with onder creation order indexing on should fail */
+ /* Setting invalid combination of a group order creation order indexing on should fail */
H5E_BEGIN_TRY {
ret = H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_INDEXED);
} H5E_END_TRY;
- if(group_id > 0) {
+ if(ret > 0) {
H5_FAILED();
puts(" H5Pset_link_create_order() should have failed for a creation order index with no tracking.");
TEST_ERROR
diff --git a/test/tattr.c b/test/tattr.c
index e4403c8..c877c37 100644
--- a/test/tattr.c
+++ b/test/tattr.c
@@ -1709,7 +1709,7 @@ test_attr_dense_verify(hid_t loc_id, unsigned max_attr)
/* Open attribute */
sprintf(attrname, "attr %02u", u);
attr = H5Aopen_name(loc_id, attrname);
- CHECK(attr, FAIL, "H5Aopen");
+ CHECK(attr, FAIL, "H5Aopen_name");
/* Read data from the attribute */
ret = H5Aread(attr, H5T_NATIVE_UINT, &value);
@@ -1807,6 +1807,10 @@ test_attr_dense_create(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on dataset's attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -1933,6 +1937,10 @@ test_attr_dense_open(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on dataset's attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -2062,6 +2070,10 @@ test_attr_dense_delete(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on dataset's attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -2229,6 +2241,10 @@ test_attr_dense_rename(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on dataset's attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -2383,6 +2399,10 @@ test_attr_dense_unlink(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on dataset's attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -2514,6 +2534,10 @@ test_attr_dense_limits(hid_t fcpl, hid_t fapl)
VERIFY(rmax_compact, max_compact, "H5Pget_attr_phase_change");
VERIFY(rmin_dense, min_dense, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on dataset's attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
@@ -2609,6 +2633,260 @@ test_attr_dense_limits(hid_t fcpl, hid_t fapl)
/****************************************************************
**
+** test_attr_corder_create_empty(): Test basic H5A (attribute) code.
+** Tests basic code to create objects with attribute creation order info
+**
+****************************************************************/
+static void
+test_attr_corder_create_basic(hid_t fcpl, hid_t fapl)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t dataset; /* Dataset ID */
+ hid_t sid; /* Dataspace ID */
+ hid_t dcpl; /* Dataset creation property list ID */
+ unsigned crt_order_flags;/* Creation order flags */
+ htri_t is_empty; /* Are there any attributes? */
+ htri_t is_dense; /* Are attributes stored densely? */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Basic Code for Attributes with Creation Order Info\n"));
+
+ /* Create file */
+ fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create dataset creation property list */
+ dcpl = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(dcpl, FAIL, "H5Pcreate");
+
+ /* Get creation order indexing on object */
+ ret = H5Pget_attr_creation_order(dcpl, &crt_order_flags);
+ CHECK(ret, FAIL, "H5Pget_attr_creation_order");
+ VERIFY(crt_order_flags, 0, "H5Pget_attr_creation_order");
+
+ /* Setting invalid combination of a attribute order creation order indexing on should fail */
+ ret = H5Pset_attr_creation_order(dcpl, H5P_CRT_ORDER_INDEXED);
+ VERIFY(ret, FAIL, "H5Pset_attr_creation_order");
+ ret = H5Pget_attr_creation_order(dcpl, &crt_order_flags);
+ CHECK(ret, FAIL, "H5Pget_attr_creation_order");
+ VERIFY(crt_order_flags, 0, "H5Pget_attr_creation_order");
+
+ /* Set attribute creation order tracking & indexing for object */
+ ret = H5Pset_attr_creation_order(dcpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED));
+ CHECK(ret, FAIL, "H5Pset_attr_creation_order");
+ ret = H5Pget_attr_creation_order(dcpl, &crt_order_flags);
+ CHECK(ret, FAIL, "H5Pget_attr_creation_order");
+ VERIFY(crt_order_flags, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) , "H5Pget_attr_creation_order");
+
+ /* Create dataspace for dataset */
+ sid = H5Screate(H5S_SCALAR);
+ CHECK(sid, FAIL, "H5Screate");
+
+ /* Create a dataset */
+ dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl);
+ CHECK(dataset, FAIL, "H5Dcreate");
+
+ /* Close dataspace */
+ ret = H5Sclose(sid);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Check on dataset's attribute storage status */
+ is_empty = H5O_is_attr_empty_test(dataset);
+ VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test");
+ is_dense = H5O_is_attr_dense_test(dataset);
+ VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+
+ /* Re-open file */
+ fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Open dataset created */
+ dataset = H5Dopen(fid, DSET1_NAME);
+ CHECK(dataset, FAIL, "H5Dopen");
+
+ /* Check on dataset's attribute storage status */
+ is_empty = H5O_is_attr_empty_test(dataset);
+ VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test");
+ is_dense = H5O_is_attr_dense_test(dataset);
+ VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
+
+ /* Retrieve dataset creation property list for group */
+ dcpl = H5Dget_create_plist(dataset);
+ CHECK(dcpl, FAIL, "H5Dget_create_plist");
+
+ /* Query the attribute creation properties */
+ ret = H5Pget_attr_creation_order(dcpl, &crt_order_flags);
+ CHECK(ret, FAIL, "H5Pget_link_creation_order");
+ VERIFY(crt_order_flags, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) , "H5Pget_attr_creation_order");
+
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Close file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* test_attr_corder_create_basic() */
+
+/****************************************************************
+**
+** test_attr_corder_create_compact(): Test basic H5A (attribute) code.
+** Tests compact attribute storage on objects with attribute creation order info
+**
+****************************************************************/
+static void
+test_attr_corder_create_compact(hid_t fcpl, hid_t fapl)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t dataset; /* Dataset ID */
+ hid_t sid; /* Dataspace ID */
+ hid_t attr; /* Attribute ID */
+ hid_t dcpl; /* Dataset creation property list ID */
+ unsigned max_compact; /* Maximum # of links to store in group compactly */
+ unsigned min_dense; /* Minimum # of links to store in group "densely" */
+ htri_t is_empty; /* Are there any attributes? */
+ htri_t is_dense; /* Are attributes stored densely? */
+ hsize_t nattrs; /* Number of attributes on object */
+ char attrname[NAME_BUF_SIZE]; /* Name of attribute */
+ unsigned u; /* Local index variable */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Compact Storage of Attributes with Creation Order Info\n"));
+
+ /* Create file */
+ fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create dataset creation property list */
+ dcpl = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(dcpl, FAIL, "H5Pcreate");
+
+ /* Set attribute creation order tracking & indexing for object */
+ ret = H5Pset_attr_creation_order(dcpl, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED));
+ CHECK(ret, FAIL, "H5Pset_attr_creation_order");
+
+ /* Create dataspace for dataset & attributes */
+ sid = H5Screate(H5S_SCALAR);
+ CHECK(sid, FAIL, "H5Screate");
+
+ /* Create a dataset */
+ dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl);
+ CHECK(dataset, FAIL, "H5Dcreate");
+
+ /* Check on dataset's attribute storage status */
+ is_empty = H5O_is_attr_empty_test(dataset);
+ VERIFY(is_empty, TRUE, "H5O_is_attr_empty_test");
+ is_dense = H5O_is_attr_dense_test(dataset);
+ VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
+
+ /* Query the attribute creation properties */
+ ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
+ CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+
+ /* Create several attributes, but keep storage in compact form */
+ for(u = 0; u < max_compact; u++) {
+ /* Create attribute */
+ sprintf(attrname, "attr %02u", u);
+ attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT);
+ CHECK(attr, FAIL, "H5Acreate");
+
+ /* Write data into the attribute */
+ ret = H5Awrite(attr, H5T_NATIVE_UINT, &u);
+ CHECK(ret, FAIL, "H5Awrite");
+
+ /* Close attribute */
+ ret = H5Aclose(attr);
+ CHECK(ret, FAIL, "H5Aclose");
+
+ /* Verify state of object */
+ ret = H5O_num_attrs_test(dataset, &nattrs);
+ CHECK(ret, FAIL, "H5O_num_attrs_test");
+ VERIFY(nattrs, (u + 1), "H5O_num_attrs_test");
+ is_empty = H5O_is_attr_empty_test(dataset);
+ VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test");
+ is_dense = H5O_is_attr_dense_test(dataset);
+ VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
+ } /* end for */
+
+ /* Close dataspace */
+ ret = H5Sclose(sid);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+
+ /* Re-open file */
+ fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Open dataset created */
+ dataset = H5Dopen(fid, DSET1_NAME);
+ CHECK(dataset, FAIL, "H5Dopen");
+
+ /* Check on dataset's attribute storage status */
+ ret = H5O_num_attrs_test(dataset, &nattrs);
+ CHECK(ret, FAIL, "H5O_num_attrs_test");
+ VERIFY(nattrs, max_compact, "H5O_num_attrs_test");
+ is_empty = H5O_is_attr_empty_test(dataset);
+ VERIFY(is_empty, FALSE, "H5O_is_attr_empty_test");
+ is_dense = H5O_is_attr_dense_test(dataset);
+ VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
+
+ /* Loop through attributes, checking their creation order values */
+ /* (the name index is used, but the creation order value is in the same order) */
+ for(u = 0; u < max_compact; u++) {
+ H5A_info_t ainfo; /* Attribute information */
+
+ /* Retrieve information for attribute */
+ sprintf(attrname, "attr %02u", u);
+ ret = H5Aget_info(dataset, attrname, &ainfo);
+ CHECK(ret, FAIL, "H5Aget_info");
+
+ /* Verify creation order of attribute */
+ VERIFY(ainfo.corder_valid, TRUE, "H5Aget_info");
+ VERIFY(ainfo.corder, u, "H5Aget_info");
+ } /* end for */
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Close file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* test_attr_corder_create_compact() */
+
+/****************************************************************
+**
** test_attr_shared_write(): Test basic H5A (attribute) code.
** Tests writing mix of shared & un-shared attributes in "compact" & "dense" storage
**
@@ -2752,6 +3030,10 @@ test_attr_shared_write(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on datasets' attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -3077,6 +3359,10 @@ test_attr_shared_rename(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on datasets' attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -3517,6 +3803,10 @@ test_attr_shared_delete(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on datasets' attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -3880,6 +4170,10 @@ test_attr_shared_unlink(hid_t fcpl, hid_t fapl)
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");
+ /* Close property list */
+ ret = H5Pclose(dcpl);
+ CHECK(ret, FAIL, "H5Pclose");
+
/* Check on datasets' attribute storage status */
is_dense = H5O_is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test");
@@ -4182,12 +4476,17 @@ test_attr(void)
my_fcpl = fcpl;
} /* end else */
+ /* General attribute tests */
test_attr_dense_create(my_fcpl, fapl2); /* Test dense attribute storage creation */
test_attr_dense_open(my_fcpl, fapl2); /* Test opening attributes in dense storage */
test_attr_dense_delete(my_fcpl, fapl2); /* Test deleting attributes in dense storage */
test_attr_dense_rename(my_fcpl, fapl2); /* Test renaming attributes in dense storage */
test_attr_dense_unlink(my_fcpl, fapl2); /* Test unlinking object with attributes in dense storage */
test_attr_dense_limits(my_fcpl, fapl2); /* Test dense attribute storage limits */
+
+ /* Attribute creation order tests */
+ test_attr_corder_create_basic(my_fcpl, fapl2); /* Test creating an object w/attribute creation order info */
+ test_attr_corder_create_compact(my_fcpl, fapl2); /* Test compact attribute storage on an object w/attribute creation order info */
} /* end for */
/* More complex tests with both "new format" and "shared" attributes */