From 7320ccac2d5b254cf77bf4a45c35804c9a4c9ec0 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 6 Feb 2007 15:03:06 -0500 Subject: [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) --- src/H5A.c | 96 ++++++++++++++++- src/H5Apkg.h | 2 +- src/H5Apublic.h | 14 ++- src/H5FDmulti.c | 1 - src/H5FDstdio.c | 6 ++ src/H5Lpublic.h | 2 +- src/H5O.c | 5 + src/H5Oattr.c | 16 +-- src/H5Oattribute.c | 8 +- src/H5Ocache.c | 2 +- src/H5Omessage.c | 49 +++++++-- src/H5Opkg.h | 13 ++- src/H5Oprivate.h | 3 - src/H5Opublic.h | 3 + src/H5Otest.c | 142 ++++++++++++++++++++++++- src/H5Pocpl.c | 4 +- test/links.c | 4 +- test/tattr.c | 301 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 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 */ -- cgit v0.12