From 665f42f9e0d7b84bddbca2ff45b276b45eb76654 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 7 Nov 2006 15:32:44 -0500 Subject: [svn-r12878] Description: Flesh out support for looking up link info by index, some cases for using dense storage are working now. Tested on: Linux/32 2.6 (chicago) --- src/H5Gbtree2.c | 2 +- src/H5Gdense.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/H5Glink.c | 10 +-- src/H5Gobj.c | 9 ++- src/H5Gpkg.h | 11 ++- src/H5L.c | 152 +++++++++++++++++--------------------- src/H5Lpublic.h | 2 +- src/H5public.h | 10 +-- test/links.c | 67 +++++++++++++++-- 9 files changed, 360 insertions(+), 126 deletions(-) diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c index 0a7ac28..68d4128 100644 --- a/src/H5Gbtree2.c +++ b/src/H5Gbtree2.c @@ -482,7 +482,7 @@ H5G_dense_btree2_corder_compare(const void *_bt2_udata, const void *_bt2_rec) { unsigned u; -HDfprintf(stderr, "%s: bt2_udata = %Hu}\n", "H5G_dense_btree2_corder_compare", (hsize_t)bt2_udata->corder); +HDfprintf(stderr, "%s: bt2_udata->corder = %Hd\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")); diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 46ba593..7cb6c48 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -206,6 +206,33 @@ typedef struct { H5G_obj_t type; /* Type of object */ } H5G_fh_gtbi_ud1_t; +/* + * Data exchange structure to pass through the v2 B-tree layer for the + * H5B2_index function when retrieving a link by index. + */ +typedef struct { + /* downward (internal) */ + H5F_t *f; /* Pointer to file that fractal heap is in */ + hid_t dxpl_id; /* DXPL for operation */ + H5HF_t *fheap; /* Fractal heap handle */ + + /* upward */ + H5O_link_t *lnk; /* Pointer to link */ +} H5G_bt2_lbi_ud1_t; + +/* + * Data exchange structure to pass through the fractal heap layer for the + * H5HF_op function when retrieving a link by index. + */ +typedef struct { + /* downward (internal) */ + H5F_t *f; /* Pointer to file that fractal heap is in */ + hid_t dxpl_id; /* DXPL for operation */ + + /* upward */ + H5O_link_t *lnk; /* Pointer to link */ +} H5G_fh_lbi_ud1_t; + /********************/ /* Package Typedefs */ /********************/ @@ -433,7 +460,7 @@ done: /*------------------------------------------------------------------------- * Function: H5G_dense_lookup_cb * - * Purpose: Callback when a link is located in the 'name' index + * Purpose: Callback when a link is located in an index * * Return: Non-negative on success/Negative on failure * @@ -529,6 +556,173 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_dense_lookup_by_idx_fh_cb + * + * Purpose: Callback for fractal heap operator, to make copy of link when + * when lookup up a link by index + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 7 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_lookup_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) +{ + H5G_fh_lbi_ud1_t *udata = (H5G_fh_lbi_ud1_t *)_udata; /* User data for fractal heap 'op' callback */ + H5O_link_t *tmp_lnk = NULL; /* Temporary pointer to link */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_dense_lookup_by_idx_fh_cb) + + /* Decode link information & keep a copy */ + if(NULL == (tmp_lnk = H5O_decode(udata->f, udata->dxpl_id, obj, H5O_LINK_ID))) + HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link") + + /* Copy link information */ + if(NULL == H5O_copy(H5O_LINK_ID, tmp_lnk, udata->lnk)) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5B2_ITER_ERROR, "can't copy link message") + +done: + if(tmp_lnk) + H5O_reset(H5O_LINK_ID, tmp_lnk); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_dense_lookup_by_idx_fh_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_dense_lookup_by_idx_bt2_cb + * + * Purpose: v2 B-tree callback for dense link storage lookup by index + * + * Return: H5B2_ITER_ERROR/H5B2_ITER_CONT/H5B2_ITER_STOP + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 7 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_dense_lookup_by_idx_bt2_cb(const void *_record, void *_bt2_udata) +{ + const H5G_dense_bt2_name_rec_t *record = (const H5G_dense_bt2_name_rec_t *)_record; + H5G_bt2_lbi_ud1_t *bt2_udata = (H5G_bt2_lbi_ud1_t *)_bt2_udata; /* User data for callback */ + H5G_fh_lbi_ud1_t fh_udata; /* User data for fractal heap 'op' callback */ + int ret_value = H5B2_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_dense_lookup_by_idx_bt2_cb) + + /* Prepare user data for callback */ + /* down */ + fh_udata.f = bt2_udata->f; + fh_udata.dxpl_id = bt2_udata->dxpl_id; + fh_udata.lnk = bt2_udata->lnk; + + /* Call fractal heap 'op' routine, to copy the link information */ + if(H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, record->id, + H5G_dense_lookup_by_idx_fh_cb, &fh_udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPERATE, H5B2_ITER_ERROR, "link found callback failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_dense_lookup_by_idx_bt2_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_dense_lookup_by_idx + * + * Purpose: Look up a link within a group that uses dense link storage, + * according to the order of an index + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 7 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, + H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk) +{ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ + haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_dense_lookup_by_idx, FAIL) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(linfo); + HDassert(lnk); + + /* Open the fractal heap */ + if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->link_fheap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + + /* Determine the address of the index to use */ + if(idx_type == H5L_INDEX_NAME) { + /* Check if "native" order is OK - since names are hashed, getting them + * in strictly increasing or decreasing order requires building a + * table and sorting it. + */ + if(order == H5_ITER_NATIVE) { + bt2_addr = linfo->name_bt2_addr; + bt2_class = H5G_BT2_NAME; + HDassert(H5F_addr_defined(bt2_addr)); + } /* end if */ + else + bt2_addr = HADDR_UNDEF; + } /* end if */ + else { + HDassert(idx_type == H5L_INDEX_CRT_ORDER); + + /* This address may not be defined if creation order is tracked, but + * there's no index on it... + */ + bt2_addr = linfo->corder_bt2_addr; + bt2_class = H5G_BT2_CORDER; + } /* end else */ + + /* If there is an index defined for the field, use it */ + if(H5F_addr_defined(bt2_addr)) { + H5G_bt2_lbi_ud1_t udata; /* User data for v2 B-tree link lookup */ + + /* Construct the user data for v2 B-tree callback */ + udata.f = f; + udata.dxpl_id = dxpl_id; + udata.fheap = fheap; + udata.lnk = lnk; + + /* Find & copy the link in the appropriate index */ + if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_lookup_by_idx_bt2_cb, &udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in index") + } /* end if */ + else { /* Otherwise, we need to build a table of the links and sort it */ +HDfprintf(stderr, "%s: building a table for dense storage not implemented yet!\n", FUNC); +HGOTO_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, "building a table for dense storage not implemented yet") + } /* end else */ + +done: + /* Release resources */ + if(fheap) + if(H5HF_close(fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_dense_lookup_by_idx() */ + + +/*------------------------------------------------------------------------- * Function: H5G_dense_build_table_cb * * Purpose: Callback routine for building table of links from dense @@ -587,7 +781,7 @@ done: */ herr_t H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, - H5_iter_order_t order, H5G_link_table_t *ltable) + H5L_index_t idx_type, H5_iter_order_t order, H5G_link_table_t *ltable) { herr_t ret_value = SUCCEED; /* Return value */ @@ -623,13 +817,22 @@ H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") /* Sort link table in correct iteration order */ -/* (XXX: by name, currently) */ - if(order == H5_ITER_INC) - HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_name_inc); - else if(order == H5_ITER_INC) - HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_name_dec); - else - HDassert(order == H5_ITER_NATIVE); + if(idx_type == H5L_INDEX_NAME) { + if(order == H5_ITER_INC) + HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_name_inc); + else if(order == H5_ITER_DEC) + HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_name_dec); + else + HDassert(order == H5_ITER_NATIVE); + } /* end if */ + else { + if(order == H5_ITER_INC) + HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_corder_inc); + else if(order == H5_ITER_DEC) + HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_corder_dec); + else + HDassert(order == H5_ITER_NATIVE); + } /* end else */ } /* end if */ else ltable->lnks = NULL; @@ -800,7 +1003,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, size_t u; /* Local index variable */ /* Build the table of links for this group */ - if(H5G_dense_build_table(f, dxpl_id, linfo, order, <able) < 0) + if(H5G_dense_build_table(f, dxpl_id, linfo, H5L_INDEX_NAME, order, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "error building iteration table of links") /* Iterate over link messages */ diff --git a/src/H5Glink.c b/src/H5Glink.c index 73b974e..5bc40dc 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -182,7 +182,7 @@ H5G_link_build_table(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, if(idx_type == H5L_INDEX_NAME) { if(order == H5_ITER_INC) HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_name_inc); - else if(order == H5_ITER_INC) + else if(order == H5_ITER_DEC) HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_name_dec); else HDassert(order == H5_ITER_NATIVE); @@ -190,7 +190,7 @@ H5G_link_build_table(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, else { if(order == H5_ITER_INC) HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_corder_inc); - else if(order == H5_ITER_INC) + else if(order == H5_ITER_DEC) HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_obj_cmp_corder_dec); else HDassert(order == H5_ITER_NATIVE); @@ -830,7 +830,7 @@ H5G_link_lookup_by_corder(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *lin HDassert(lnk); /* Build table of all link messages, sorted according to desired order */ - if(H5G_link_build_table(oloc, dxpl_id, linfo, H5L_INDEX_CORDER, order, <able) < 0) + if(H5G_link_build_table(oloc, dxpl_id, linfo, H5L_INDEX_CRT_ORDER, order, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table") /* Check for going out of bounds */ @@ -838,10 +838,6 @@ H5G_link_lookup_by_corder(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *lin HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index out of bound") /* Copy link information */ -#ifdef QAK -HDfprintf(stderr, "%s: ltable.lnks[%Hu].corder = %Hd\n", FUNC, n, ltable.lnks[n].corder); -HDfprintf(stderr, "%s: ltable.lnks[%Hu].corder_valid = %t\n", FUNC, n, ltable.lnks[n].corder_valid); -#endif /* QAK */ if(NULL == H5O_copy(H5O_LINK_ID, <able.lnks[n], lnk)) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5O_ITER_ERROR, "can't copy link message") diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 633ac5c..515b822 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -1005,7 +1005,7 @@ H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxp size_t u; /* Local index */ /* Build the table of links for this group */ - if(H5G_dense_build_table(oloc->file, dxpl_id, &linfo, H5_ITER_NATIVE, <able) < 0) + if(H5G_dense_build_table(oloc->file, dxpl_id, &linfo, H5L_INDEX_NAME, H5_ITER_NATIVE, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") /* Inspect links in table for ones that can't be converted back @@ -1198,11 +1198,12 @@ H5G_obj_lookup_by_idx(H5O_loc_t *grp_oloc, H5L_index_t idx_type, /* Check for dense link storage */ if(H5F_addr_defined(linfo.link_fheap_addr)) { -HDfprintf(stderr, "%s: creation order query on dense storage not implemented yet!\n", FUNC); -HGOTO_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, "creation order query on dense storage not implemented yet") + /* Get the link from the dense storage */ + if(H5G_dense_lookup_by_idx(grp_oloc->file, dxpl_id, &linfo, idx_type, order, n, lnk) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") } /* end if */ else { - /* Get the object's info from the link messages */ + /* Get the link from the link messages */ if(H5G_link_lookup_by_corder(grp_oloc, dxpl_id, &linfo, order, n, lnk) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") } /* end else */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 9c1928b..34eec8e 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -266,15 +266,17 @@ typedef struct H5G_bt_it_ud5_t { /* (fractal heap & v2 B-tree info) */ /* Typedef for native 'name' field index records in the v2 B-tree */ +/* (Keep 'id' field first so generic record handling in callbacks works) */ typedef struct H5G_dense_bt2_name_rec_t { - uint32_t hash; /* Hash of 'name' field value */ uint8_t id[H5G_DENSE_FHEAP_ID_LEN]; /* Heap ID for link */ + uint32_t hash; /* Hash of 'name' field value */ } H5G_dense_bt2_name_rec_t; /* Typedef for native 'creation order' field index records in the v2 B-tree */ +/* (Keep 'id' field first so generic record handling in callbacks works) */ 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 */ + uint64_t corder; /* 'creation order' field value */ } H5G_dense_bt2_corder_rec_t; /* @@ -435,12 +437,15 @@ H5_DLL herr_t H5G_link_lookup_by_corder(H5O_loc_t *oloc, hid_t dxpl_id, /* Functions that understand "dense" link storage */ H5_DLL herr_t H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, - H5_iter_order_t order, H5G_link_table_t *ltable); + H5L_index_t idx_type, H5_iter_order_t order, H5G_link_table_t *ltable); H5_DLL herr_t H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo); H5_DLL herr_t H5G_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, const H5O_link_t *lnk); H5_DLL herr_t H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, const char *name, H5O_link_t *lnk); +H5_DLL herr_t H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, + const H5O_linfo_t *linfo, H5L_index_t idx_type, H5_iter_order_t order, + hsize_t n, H5O_link_t *lnk); H5_DLL herr_t H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, const H5O_linfo_t *linfo, hbool_t lib_internal, int skip, int *last_lnk, H5G_link_iterate_t op, void *op_data); diff --git a/src/H5L.c b/src/H5L.c index 793d570..a50d6aa 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -127,6 +127,7 @@ static herr_t H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, static herr_t H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); +static herr_t H5L_get_info_real(const H5O_link_t *lnk, H5L_info_t *linfo); static herr_t H5L_get_info_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); @@ -1248,21 +1249,21 @@ H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path /* Check for flags present in creation property list */ if(lcpl_id != H5P_DEFAULT) { - unsigned crt_intmd_group; + unsigned crt_intmd_group; - if(NULL == (lc_plist = H5I_object(lcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + if(NULL == (lc_plist = H5I_object(lcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - /* Get intermediate group creation property */ - if(H5P_get(lc_plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups") + /* Get intermediate group creation property */ + if(H5P_get(lc_plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups") - if (crt_intmd_group > 0) - target_flags |= H5G_CRT_INTMD_GROUP; + if(crt_intmd_group > 0) + target_flags |= H5G_CRT_INTMD_GROUP; - /* Get character encoding property */ - if(H5P_get(lc_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &char_encoding) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding") + /* Get character encoding property */ + if(H5P_get(lc_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &char_encoding) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding") } /* end if */ /* Pass the lcpl to the link creation callback */ @@ -2044,42 +2045,35 @@ done: /*------------------------------------------------------------------------- - * Function: H5L_get_info_cb + * Function: H5L_get_info_real * - * Purpose: Callback for retrieving a link's metadata + * Purpose: Retrieve information from a link object * * Return: Non-negative on success/Negative on failure * - * Programmer: James Laird - * Monday, April 17 2006 + * Programmer: Quincey Koziol + * Tuesday, November 7 2006 * *------------------------------------------------------------------------- */ static herr_t -H5L_get_info_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, - const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, - H5G_own_loc_t *own_loc/*out*/) +H5L_get_info_real(const H5O_link_t *lnk, H5L_info_t *linfo) { - H5L_trav_ud1_t *udata = (H5L_trav_ud1_t *)_udata; /* User data passed in */ - H5L_info_t *linfo = udata->linfo; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5L_get_info_cb) + FUNC_ENTER_NOAPI_NOINIT(H5L_get_info_real) - /* Check if the name in this group resolved to a valid link */ - if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + /* Sanity check */ + HDassert(lnk); /* Get information from the link */ - if(linfo) - { + if(linfo) { linfo->cset = lnk->cset; linfo->corder = lnk->corder; linfo->corder_valid = lnk->corder_valid; linfo->type = lnk->type; - switch(lnk->type) - { + switch(lnk->type) { case H5L_TYPE_HARD: linfo->u.address = lnk->u.hard.addr; break; @@ -2117,6 +2111,41 @@ H5L_get_info_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, } /* end if */ done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_info_real() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_get_info_cb + * + * Purpose: Callback for retrieving a link's metadata + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, April 17 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_get_info_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, + const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5L_trav_ud1_t *udata = (H5L_trav_ud1_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_get_info_cb) + + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Get information from the link */ + if(H5L_get_info_real(lnk, udata->linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") + +done: /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; @@ -2178,27 +2207,11 @@ H5L_get_info_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, { H5L_trav_ud7_t *udata = (H5L_trav_ud7_t *)_udata; /* User data passed in */ H5O_link_t grp_lnk; /* Link within group */ - H5L_info_t *linfo = udata->linfo; + hbool_t lnk_copied = FALSE; /* Whether the link was copied */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_get_info_by_idx_cb) -#ifdef QAK -HDfprintf(stderr, "%s: grp_loc = %p\n", FUNC, grp_loc); -HDfprintf(stderr, "%s: name = %p\n", FUNC, name); -if(name) - HDfprintf(stderr, "%s: name = '%s'\n", FUNC, name); -HDfprintf(stderr, "%s: lnk = %p\n", FUNC, lnk); -if(lnk && lnk->name) - HDfprintf(stderr, "%s: lnk->name = '%s'\n", FUNC, lnk->name); -HDfprintf(stderr, "%s: obj_loc = %p\n", FUNC, obj_loc); -if(obj_loc) { - HDfprintf(stderr, "%s: obj_loc->oloc = %p\n", FUNC, obj_loc->oloc); - if(obj_loc->oloc) - HDfprintf(stderr, "%s: obj_loc->oloc->addr = %a\n", FUNC, obj_loc->oloc->addr); -} /* end if */ -#endif /* QAK */ - /* Check if the name of the group resolved to a valid object */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group doesn't exist") @@ -2207,52 +2220,17 @@ if(obj_loc) { if(H5G_obj_lookup_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, &grp_lnk, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "link not found") + lnk_copied = TRUE; /* Get information from the link */ - if(linfo) { - linfo->cset = grp_lnk.cset; - linfo->corder = grp_lnk.corder; - linfo->corder_valid = grp_lnk.corder_valid; - linfo->type = grp_lnk.type; - - switch(grp_lnk.type) { - case H5L_TYPE_HARD: - linfo->u.address = grp_lnk.u.hard.addr; - break; - - case H5L_TYPE_SOFT: - linfo->u.link_size = HDstrlen(grp_lnk.u.soft.name) + 1; /*count the null terminator*/ - break; - - default: - { - const H5L_class_t *link_class; /* User-defined link class */ - - if(grp_lnk.type < H5L_TYPE_UD_MIN || grp_lnk.type > H5L_TYPE_MAX) - HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "unknown link class") - - /* User-defined link; call its query function to get the link udata size. */ - /* Get the link class for this type of link. It's okay if the class - * isn't registered, though--we just can't give any more information - * about it - */ - link_class = H5L_find_class(grp_lnk.type); - - if(link_class != NULL && link_class->query_func != NULL) { - ssize_t cb_ret; /* Return value from UD callback */ - - if((cb_ret = (link_class->query_func)(grp_lnk.name, grp_lnk.u.ud.udata, grp_lnk.u.ud.size, NULL, (size_t)0)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query buffer size callback returned failure") - - linfo->u.link_size = cb_ret; - } /* end if */ - else - linfo->u.link_size = 0; - } /* end case */ - } /* end switch */ - } /* end if */ + if(H5L_get_info_real(&grp_lnk, udata->linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") done: + /* Reset the link information, if we have a copy */ + if(lnk_copied) + H5O_reset(H5O_LINK_ID, &grp_lnk); + /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index eb24375..f206b94 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -127,7 +127,7 @@ typedef struct { typedef enum H5L_index_t { H5L_INDEX_UNKNOWN = -1, /* Unknown index type */ H5L_INDEX_NAME, /* Index on names of links */ - H5L_INDEX_CORDER, /* Index on creation order of links */ + H5L_INDEX_CRT_ORDER, /* Index on creation order of links */ H5L_INDEX_N /* Number of indices defined on links in groups */ } H5L_index_t; diff --git a/src/H5public.h b/src/H5public.h index 114944a..c45e1d1 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -229,11 +229,11 @@ typedef ssize_t hssize_t; /* Common iteration orders */ typedef enum { - H5_ITER_UNKNOWN, /* Unknown order */ - H5_ITER_INC, /* Increasing order */ - H5_ITER_DEC, /* Decreasing order */ - H5_ITER_NATIVE, /* No particular order, whatever is fastest */ - H5_ITER_N /* Number of iteration orders */ + H5_ITER_UNKNOWN = -1, /* Unknown order */ + H5_ITER_INC, /* Increasing order */ + H5_ITER_DEC, /* Decreasing order */ + H5_ITER_NATIVE, /* No particular order, whatever is fastest */ + H5_ITER_N /* Number of iteration orders */ } H5_iter_order_t; /* Functions in H5.c */ diff --git a/test/links.c b/test/links.c index 9fa4221..4dce7de 100644 --- a/test/links.c +++ b/test/links.c @@ -5927,6 +5927,7 @@ corder_info_by_idx(hid_t fapl) char objname[NAME_BUF_SIZE]; /* Object name */ char filename[NAME_BUF_SIZE];/* File name */ unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ TESTING("querying info by index") @@ -5955,23 +5956,73 @@ corder_info_by_idx(hid_t fapl) if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR if(H5Gclose(group_id2) < 0) TEST_ERROR - /* Get the link information for new object */ - if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + /* Get the link information for new link, in increasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - /* Verify the link information for new object */ -#ifdef QAK -HDfprintf(stderr, "linfo.corder_valid = %t\n", linfo.corder_valid); -HDfprintf(stderr, "linfo.corder = %Hd\n", linfo.corder); -HDfprintf(stderr, "u = %u\n", u); -#endif /* QAK */ + /* Verify the link information for new link */ + if(linfo.corder != u) TEST_ERROR + + /* Get the link information for first link, in increasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link */ + if(linfo.corder != 0) TEST_ERROR + + /* Get the link information for new link, in decreasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for new link */ if(linfo.corder != u) TEST_ERROR + + /* Get the link information for first link, in decreasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link */ + if(linfo.corder != 0) TEST_ERROR } /* end for */ + /* Check for out of bound offset */ + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + /* Create another link, 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 + /* Get the link information for new link, in increasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for new link */ + if(linfo.corder != u) TEST_ERROR + + /* Get the link information for first link, in increasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link */ + if(linfo.corder != 0) TEST_ERROR + + /* Get the link information for new link, in decreasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for new link */ + if(linfo.corder != u) TEST_ERROR + + /* Get the link information for first link, in decreasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link */ + if(linfo.corder != 0) TEST_ERROR + + /* Verify state of group */ + if(H5G_is_new_dense_test(group_id) != TRUE) TEST_ERROR + /* Close the group */ if(H5Gclose(group_id) < 0) TEST_ERROR -- cgit v0.12