From 12edb97078593e2aa73950919c4823a37367915e Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 30 Oct 2006 09:33:14 -0500 Subject: [svn-r12825] Description: Rudimentary support for creating creation order index (but not inserting links in it yet). Testedon: Mac OS X/32 10.4.8 (amazon) --- src/H5G.c | 30 +++- src/H5Gbtree2.c | 215 ++++++++++++++++++++++++++++- src/H5Gdense.c | 23 +++- src/H5Gobj.c | 15 +- src/H5Gpkg.h | 13 +- src/H5Gprivate.h | 4 + src/H5Gtraverse.c | 15 +- src/H5P.c | 6 + src/H5Pgcpl.c | 85 +++++++++++- src/H5Ppublic.h | 2 + test/links.c | 400 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 11 files changed, 781 insertions(+), 27 deletions(-) diff --git a/src/H5G.c b/src/H5G.c index 25525c9..0edacab 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -888,6 +888,7 @@ hid_t H5Gget_create_plist(hid_t group_id) { htri_t ginfo_exists = 0; + htri_t linfo_exists = 0; H5G_t *grp = NULL; H5P_genplist_t *gcpl_plist; H5P_genplist_t *new_plist; @@ -924,6 +925,21 @@ H5Gget_create_plist(hid_t group_id) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info") } /* end if */ + /* Check for the group having a link info message */ + if((linfo_exists = H5O_exists(&(grp->oloc), H5O_LINFO_ID, 0, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + if(linfo_exists) { + H5O_linfo_t linfo; /* Link info message */ + + /* Read the link info */ + if(NULL == H5O_read(&(grp->oloc), H5O_LINFO_ID, 0, &linfo, H5AC_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info") + + /* Set the link info for the property list */ + if(H5P_set(new_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info") + } /* end if */ + /* Set the return value */ ret_value = new_gcpl_id; @@ -1378,6 +1394,7 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc) if (loc == NULL) { H5P_genplist_t *fc_plist; /* File creation property list */ H5O_ginfo_t ginfo; /* Group info parameters */ + H5O_linfo_t linfo; /* Link info parameters */ /* Get the file creation property list */ /* (Which is a sub-class of the group creation property class) */ @@ -1388,13 +1405,17 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc) if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info") + /* Get the link info property */ + if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") + /* Set up group location for root group */ new_root_loc.oloc = &new_root_oloc; new_root_loc.path = &new_root_path; H5G_loc_reset(&new_root_loc); loc = &new_root_loc; - if(H5G_obj_create(f, dxpl_id, &ginfo, loc->oloc/*out*/) < 0) + if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, loc->oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") if(1 != H5O_link(loc->oloc, 1, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") @@ -1460,6 +1481,7 @@ H5G_create(H5F_t *file, hid_t dxpl_id, hid_t gcpl_id, hid_t UNUSED gapl_id) H5G_t *grp = NULL; /*new group */ H5P_genplist_t *gc_plist; /* Property list created */ H5O_ginfo_t ginfo; /* Group info */ + H5O_linfo_t linfo; /* Link info */ unsigned oloc_init = 0; /* Flag to indicate that the group object location was created successfully */ H5G_t *ret_value; /* Return value */ @@ -1486,8 +1508,12 @@ H5G_create(H5F_t *file, hid_t dxpl_id, hid_t gcpl_id, hid_t UNUSED gapl_id) if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info") + /* Get the link info property */ + if(H5P_get(gc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info") + /* Create the group object header */ - if(H5G_obj_create(file, dxpl_id, &ginfo, &(grp->oloc)/*out*/) < 0) + if(H5G_obj_create(file, dxpl_id, &ginfo, &linfo, &(grp->oloc)/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header") oloc_init = 1; /* Indicate that the object location information is valid */ diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c index f53493c..0a7ac28 100644 --- a/src/H5Gbtree2.c +++ b/src/H5Gbtree2.c @@ -75,7 +75,18 @@ typedef struct H5G_fh_ud_cmp_t { /* v2 B-tree function callbacks */ -/* v2 B-tree driver callbacks */ +/* v2 B-tree driver callbacks for 'creation order' index */ +static herr_t H5G_dense_btree2_corder_store(void *native, const void *udata); +static herr_t H5G_dense_btree2_corder_retrieve(void *udata, const void *native); +static herr_t H5G_dense_btree2_corder_compare(const void *rec1, const void *rec2); +static herr_t H5G_dense_btree2_corder_encode(const H5F_t *f, uint8_t *raw, + const void *native); +static herr_t H5G_dense_btree2_corder_decode(const H5F_t *f, const uint8_t *raw, + void *native); +static herr_t H5G_dense_btree2_corder_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *_udata); + +/* v2 B-tree driver callbacks for 'name' index */ static herr_t H5G_dense_btree2_name_store(void *native, const void *udata); static herr_t H5G_dense_btree2_name_retrieve(void *udata, const void *native); static herr_t H5G_dense_btree2_name_compare(const void *rec1, const void *rec2); @@ -106,6 +117,18 @@ const H5B2_class_t H5G_BT2_NAME[1]={{ /* B-tree class information */ H5G_dense_btree2_name_debug /* Record debugging callback */ }}; +/* v2 B-tree class for indexing 'creation order' field of links */ +const H5B2_class_t H5G_BT2_CORDER[1]={{ /* B-tree class information */ + H5B2_GRP_DENSE_CORDER_ID, /* Type of B-tree */ + sizeof(H5G_dense_bt2_corder_rec_t), /* Size of native record */ + H5G_dense_btree2_corder_store, /* Record storage callback */ + H5G_dense_btree2_corder_retrieve, /* Record retrieval callback */ + H5G_dense_btree2_corder_compare, /* Record comparison callback */ + H5G_dense_btree2_corder_encode, /* Record encoding callback */ + H5G_dense_btree2_corder_decode, /* Record decoding callback */ + H5G_dense_btree2_corder_debug /* Record debugging callback */ +}}; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -374,3 +397,193 @@ H5G_dense_btree2_name_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dx FUNC_LEAVE_NOAPI(SUCCEED) } /* H5G_dense_btree2_name_debug() */ + +/*------------------------------------------------------------------------- + * Function: H5G_dense_btree2_corder_store + * + * Purpose: Store user information into native record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_btree2_corder_store(void *_nrecord, const void *_udata) +{ + const H5G_bt2_ud_ins_t *udata = (const H5G_bt2_ud_ins_t *)_udata; + H5G_dense_bt2_corder_rec_t *nrecord = (H5G_dense_bt2_corder_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_store) + + /* Copy user information info native record */ + nrecord->corder = udata->common.corder; + HDmemcpy(nrecord->id, udata->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5G_dense_btree2_corder_store() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_dense_btree2_corder_retrieve + * + * Purpose: Retrieve native information from record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_btree2_corder_retrieve(void *udata, const void *nrecord) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_retrieve) + + *(H5G_dense_bt2_corder_rec_t *)udata = *(const H5G_dense_bt2_corder_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5G_dense_btree2_corder_retrieve() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_dense_btree2_corder_compare + * + * Purpose: Compare two native information records, according to some key + * + * Return: <0 if rec1 < rec2 + * =0 if rec1 == rec2 + * >0 if rec1 > rec2 + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_btree2_corder_compare(const void *_bt2_udata, const void *_bt2_rec) +{ + const H5G_bt2_ud_common_t *bt2_udata = (const H5G_bt2_ud_common_t *)_bt2_udata; + const H5G_dense_bt2_corder_rec_t *bt2_rec = (const H5G_dense_bt2_corder_rec_t *)_bt2_rec; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_compare) + + /* Sanity check */ + HDassert(bt2_udata); + HDassert(bt2_rec); + +#ifdef QAK +{ +unsigned u; + +HDfprintf(stderr, "%s: bt2_udata = %Hu}\n", "H5G_dense_btree2_corder_compare", (hsize_t)bt2_udata->corder); +HDfprintf(stderr, "%s: bt2_rec = {%Hu, ", "H5G_dense_btree2_corder_compare", (hsize_t)bt2_rec->corder); +for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++) + HDfprintf(stderr, "%02x%s", bt2_rec->id[u], (u < (H5G_DENSE_FHEAP_ID_LEN - 1) ? " " : "}\n")); +} +#endif /* QAK */ + /* Check creation order value */ + if(bt2_udata->corder < bt2_rec->corder) + ret_value = -1; + else if(bt2_udata->corder > bt2_rec->corder) + ret_value = 1; + else + ret_value = 0; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G_dense_btree2_corder_compare() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_dense_btree2_corder_encode + * + * Purpose: Encode native information into raw form for storing on disk + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_btree2_corder_encode(const H5F_t UNUSED *f, uint8_t *raw, const void *_nrecord) +{ + const H5G_dense_bt2_corder_rec_t *nrecord = (const H5G_dense_bt2_corder_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_encode) + + /* Encode the record's fields */ + UINT64ENCODE(raw, nrecord->corder) + HDmemcpy(raw, nrecord->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5G_dense_btree2_corder_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_dense_btree2_corder_decode + * + * Purpose: Decode raw disk form of record into native form + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_btree2_corder_decode(const H5F_t UNUSED *f, const uint8_t *raw, void *_nrecord) +{ + H5G_dense_bt2_corder_rec_t *nrecord = (H5G_dense_bt2_corder_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_decode) + + /* Decode the record's fields */ + UINT64DECODE(raw, nrecord->corder) + HDmemcpy(nrecord->id, raw, (size_t)H5G_DENSE_FHEAP_ID_LEN); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5G_dense_btree2_corder_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_dense_btree2_corder_debug + * + * Purpose: Debug native form of record + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_btree2_corder_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_nrecord, + const void UNUSED *_udata) +{ + const H5G_dense_bt2_corder_rec_t *nrecord = (const H5G_dense_bt2_corder_rec_t *)_nrecord; + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_debug) + + HDfprintf(stream, "%*s%-*s {%Hu, ", indent, "", fwidth, "Record:", + nrecord->corder); + for(u = 0; u < H5G_DENSE_FHEAP_ID_LEN; u++) + HDfprintf(stderr, "%02x%s", nrecord->id[u], (u < (H5G_DENSE_FHEAP_ID_LEN - 1) ? " " : "}\n")); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5G_dense_btree2_corder_debug() */ + diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 3019d4f..76970fc 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -219,6 +219,9 @@ typedef struct { /* The v2 B-tree class for indexing 'name' field on links */ H5_DLLVAR const H5B2_class_t H5G_BT2_NAME[1]; +/* The v2 B-tree class for indexing 'creation order' field on links */ +H5_DLLVAR const H5B2_class_t H5G_BT2_CORDER[1]; + /*****************************/ /* Library Private Variables */ @@ -299,8 +302,8 @@ HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len); HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") /* Create the name index v2 B-tree */ - bt2_rrec_size = 4 + /* Name's hash value */ - fheap_id_len; /* Fractal heap ID */ + bt2_rrec_size = 4 + /* Name's hash value */ + fheap_id_len; /* Fractal heap ID */ if(H5B2_create(f, dxpl_id, H5G_BT2_NAME, (size_t)H5G_NAME_BT2_NODE_SIZE, bt2_rrec_size, H5G_NAME_BT2_SPLIT_PERC, H5G_NAME_BT2_MERGE_PERC, @@ -310,8 +313,20 @@ HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len); HDfprintf(stderr, "%s: linfo->name_bt2_addr = %a\n", FUNC, linfo->name_bt2_addr); #endif /* QAK */ - /* XXX: Check if we should create a creation order index v2 B-tree */ - /* XXX: Create the creation order index v2 B-tree */ + /* Check if we should create a creation order index v2 B-tree */ + if(linfo->index_corder) { + /* Create the creation order index v2 B-tree */ + bt2_rrec_size = 8 + /* Creation order value */ + fheap_id_len; /* Fractal heap ID */ + if(H5B2_create(f, dxpl_id, H5G_BT2_CORDER, + (size_t)H5G_CORDER_BT2_NODE_SIZE, bt2_rrec_size, + H5G_CORDER_BT2_SPLIT_PERC, H5G_CORDER_BT2_MERGE_PERC, + &(linfo->corder_bt2_addr)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index") +#ifdef QAK +HDfprintf(stderr, "%s: linfo->corder_bt2_addr = %a\n", FUNC, linfo->corder_bt2_addr); +#endif /* QAK */ + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Gobj.c b/src/H5Gobj.c index b6abe4c..fd8a31e 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -219,9 +219,8 @@ done: */ herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - H5O_loc_t *oloc/*out*/) + const H5O_linfo_t *linfo, H5O_loc_t *oloc/*out*/) { - H5O_linfo_t linfo; /* Link information */ size_t hdr_size; /* Size of object header to request */ hbool_t use_latest_format; /* Flag indicating the new group format should be used */ herr_t ret_value = SUCCEED; /* Return value */ @@ -242,18 +241,20 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, else use_latest_format = FALSE; + /* Make certain that the creation order is being tracked if an index is + * going to be built on it. + */ + if(linfo->index_corder && !ginfo->track_corder) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "must track creation order to create index for it") + /* Check if we should be using the latest version of the group format */ if(use_latest_format) { - H5O_linfo_t def_linfo = H5G_CRT_LINK_INFO_DEF; /* Default link info */ H5O_link_t lnk; /* Temporary link message info for computing message size */ char null_char = '\0'; /* Character for creating null string */ size_t ginfo_size; /* Size of the group info message */ size_t linfo_size; /* Size of the link info message */ size_t link_size; /* Size of a link message */ - /* Initialize message information */ - HDmemcpy(&linfo, &def_linfo, sizeof(H5O_linfo_t)); - /* Calculate message size infomation, for creating group's object header */ linfo_size = H5O_mesg_size(H5O_LINFO_ID, f, &linfo, (size_t)0); HDassert(linfo_size); @@ -287,7 +288,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Check for format of group to create */ if(use_latest_format) { /* Insert link info message */ - if(H5O_modify(oloc, H5O_LINFO_ID, H5O_NEW_MESG, 0, 0, &linfo, dxpl_id) < 0) + if(H5O_modify(oloc, H5O_LINFO_ID, H5O_NEW_MESG, 0, 0, linfo, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") /* Insert group info message */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index d3ed14e..1051846 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -248,10 +248,16 @@ typedef struct H5G_bt_it_ud5_t { /* Typedef for native 'name' field index records in the v2 B-tree */ typedef struct H5G_dense_bt2_name_rec_t { - uint32_t hash; /* Hash of 'name' field value */ + uint32_t hash; /* Hash of 'name' field value */ uint8_t id[H5G_DENSE_FHEAP_ID_LEN]; /* Heap ID for link */ } H5G_dense_bt2_name_rec_t; +/* Typedef for native 'creation order' field index records in the v2 B-tree */ +typedef struct H5G_dense_bt2_corder_rec_t { + uint64_t corder; /* 'creation order' field value */ + uint8_t id[H5G_DENSE_FHEAP_ID_LEN]; /* Heap ID for link */ +} H5G_dense_bt2_corder_rec_t; + /* * Common data exchange structure for dense link storage. This structure is * passed through the v2 B-tree layer to the methods for the objects @@ -261,9 +267,10 @@ typedef struct H5G_bt2_ud_common_t { /* downward */ H5F_t *f; /* Pointer to file that fractal heap is in */ hid_t dxpl_id; /* DXPL for operation */ - H5HF_t *fheap; /* Fractal heap handle */ + H5HF_t *fheap; /* Fractal heap handle */ const char *name; /* Name of link to compare */ uint32_t name_hash; /* Hash of name of link to compare */ + uint64_t corder; /* Creation order value of link to compare */ H5B2_found_t found_op; /* Callback when correct link is found */ void *found_op_data; /* Callback data when correct link is found */ } H5G_bt2_ud_common_t; @@ -427,7 +434,7 @@ H5_DLL int H5G_obj_cmp_name_inc(const void *lnk1, const void *lnk2); H5_DLL int H5G_obj_cmp_name_dec(const void *lnk1, const void *lnk2); H5_DLL herr_t H5G_obj_release_table(H5G_link_table_t *ltable); H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - H5O_loc_t *oloc/*out*/); + const H5O_linfo_t *linfo, H5O_loc_t *oloc/*out*/); H5_DLL herr_t H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, hbool_t adj_link, hid_t dxpl_id); H5_DLL herr_t H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name, diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index cb075fa..04eb75c 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -66,6 +66,10 @@ #define H5G_CRT_LINFO_LINK_FHEAP_ADDR HADDR_UNDEF #define H5G_CRT_LINFO_NAME_BT2_ADDR HADDR_UNDEF #define H5G_CRT_LINFO_CORDER_BT2_ADDR HADDR_UNDEF + +/* Definitions for link info settings */ +#define H5G_CRT_LINK_INFO_NAME "link info" +#define H5G_CRT_LINK_INFO_SIZE sizeof(H5O_linfo_t) #define H5G_CRT_LINK_INFO_DEF {H5G_CRT_LINFO_INDEX_CORDER, \ H5G_CRT_LINFO_NLINKS, \ H5G_CRT_LINFO_MIN_CORDER, \ diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 0020377..68e8dfc 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -651,6 +651,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* If an intermediate group doesn't exist & flag is set, create the group */ if(target & H5G_CRT_INTMD_GROUP) { H5O_ginfo_t ginfo; /* Group info message for parent group */ + H5O_linfo_t linfo; /* Link info message for parent group */ /* Get the group info for parent group */ /* (OK if not found) */ @@ -664,9 +665,21 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, HDmemcpy(&ginfo, &def_ginfo, sizeof(H5O_ginfo_t)); } /* end if */ + /* Get the link info for parent group */ + /* (OK if not found) */ + if(NULL == H5O_read(grp_loc.oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + H5O_linfo_t def_linfo = H5G_CRT_LINK_INFO_DEF; + + /* Clear error stack from not finding the link info message */ + H5E_clear_stack(NULL); + + /* Use default link info settings */ + HDmemcpy(&linfo, &def_linfo, sizeof(H5O_linfo_t)); + } /* end if */ + /* Create the intermediate group */ /* XXX: Should we allow user to control the group creation params here? -QAK */ - if(H5G_obj_create(grp_oloc.file, dxpl_id, &ginfo, obj_loc.oloc/*out*/) < 0) + if(H5G_obj_create(grp_oloc.file, dxpl_id, &ginfo, &linfo, obj_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") /* Insert new group into current group's symbol table */ diff --git a/src/H5P.c b/src/H5P.c index fa694b1..dcda4ef 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -247,9 +247,11 @@ H5P_init_interface(void) /* Group creation property class variables. In sequence, they are, * - Creation property list class to modify * - Default value for "group info" + * - Default value for "link info" */ H5P_genclass_t *gcrt_class; /* Pointer to group creation property list class created */ H5O_ginfo_t ginfo = H5G_CRT_GROUP_INFO_DEF; + H5O_linfo_t linfo = H5G_CRT_LINK_INFO_DEF; /* Object creation property class variables. In sequence, they are, * - Creation property list class to modify */ @@ -377,6 +379,10 @@ H5P_init_interface(void) if(H5P_register(gcrt_class, H5G_CRT_GROUP_INFO_NAME, H5G_CRT_GROUP_INFO_SIZE, &ginfo, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register link info */ + if(H5P_register(gcrt_class, H5G_CRT_LINK_INFO_NAME, H5G_CRT_LINK_INFO_SIZE, + &linfo, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") } /* end if */ /* Allocate the group access class */ diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c index a97fe42..5e4d281 100644 --- a/src/H5Pgcpl.c +++ b/src/H5Pgcpl.c @@ -367,11 +367,92 @@ H5Pget_creation_order_tracking(hid_t plist_id, hbool_t *track_corder /*out*/) if(H5P_get(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info") - if(track_corder) - *track_corder = ginfo.track_corder; + *track_corder = ginfo.track_corder; } /* end if */ done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_creation_order_tracking() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_creation_order_index + * + * Purpose: Set the flag to index creation order of links in a group + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * October 30, 2006 + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_creation_order_index(hid_t plist_id, hbool_t index_corder) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5O_linfo_t linfo; /* Link information structure */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pset_creation_order_index, FAIL) + H5TRACE2("e","ib",plist_id,index_corder); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get link info */ + if(H5P_get(plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") + + /* Update fields */ + linfo.index_corder = index_corder; + + /* Set link info */ + if(H5P_set(plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_creation_order_index() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_creation_order_index + * + * Purpose: Returns the flag indicating that creation order is indexed + * for links in a group. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * October 30, 2006 + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_creation_order_index(hid_t plist_id, hbool_t *index_corder /*out*/) +{ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pget_creation_order_index, FAIL) + H5TRACE2("e","ix",plist_id,index_corder); + + /* Get values */ + if(index_corder) { + H5P_genplist_t *plist; /* Property list pointer */ + H5O_linfo_t linfo; /* Link information structure */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get link info */ + if(H5P_get(plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") + + *index_corder = linfo.index_corder; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_creation_order_index() */ + diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 9681c55..ed671c5 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -370,6 +370,8 @@ H5_DLL herr_t H5Pset_est_link_info(hid_t plist_id, unsigned est_num_entries, uns H5_DLL herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /* out */, unsigned *est_name_len /* out */); H5_DLL herr_t H5Pset_creation_order_tracking(hid_t plist_id, hbool_t track_corder); H5_DLL herr_t H5Pget_creation_order_tracking(hid_t plist_id, hbool_t *track_corder /* out */); +H5_DLL herr_t H5Pset_creation_order_index(hid_t plist_id, hbool_t index_corder); +H5_DLL herr_t H5Pget_creation_order_index(hid_t plist_id, hbool_t *index_corder /* out */); /* String creation property list (SCPL) routines */ H5_DLL herr_t H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding); diff --git a/test/links.c b/test/links.c index b1da4af..28c7fab 100644 --- a/test/links.c +++ b/test/links.c @@ -72,6 +72,10 @@ const char *FILENAME[] = { #define H5L_DIM1 100 #define H5L_DIM2 100 +/* Creation order macros */ +#define CORDER_GROUP_NAME "corder_group" + +#ifdef QAK /*------------------------------------------------------------------------- * Function: mklinks @@ -2807,7 +2811,7 @@ external_link_unlink_dense(hid_t fapl, hbool_t new_format) /* Create enough objects in the root group to change it into a "dense" group */ for(u = 0; u < max_compact; u++) { - sprintf(objname, "filler %u\n", u); + sprintf(objname, "filler %u", u); if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR if(H5Gclose(gid2) < 0) TEST_ERROR } /* end for */ @@ -2850,7 +2854,7 @@ external_link_unlink_dense(hid_t fapl, hbool_t new_format) /* Remove enough objects in the root group to change it into a "compact" group */ for(u = 0; u < ((max_compact - min_dense) + 1); u++) { - sprintf(objname, "filler %u\n", u); + sprintf(objname, "filler %u", u); if(H5Gunlink(gid, objname) < 0) TEST_ERROR } /* end for */ @@ -3137,7 +3141,7 @@ external_link_ride(hid_t fapl, hbool_t new_format) /* Create enough objects in the root group to change it into a "dense" group */ for(u = 0; u < (max_compact + 1); u++) { - sprintf(objname, "filler %u\n", u); + sprintf(objname, "filler %u", u); if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR if(H5Gclose(gid2) < 0) TEST_ERROR } /* end for */ @@ -3206,7 +3210,7 @@ external_link_ride(hid_t fapl, hbool_t new_format) /* Remove enough objects in the root group to change it into a "compact" group */ for(u = 0; u < ((max_compact - min_dense) + 3); u++) { - sprintf(objname, "filler %u\n", u); + sprintf(objname, "filler %u", u); if(H5Gunlink(gid, objname) < 0) TEST_ERROR } /* end for */ @@ -5144,15 +5148,383 @@ check_all_closed(hid_t fapl, hbool_t new_format) PASSED(); return 0; - error: - printf("Error on file %d.\n", x); +error: H5E_BEGIN_TRY { H5Fclose(fid); } H5E_END_TRY; return -1; -} +} /* end check_all_closed() */ +#endif /* QAK */ + + +/*------------------------------------------------------------------------- + * Function: corder_create_empty + * + * Purpose: Create an empty group with creation order indices + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static int +corder_create_empty(hid_t fapl) +{ + hid_t file_id = (-1); /* File ID */ + hid_t group_id = (-1); /* Group ID */ + hid_t gcpl_id = (-1); /* Group creation property list ID */ + hbool_t track_corder; /* Status of creation order tracking for GCPL */ + hbool_t index_corder; /* Status of creation order indexing for GCPL */ + char filename[NAME_BUF_SIZE];/* File name */ + + TESTING("creating empty group with creation order tracking") + + /* Create file */ + /* (with creation order tracking for the root group) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Set creation order indexing on group */ + if(H5Pget_creation_order_index(gcpl_id, &index_corder) < 0) TEST_ERROR + if(index_corder != FALSE) TEST_ERROR + if(H5Pset_creation_order_index(gcpl_id, TRUE) < 0) TEST_ERROR + if(H5Pget_creation_order_index(gcpl_id, &index_corder) < 0) TEST_ERROR + if(index_corder != TRUE) TEST_ERROR + + /* Creating a group with onder creation order indexing on should fail */ + H5E_BEGIN_TRY { + group_id = H5Gcreate_expand(file_id, gcpl_id, H5P_DEFAULT); + } H5E_END_TRY; + if(group_id > 0) { + H5Gclose(group_id); + H5_FAILED(); + puts(" H5Gcreate_expand() should have failed for a creation order index with no tracking."); + TEST_ERROR + } /* end if */ + + /* Set creation order tracking on group */ + if(H5Pget_creation_order_tracking(gcpl_id, &track_corder) < 0) TEST_ERROR + if(track_corder != FALSE) TEST_ERROR + if(H5Pset_creation_order_tracking(gcpl_id, TRUE) < 0) TEST_ERROR + if(H5Pget_creation_order_tracking(gcpl_id, &track_corder) < 0) TEST_ERROR + if(track_corder != TRUE) TEST_ERROR + + /* Create group with creation order indexing & tracking on */ + if((group_id = H5Gcreate_expand(file_id, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Llink(file_id, CORDER_GROUP_NAME, group_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check on group's status */ + if(H5G_is_empty_test(group_id) != TRUE) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created */ + if((group_id = H5Gopen(file_id, CORDER_GROUP_NAME)) < 0) TEST_ERROR + + /* Check on group's status */ + if(H5G_is_empty_test(group_id) != TRUE) TEST_ERROR + + /* Retrieve group creation property list for group */ + if((gcpl_id = H5Gget_create_plist(group_id)) < 0) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_creation_order_index(gcpl_id, &index_corder) < 0) TEST_ERROR + if(index_corder != TRUE) TEST_ERROR + if(H5Pget_creation_order_tracking(gcpl_id, &track_corder) < 0) TEST_ERROR + if(track_corder != TRUE) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return -1; +} /* end corder_create_empty() */ + + +/*------------------------------------------------------------------------- + * Function: corder_create_compact + * + * Purpose: Create a group with creation order indices and insert links + * in it when in compact form + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static int +corder_create_compact(hid_t fapl) +{ + hid_t file_id = (-1); /* File ID */ + hid_t group_id = (-1), group_id2 = (-1); /* Group IDs */ + hid_t gcpl_id = (-1); /* Group 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" */ + unsigned nlinks; /* Number of link messages in group's header */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + unsigned u; /* Local index variable */ + + TESTING("creating compact group with creation order tracking") + + /* Create file */ + /* (with creation order tracking for the root group) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Set creation order tracking & indexing on group */ + if(H5Pset_creation_order_index(gcpl_id, TRUE) < 0) TEST_ERROR + if(H5Pset_creation_order_tracking(gcpl_id, TRUE) < 0) TEST_ERROR + + /* Create group with creation order indexing & tracking on */ + if((group_id = H5Gcreate_expand(file_id, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Llink(file_id, CORDER_GROUP_NAME, group_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check on group's initial status */ + if(H5G_is_empty_test(group_id) != TRUE) TEST_ERROR + if(H5G_has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G_is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Create several links, but keep group in compact form */ + for(u = 0; u < max_compact; u++) { + sprintf(objname, "filler %u", u); + if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G_has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR + if(nlinks != (u + 1)) TEST_ERROR + if(H5G_has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G_is_new_dense_test(group_id) == TRUE) TEST_ERROR + } /* end for */ + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created */ + if((group_id = H5Gopen(file_id, CORDER_GROUP_NAME)) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G_has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR + if(nlinks != max_compact) TEST_ERROR + if(H5G_has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G_is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Loop through links, 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++) { + H5L_linkinfo_t linfo; /* Link information */ + + /* Retrieve information for link */ + sprintf(objname, "filler %u", u); + if(H5Lget_linkinfo(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify creation order of link */ + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != u) TEST_ERROR + } /* end for */ + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return -1; +} /* end corder_create_compact() */ + +/*------------------------------------------------------------------------- + * Function: corder_create_dense + * + * Purpose: Create a group with creation order indices and insert links + * in it until it's in dense form + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Monday, October 30, 2006 + * + *------------------------------------------------------------------------- + */ +static int +corder_create_dense(hid_t fapl) +{ + hid_t file_id = (-1); /* File ID */ + hid_t group_id = (-1), group_id2 = (-1); /* Group IDs */ + hid_t gcpl_id = (-1); /* Group 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" */ + unsigned nlinks; /* Number of link messages in group's header */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + unsigned u; /* Local index variable */ + + TESTING("creating dense group with creation order tracking") + + /* Create file */ + /* (with creation order tracking for the root group) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create group creation property list */ + if((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + + /* Set creation order tracking & indexing on group */ + if(H5Pset_creation_order_index(gcpl_id, TRUE) < 0) TEST_ERROR + if(H5Pset_creation_order_tracking(gcpl_id, TRUE) < 0) TEST_ERROR + + /* Create group with creation order indexing & tracking on */ +HDfprintf(stderr, "Before creating group with creation order tracking & index\n"); + if((group_id = H5Gcreate_expand(file_id, gcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR +HDfprintf(stderr, "After creating group with creation order tracking & index\n"); + if(H5Llink(file_id, CORDER_GROUP_NAME, group_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check on group's initial status */ + if(H5G_is_empty_test(group_id) != TRUE) TEST_ERROR + if(H5G_has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G_is_new_dense_test(group_id) == TRUE) TEST_ERROR + + /* Query the group creation properties */ + if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Create several links, up to limit of compact form */ + for(u = 0; u < max_compact; u++) { + sprintf(objname, "filler %u", u); + if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G_has_links_test(group_id, &nlinks) != TRUE) TEST_ERROR + if(nlinks != (u + 1)) TEST_ERROR + if(H5G_has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G_is_new_dense_test(group_id) == TRUE) TEST_ERROR + } /* end for */ + + /* Create another group, to push group into dense form */ + sprintf(objname, "filler %u", max_compact); + if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G_has_links_test(group_id, NULL) == TRUE) TEST_ERROR + if(H5G_has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G_is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created */ + if((group_id = H5Gopen(file_id, CORDER_GROUP_NAME)) < 0) TEST_ERROR + + /* Verify state of group */ + if(H5G_has_links_test(group_id, NULL) == TRUE) TEST_ERROR + if(H5G_has_stab_test(group_id) == TRUE) TEST_ERROR + if(H5G_is_new_dense_test(group_id) != TRUE) TEST_ERROR + + /* Loop through links, 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 + 1); u++) { + H5L_linkinfo_t linfo; /* Link information */ + + /* Retrieve information for link */ + sprintf(objname, "filler %u", u); + if(H5Lget_linkinfo(group_id, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify creation order of link */ + if(linfo.corder_valid != TRUE) TEST_ERROR + if(linfo.corder != u) TEST_ERROR + } /* end for */ + + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return -1; +} /* end corder_create_compact() */ + + /*------------------------------------------------------------------------- * Function: main * @@ -5189,6 +5561,7 @@ main(void) /* Set the "use the latest version of the format" flag for creating objects in the file */ if(H5Pset_latest_format(fapl2, TRUE) < 0) TEST_ERROR +#ifdef QAK /* Loop over using new group format */ for(new_format = FALSE; new_format <= TRUE; new_format++) { /* General tests... (on both old & new format groups */ @@ -5243,7 +5616,20 @@ main(void) nerrors += linkinfo((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0; nerrors += check_all_closed((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0; + + /* Creation order tests */ + if(new_format == TRUE) { + } /* end if */ } /* end for */ +#else /* QAK */ + nerrors += corder_create_empty(fapl2) < 0 ? 1 : 0; +/* XXX: when creation order indexing is fully working, go back and add checks + * to these tests to make certain that the creation order values are + * correct. + */ + nerrors += corder_create_compact(fapl2) < 0 ? 1 : 0; + nerrors += corder_create_dense(fapl2) < 0 ? 1 : 0; +#endif /* QAK */ /* Close 2nd FAPL */ H5Pclose(fapl2); -- cgit v0.12