diff options
-rw-r--r-- | src/H5Gbtree2.c | 4 | ||||
-rw-r--r-- | src/H5Gdense.c | 42 | ||||
-rw-r--r-- | src/H5Glink.c | 64 | ||||
-rw-r--r-- | src/H5Gnode.c | 151 | ||||
-rw-r--r-- | src/H5Gobj.c | 47 | ||||
-rw-r--r-- | src/H5Gpkg.h | 83 | ||||
-rw-r--r-- | src/H5Gstab.c | 272 | ||||
-rw-r--r-- | src/H5Ostab.c | 2 | ||||
-rw-r--r-- | test/links.c | 258 |
9 files changed, 618 insertions, 305 deletions
diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c index 68d4128..bc53998 100644 --- a/src/H5Gbtree2.c +++ b/src/H5Gbtree2.c @@ -521,7 +521,7 @@ H5G_dense_btree2_corder_encode(const H5F_t UNUSED *f, uint8_t *raw, const void * FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_encode) /* Encode the record's fields */ - UINT64ENCODE(raw, nrecord->corder) + INT64ENCODE(raw, nrecord->corder) HDmemcpy(raw, nrecord->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) @@ -549,7 +549,7 @@ H5G_dense_btree2_corder_decode(const H5F_t UNUSED *f, const uint8_t *raw, void * FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_dense_btree2_corder_decode) /* Decode the record's fields */ - UINT64DECODE(raw, nrecord->corder) + INT64DECODE(raw, nrecord->corder) HDmemcpy(nrecord->id, raw, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 7cb6c48..4bb9062 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -651,7 +651,6 @@ 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 */ @@ -665,10 +664,6 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, 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 @@ -687,7 +682,8 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, 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... + * there's no index on it. If there's no v2 B-tree that indexes + * the links, a table will be built. */ bt2_addr = linfo->corder_bt2_addr; bt2_class = H5G_BT2_CORDER; @@ -695,7 +691,12 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, /* 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 */ + H5HF_t *fheap; /* Fractal heap handle */ + H5G_bt2_lbi_ud1_t udata; /* User data for v2 B-tree link lookup */ + + /* 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") /* Construct the user data for v2 B-tree callback */ udata.f = f; @@ -706,18 +707,28 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, /* 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") + + /* Close heap */ + if(H5HF_close(fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") } /* 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") + H5G_link_table_t ltable; /* Table of links */ + + /* Build the table of links for this group */ + if(H5G_dense_build_table(f, dxpl_id, linfo, idx_type, order, <able) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "error building table of links") + + /* Copy link information */ + if(NULL == H5O_copy(H5O_LINK_ID, <able.lnks[n], lnk)) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5B2_ITER_ERROR, "can't copy link message") + + /* Free link table information */ + if(H5G_obj_release_table(<able) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") } /* 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() */ @@ -826,6 +837,7 @@ H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, HDassert(order == H5_ITER_NATIVE); } /* end if */ else { + HDassert(idx_type == H5L_INDEX_CRT_ORDER); 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) @@ -1004,7 +1016,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, /* Build the table of links for this group */ 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") + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "error building table of links") /* Iterate over link messages */ for(u = 0, ret_value = H5B_ITER_CONT; u < ltable.nlinks && !ret_value; u++) { diff --git a/src/H5Glink.c b/src/H5Glink.c index 5bc40dc..20c7476 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -188,6 +188,7 @@ H5G_link_build_table(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, HDassert(order == H5_ITER_NATIVE); } /* end if */ else { + HDassert(idx_type == H5L_INDEX_CRT_ORDER); 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) @@ -237,38 +238,33 @@ H5G_link_convert(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, lnk->name = H5MM_xstrdup(name); /* Object is a symbolic or hard link */ - switch(ent->type) { - case H5G_CACHED_SLINK: - { - const char *s; /* Pointer to link value */ - const H5HL_t *heap; /* Pointer to local heap for group */ - - /* Lock the local heap */ - if(NULL == (heap = H5HL_protect(f, dxpl_id, lheap_addr))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") + if(ent->type == H5G_CACHED_SLINK) { + const char *s; /* Pointer to link value */ + const H5HL_t *heap; /* Pointer to local heap for group */ - s = H5HL_offset_into(f, heap, ent->cache.slink.lval_offset); + /* Lock the local heap */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, lheap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") - /* Copy the link value */ - lnk->u.soft.name = H5MM_xstrdup(s); + s = H5HL_offset_into(f, heap, ent->cache.slink.lval_offset); - /* Release the local heap */ - if(H5HL_unprotect(f, dxpl_id, heap, lheap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") + /* Copy the link value */ + lnk->u.soft.name = H5MM_xstrdup(s); - /* Set link type */ - lnk->type = H5L_TYPE_SOFT; - } - break; + /* Release the local heap */ + if(H5HL_unprotect(f, dxpl_id, heap, lheap_addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") - default: - /* Set address of object */ - lnk->u.hard.addr = ent->header; + /* Set link type */ + lnk->type = H5L_TYPE_SOFT; + } /* end if */ + else { + /* Set address of object */ + lnk->u.hard.addr = ent->header; - /* Set link type */ - lnk->type = H5L_TYPE_HARD; - break; - } /* end switch */ + /* Set link type */ + lnk->type = H5L_TYPE_HARD; + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -802,10 +798,10 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_link_lookup_by_corder + * Function: H5G_link_lookup_by_idx * - * Purpose: Look up an object in a group using link messages, according - * the link's creation order. + * Purpose: Look up an object in a group using link messages, + * according to the order of an index * * Return: Non-negative on success/Negative on failure * @@ -816,13 +812,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_link_lookup_by_corder(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, - H5_iter_order_t order, hsize_t n, H5O_link_t *lnk) +H5G_link_lookup_by_idx(H5O_loc_t *oloc, 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) { H5G_link_table_t ltable = {0, NULL}; /* Link table */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_link_lookup_by_corder, FAIL) + FUNC_ENTER_NOAPI(H5G_link_lookup_by_idx, FAIL) /* check arguments */ HDassert(oloc && oloc->file); @@ -830,7 +826,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_CRT_ORDER, order, <able) < 0) + if(H5G_link_build_table(oloc, dxpl_id, linfo, idx_type, order, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table") /* Check for going out of bounds */ @@ -850,5 +846,5 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_link_lookup_by_corder() */ +} /* end H5G_link_lookup_by_idx() */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index ac74dfa..978cbe2 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1448,20 +1448,17 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad const H5HL_t *heap = NULL; unsigned nsyms; /* # of symbols in node */ H5G_entry_t *ents = NULL; /* Copy of entries in this node */ - size_t n; - const char *name; - char buf[1024], *s; unsigned u; /* Local index variable */ int ret_value; - FUNC_ENTER_NOAPI(H5G_node_iterate, H5B_ITER_ERROR); + FUNC_ENTER_NOAPI(H5G_node_iterate, H5B_ITER_ERROR) /* * Check arguments. */ - assert(f); - assert(H5F_addr_defined(addr)); - assert(udata); + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(udata); /* * Save information about the symbol table node since we can't lock it @@ -1478,8 +1475,7 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad sn = NULL; HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header") } /* end if */ - - sn=NULL; /* Make certain future references will be caught */ + sn = NULL; /* Make certain future references will be caught */ /* * Iterate over the symbol table node entries. @@ -1488,6 +1484,10 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad if(udata->skip > 0) --udata->skip; else { + size_t n; /* Length of link name */ + const char *name; /* Pointer to link name in heap */ + char buf[1024], *s; /* Buffer for link name & pointer to link name */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr))) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name") @@ -1552,8 +1552,8 @@ done: if(ents) H5FL_SEQ_FREE(H5G_entry_t, ents); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_node_iterate() */ /*------------------------------------------------------------------------- @@ -1577,27 +1577,27 @@ H5G_node_sumup(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr H5G_node_t *sn = NULL; int ret_value = H5B_ITER_CONT; - FUNC_ENTER_NOAPI(H5G_node_sumup, H5B_ITER_ERROR); + FUNC_ENTER_NOAPI(H5G_node_sumup, H5B_ITER_ERROR) /* * Check arguments. */ - assert(f); - assert(H5F_addr_defined(addr)); - assert(num_objs); + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(num_objs); /* Find the object node and add the number of symbol entries. */ - if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node"); + if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node") *num_objs += sn->nsyms; done: - if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); + if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header") - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_node_sumup() */ /*------------------------------------------------------------------------- @@ -1615,125 +1615,50 @@ done: *------------------------------------------------------------------------- */ int -H5G_node_name(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, +H5G_node_by_idx(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, const void UNUSED *_rt_key, void *_udata) { - H5G_bt_it_ud2_t *udata = (H5G_bt_it_ud2_t *)_udata; - const H5HL_t *heap = NULL; - size_t name_off; - hsize_t loc_idx; - const char *name; + H5G_bt_it_idx_common_t *udata = (H5G_bt_it_idx_common_t *)_udata; H5G_node_t *sn = NULL; int ret_value = H5B_ITER_CONT; - FUNC_ENTER_NOAPI(H5G_node_name, H5B_ITER_ERROR); + FUNC_ENTER_NOAPI(H5G_node_by_idx, H5B_ITER_ERROR); /* * Check arguments. */ - assert(f); - assert(H5F_addr_defined(addr)); - assert(udata); - - if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node"); - - /* Find the node, locate the object symbol table entry and retrieve the name */ - if(udata->idx >= udata->num_objs && udata->idx < (udata->num_objs + sn->nsyms)) { - loc_idx = udata->idx - udata->num_objs; - name_off = sn->entry[loc_idx].name_off; - - if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name"); - - name = H5HL_offset_into(f, heap, name_off); - assert (name); - udata->name = H5MM_strdup (name); - assert(udata->name); - - if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name"); - heap=NULL; name=NULL; - - ret_value = H5B_ITER_STOP; - } else { - udata->num_objs += sn->nsyms; - } - -done: - if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); - - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_node_type - * - * Purpose: This function gets called during a group iterate operation - * to return object type by given idx. - * - * Return: 0 if object isn't found in this node; 1 if found; - * Negative on failure - * - * Programmer: Raymond Lu - * Nov 20, 2002 - * - *------------------------------------------------------------------------- - */ -int -H5G_node_type(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, - const void UNUSED *_rt_key, void *_udata) -{ - H5G_bt_it_ud3_t *udata = (H5G_bt_it_ud3_t*)_udata; - H5G_node_t *sn = NULL; - int ret_value = H5B_ITER_CONT; - - FUNC_ENTER_NOAPI(H5G_node_type, H5B_ITER_ERROR) - - /* Check arguments. */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(udata); - /* Find the node, locate the object symbol table entry and retrieve the type */ + /* Get a pointer to the symbol table node */ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node"); + /* Find the node, locate the object symbol table entry and retrieve the name */ if(udata->idx >= udata->num_objs && udata->idx < (udata->num_objs + sn->nsyms)) { - H5O_loc_t tmp_oloc; /* Temporary object location */ - hsize_t loc_idx; + hsize_t ent_idx; /* Entry index in this node */ /* Compute index of entry */ - loc_idx = udata->idx - udata->num_objs; + ent_idx = udata->idx - udata->num_objs; - /* Check for a soft link */ - switch(sn->entry[loc_idx].type) { - case H5G_CACHED_SLINK: - udata->type = H5G_LINK; - break; + /* Call 'by index' callback */ + HDassert(udata->op); + if((udata->op)(&sn->entry[ent_idx], udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_INS_ERROR, "'by index' callback failed") - default: - /* Build temporary object location */ - tmp_oloc.file = f; - HDassert(H5F_addr_defined(sn->entry[loc_idx].header)); - tmp_oloc.addr = sn->entry[loc_idx].header; - - udata->type = H5O_obj_type(&tmp_oloc, dxpl_id); - break; - } + /* Indicate that we found the entry we are interested in */ ret_value = H5B_ITER_STOP; - } else { + } /* end if */ + else udata->num_objs += sn->nsyms; - } /* end else */ done: if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header"); + HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value); -} /* end H5G_node_type() */ +} /* end H5G_node_by_idx() */ /*------------------------------------------------------------------------- @@ -1876,7 +1801,7 @@ int H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, const void UNUSED *_rt_key, void *_udata) { - H5G_bt_it_ud5_t *udata = (H5G_bt_it_ud5_t *)_udata; + H5G_bt_it_cpy_t *udata = (H5G_bt_it_cpy_t *)_udata; const H5O_loc_t *src_oloc = udata->src_oloc; H5O_copy_t *cpy_info = udata->cpy_info; const H5HL_t *heap = NULL; diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 515b822..cc60366 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -1171,42 +1171,29 @@ H5G_obj_lookup_by_idx(H5O_loc_t *grp_oloc, H5L_index_t idx_type, /* Attempt to get the link info message for this group */ if(H5O_read(grp_oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { - /* Check for query on the name */ - if(idx_type == H5L_INDEX_NAME) { - /* Check for dense link storage */ - if(H5F_addr_defined(linfo.link_fheap_addr)) { - /* Get the object's info from the dense link storage */ - if(H5G_dense_lookup(grp_oloc->file, dxpl_id, &linfo, "", 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 */ - if(H5G_link_lookup(grp_oloc, "", lnk, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") - } /* end else */ - } /* end if */ - else { + /* Check for creation order tracking, if creation order index lookup requested */ + if(idx_type == H5L_INDEX_CRT_ORDER) { H5O_ginfo_t ginfo; /* Group info message */ - /* Get group info message, to see if creation order is stored for links in this group */ + /* Get group info message, to see if creation order is tracked for links in this group */ if(NULL == H5O_read(grp_oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info message for group") /* Check if creation order is tracked */ if(!ginfo.track_corder) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "creation order not tracked for links in group") + } /* end if */ - /* Check for dense link storage */ - if(H5F_addr_defined(linfo.link_fheap_addr)) { - /* 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 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 */ + /* Check for dense link storage */ + if(H5F_addr_defined(linfo.link_fheap_addr)) { + /* 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 link from the link messages */ + if(H5G_link_lookup_by_idx(grp_oloc, dxpl_id, &linfo, idx_type, order, n, lnk) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") } /* end else */ } /* end if */ else { @@ -1216,13 +1203,9 @@ H5G_obj_lookup_by_idx(H5O_loc_t *grp_oloc, H5L_index_t idx_type, /* Can only perform name lookups on groups with symbol tables */ if(idx_type != H5L_INDEX_NAME) HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query") -if(order == H5_ITER_DEC) { - HDfprintf(stderr, "%s: decreasing order query on symbol table not implemented yet!\n", FUNC); - HGOTO_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, "decreasing order query on symbol table not implemented yet") -} /* end if */ /* Get the object's info from the symbol table */ - if(H5G_stab_lookup(grp_oloc, "", lnk, dxpl_id) < 0) + if(H5G_stab_lookup_by_idx(grp_oloc, order, n, lnk, dxpl_id) < 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 34eec8e..00118a2 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -212,55 +212,54 @@ typedef struct H5G_bt_it_ud1_t { int *final_ent; /*final entry looked at */ } H5G_bt_it_ud1_t; -/* - * Data exchange structure to pass through the B-tree layer for the - * H5B_iterate function. - */ -typedef struct H5G_bt_it_ud2_t { +/* Data passed through B-tree iteration for copying copy symbol table content */ +typedef struct H5G_bt_it_cpy_t { + const H5O_loc_t *src_oloc; /* Source object location */ + haddr_t src_heap_addr; /* Heap address of the source symbol table */ + H5F_t *dst_file; /* File of destination group */ + H5O_stab_t *dst_stab; /* Symbol table message for destination group */ + H5O_copy_t *cpy_info; /* Information for copy operation */ +} H5G_bt_it_cpy_t; + +/* Common information for "by index" lookups in symbol tables */ +typedef struct H5G_bt_it_idx_common_t { + /* downward */ + H5F_t *f; /* Pointer to file that symbol table is in */ + hid_t dxpl_id; /* DXPL for operation */ + hsize_t idx; /* Index of group member to be queried */ + hsize_t num_objs; /* The number of objects having been traversed */ + H5G_bt_find_op_t op; /* Operator to call when correct entry is found */ +} H5G_bt_it_idx_common_t; + +/* Data passed through B-tree iteration for looking up a name by index */ +typedef struct H5G_bt_it_idx1_t { /* downward */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ haddr_t heap_addr; /*symbol table heap address */ - hsize_t idx; /*index of group member to be queried */ - hsize_t num_objs; /*the number of objects having been traversed*/ /* upward */ char *name; /*member name to be returned */ -} H5G_bt_it_ud2_t; +} H5G_bt_it_idx1_t; -/* - * Data exchange structure to pass through the B-tree layer for the - * H5B_iterate function. - */ -typedef struct H5G_bt_it_ud3_t { +/* Data passed through B-tree iteration for looking up a type by index */ +typedef struct H5G_bt_it_idx2_t { /* downward */ - hsize_t idx; /*index of group member to be queried */ - hsize_t num_objs; /*the number of objects having been traversed*/ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ /* upward */ H5G_obj_t type; /*member type to be returned */ -} H5G_bt_it_ud3_t; +} H5G_bt_it_idx2_t; -/* - * Data exchange structure to pass through the B-tree layer for the - * H5B_iterate function. - */ -typedef struct H5G_bt_it_ud4_t { +/* Data passed through B-tree iteration for looking up a link by index */ +typedef struct H5G_bt_it_idx3_t { /* downward */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ haddr_t heap_addr; /*symbol table heap address */ - size_t max_links; /* Max. # of links array can store */ /* upward */ - H5O_link_t *lnk_table; /* Pointer to array of links to fill in */ - size_t nlinks; /* Links inserted into table */ -} H5G_bt_it_ud4_t; - -/* Data passed to B-tree iteration for copying copy symblol table content */ -typedef struct H5G_bt_it_ud5_t { - const H5O_loc_t *src_oloc; /* Source object location */ - haddr_t src_heap_addr; /* Heap address of the source symbol table */ - H5F_t *dst_file; /* File of destination group */ - H5O_stab_t *dst_stab; /* Symbol table message for destination group */ - H5O_copy_t *cpy_info; /* Information for copy operation */ -} H5G_bt_it_ud5_t; + H5O_link_t *lnk; /*link to be returned */ + hbool_t found; /*whether we found the link */ +} H5G_bt_it_idx3_t; /* Typedefs for "new format" groups */ /* (fractal heap & v2 B-tree info) */ @@ -276,7 +275,7 @@ typedef struct H5G_dense_bt2_name_rec_t { /* (Keep 'id' field first so generic record handling in callbacks works) */ typedef struct H5G_dense_bt2_corder_rec_t { uint8_t id[H5G_DENSE_FHEAP_ID_LEN]; /* Heap ID for link */ - uint64_t corder; /* 'creation order' field value */ + int64_t corder; /* 'creation order' field value */ } H5G_dense_bt2_corder_rec_t; /* @@ -291,7 +290,7 @@ typedef struct H5G_bt2_ud_common_t { 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 */ + int64_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; @@ -383,6 +382,8 @@ H5_DLL herr_t H5G_stab_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id); H5_DLL herr_t H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, hid_t dxpl_id); +H5_DLL herr_t H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, + hsize_t n, H5O_link_t *lnk, hid_t dxpl_id); /* * Functions that understand symbol table entries. @@ -405,9 +406,7 @@ H5_DLL int H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_ const void *_rt_key, void *_udata); H5_DLL int H5G_node_sumup(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata); -H5_DLL int H5G_node_name(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr, - const void *_rt_key, void *_udata); -H5_DLL int H5G_node_type(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr, +H5_DLL int H5G_node_by_idx(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata); H5_DLL int H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata); @@ -431,9 +430,9 @@ H5_DLL herr_t H5G_link_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t int *last_obj, H5G_link_iterate_t op, void *op_data); H5_DLL herr_t H5G_link_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, hid_t dxpl_id); -H5_DLL herr_t H5G_link_lookup_by_corder(H5O_loc_t *oloc, hid_t dxpl_id, - const H5O_linfo_t *linfo, H5_iter_order_t order, hsize_t n, - H5O_link_t *lnk); +H5_DLL herr_t H5G_link_lookup_by_idx(H5O_loc_t *oloc, 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); /* 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, diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 81b9916..9dc945b 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -443,7 +443,7 @@ herr_t H5G_stab_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id) { H5O_stab_t stab; /* Info about symbol table */ - herr_t ret_value; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5G_stab_count, FAIL) @@ -459,8 +459,8 @@ H5G_stab_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") /* Iterate over the group members */ - if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, num_objs)) < 0) - HERROR(H5E_SYM, H5E_CANTINIT, "iteration operator failed"); + if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, num_objs) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed") done: FUNC_LEAVE_NOAPI(ret_value) @@ -468,6 +468,55 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_stab_get_name_by_idx_cb + * + * Purpose: Callback for B-tree iteration 'by index' info query to + * retrieve the name of a link + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Nov 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_stab_get_name_by_idx_cb(const H5G_entry_t *ent, void *_udata) +{ + H5G_bt_it_idx1_t *udata = (H5G_bt_it_idx1_t *)_udata; + const H5HL_t *heap = NULL; /* Pointer to local heap for group */ + size_t name_off; /* Offset of name in heap */ + const char *name; /* Pointer to name string in heap */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_stab_get_name_by_idx) + + /* Sanity check */ + HDassert(ent); + HDassert(udata); + + /* Get name offset in heap */ + name_off = ent->name_off; + + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(udata->common.f, udata->common.dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") + + name = H5HL_offset_into(udata->common.f, heap, name_off); + HDassert(name); + udata->name = H5MM_strdup(name); + HDassert(udata->name); + +done: + if(heap && H5HL_unprotect(udata->common.f, udata->common.dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_get_name_by_idx_cb */ + + +/*------------------------------------------------------------------------- * Function: H5G_stab_get_name_by_idx * * Purpose: Returns the name of objects in the group by giving index. @@ -485,7 +534,7 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, size_t size, hid_t dxpl_id) { H5O_stab_t stab; /* Info about local heap & B-tree */ - H5G_bt_it_ud2_t udata; /* Iteration information */ + H5G_bt_it_idx1_t udata; /* Iteration information */ ssize_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_stab_get_name_by_idx, FAIL) @@ -498,17 +547,20 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") /* Set iteration information */ - udata.idx = idx; - udata.num_objs = 0; + udata.common.f = oloc->file; + udata.common.dxpl_id = dxpl_id; + udata.common.idx = idx; + udata.common.num_objs = 0; + udata.common.op = H5G_stab_get_name_by_idx_cb; udata.heap_addr = stab.heap_addr; udata.name = NULL; /* Iterate over the group members */ - if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_name, stab.btree_addr, &udata)) < 0) + if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_by_idx, stab.btree_addr, &udata) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed") /* If we don't know the name now, we almost certainly went out of bounds */ - if(udata.name==NULL) + if(udata.name == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") /* Get the length of the name */ @@ -516,20 +568,67 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, /* Copy the name into the user's buffer, if given */ if(name) { - HDstrncpy(name, udata.name, MIN((size_t)(ret_value+1),size)); + HDstrncpy(name, udata.name, MIN((size_t)(ret_value + 1),size)); if((size_t)ret_value >= size) - name[size-1]='\0'; + name[size - 1]='\0'; } /* end if */ done: /* Free the duplicated name */ - if(udata.name!=NULL) + if(udata.name != NULL) H5MM_xfree(udata.name); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_get_name_by_idx() */ /*------------------------------------------------------------------------- + * Function: H5G_stab_get_type_by_idx_cb + * + * Purpose: Callback for B-tree iteration 'by index' info query to + * retrieve the type of an object + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Nov 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_stab_get_type_by_idx_cb(const H5G_entry_t *ent, void *_udata) +{ + H5G_bt_it_idx2_t *udata = (H5G_bt_it_idx2_t *)_udata; + H5O_loc_t tmp_oloc; /* Temporary object location */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_stab_get_type_by_idx) + + /* Sanity check */ + HDassert(ent); + HDassert(udata); + + /* Check for a soft link */ + switch(ent->type) { + case H5G_CACHED_SLINK: + udata->type = H5G_LINK; + break; + + default: + /* Build temporary object location */ + tmp_oloc.file = udata->common.f; + HDassert(H5F_addr_defined(ent->header)); + tmp_oloc.addr = ent->header; + + udata->type = H5O_obj_type(&tmp_oloc, udata->common.dxpl_id); + break; + } /* end switch */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G_stab_get_type_by_idx_cb */ + + +/*------------------------------------------------------------------------- * Function: H5G_get_objtype_by_idx * * Purpose: Private function for H5Gget_objtype_by_idx. @@ -548,7 +647,7 @@ H5G_obj_t H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) { H5O_stab_t stab; /* Info about local heap & B-tree */ - H5G_bt_it_ud3_t udata; /* User data for B-tree callback */ + H5G_bt_it_idx2_t udata; /* User data for B-tree callback */ H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_stab_get_type_by_idx, H5G_UNKNOWN) @@ -561,12 +660,15 @@ H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "unable to determine local heap address") /* Set iteration information */ - udata.idx = idx; - udata.num_objs = 0; + udata.common.f = oloc->file; + udata.common.dxpl_id = dxpl_id; + udata.common.idx = idx; + udata.common.num_objs = 0; + udata.common.op = H5G_stab_get_type_by_idx_cb; udata.type = H5G_UNKNOWN; /* Iterate over the group members */ - if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_type, stab.btree_addr, &udata) < 0) + if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_by_idx, stab.btree_addr, &udata) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed") /* If we don't know the type now, we almost certainly went out of bounds */ @@ -670,3 +772,143 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup() */ + +/*------------------------------------------------------------------------- + * Function: H5G_stab_lookup_by_idx_cb + * + * Purpose: Callback for B-tree iteration 'by index' info query to + * retrieve the link + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Nov 9, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata) +{ + H5G_bt_it_idx3_t *udata = (H5G_bt_it_idx3_t *)_udata; + const H5HL_t *heap; /* Pointer to local heap for group */ + size_t name_off; /* Offset of name in heap */ + const char *name; /* Pointer to name string in heap */ + size_t name_len; /* Length of link name */ + char buf[1024]; /* Buffer for name */ + char *s = NULL; /* Pointer to copy of name string */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_stab_lookup_by_idx_cb) + + /* Sanity check */ + HDassert(ent); + HDassert(udata); + + /* Get name offset in heap */ + name_off = ent->name_off; + + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(udata->common.f, udata->common.dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") + + /* Duplicate the link name */ + name = H5HL_offset_into(udata->common.f, heap, name_off); + HDassert(name); + name_len = HDstrlen(name); + + /* Allocate space or point to existing buffer */ + if((name_len + 1) > sizeof(buf)) { + if(NULL == (s = H5MM_malloc(name_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + } /* end if */ + else + s = buf; + + /* Make a copy of the name */ + HDstrcpy(s, name); + + /* Unlock the heap */ + if(H5HL_unprotect(udata->common.f, udata->common.dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") + heap = NULL; name = NULL; + + /* Convert the entry to a link */ + if(H5G_link_convert(udata->common.f, udata->common.dxpl_id, udata->lnk, udata->heap_addr, ent, s) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link") + udata->found = TRUE; + +done: + /* Free the memory for the name, if we used a dynamically allocated buffer */ + if(s && s != buf) + H5MM_xfree(s); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_lookup_by_idx_cb */ + + +/*------------------------------------------------------------------------- + * Function: H5G_stab_lookup_by_idx + * + * Purpose: Look up an object in a group, according to the name index + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 7 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, + H5O_link_t *lnk, hid_t dxpl_id) +{ + H5G_bt_it_idx3_t udata; /* Iteration information */ + H5O_stab_t stab; /* Symbol table message */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_stab_lookup_by_idx, FAIL) + + /* check arguments */ + HDassert(grp_oloc && grp_oloc->file); + HDassert(lnk); + + /* Get the B-tree & local heap info */ + if(NULL == H5O_read(grp_oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + + /* Remap index for decreasing iteration order */ + if(order == H5_ITER_DEC) { + hsize_t nlinks = 0; /* Number of links in group */ + + /* Iterate over the symbol table nodes, to count the links */ + if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, &nlinks) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed"); + + /* Map decreasing iteration order index to increasing iteration order index */ + n = nlinks - (n + 1); + } /* end if */ + + /* Set iteration information */ + udata.common.f = grp_oloc->file; + udata.common.dxpl_id = dxpl_id; + udata.common.idx = n; + udata.common.num_objs = 0; + udata.common.op = H5G_stab_lookup_by_idx_cb; + udata.heap_addr = stab.heap_addr; + udata.lnk = lnk; + udata.found = FALSE; + + /* Iterate over the group members */ + if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, H5G_node_by_idx, stab.btree_addr, &udata) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed") + + /* If we didn't find the link, we almost certainly went out of bounds */ + if(!udata.found) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_stab_lookup_by_idx() */ + diff --git a/src/H5Ostab.c b/src/H5Ostab.c index c15d676..85f7493 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -365,7 +365,7 @@ H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc { const H5O_stab_t *stab_src = (const H5O_stab_t *)mesg_src; H5O_stab_t *stab_dst = (H5O_stab_t *)mesg_dst; - H5G_bt_it_ud5_t udata; /* B-tree user data */ + H5G_bt_it_cpy_t udata; /* B-tree user data */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_stab_post_copy_file) diff --git a/test/links.c b/test/links.c index 4dce7de..e16b7ee 100644 --- a/test/links.c +++ b/test/links.c @@ -74,6 +74,7 @@ const char *FILENAME[] = { /* Creation order macros */ #define CORDER_GROUP_NAME "corder_group" +#define CORDER_NLINKS 17 #define CORDER_EST_ENTRY_LEN 9 #ifndef QAK @@ -5902,6 +5903,100 @@ error: /*------------------------------------------------------------------------- + * Function: corder_info_check + * + * Purpose: Support routine for corder_info_by_idx, to verify the link + * info is correct for a link + * + * Note: This routine assumes that the links have been inserted in the + * group in alphabetical order. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, November 7, 2006 + * + *------------------------------------------------------------------------- + */ +static int +corder_info_check(hid_t group_id, hsize_t n, hbool_t use_index) +{ + H5L_info_t linfo; /* Link info struct */ + + /* 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, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for new link */ + if(linfo.corder != (int64_t)n) 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 native creation order (which is increasing) */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for new link */ + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Don't test "native" order if there is no index */ + if(use_index) { + /* Get the link information for first link, in native creation order (which is increasing) */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_NATIVE, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link */ + if(linfo.corder != 0) TEST_ERROR + } /* end if */ + + /* 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 != (int64_t)n) 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, n, &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 increasing link name order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for new link */ + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Get the link information for first link, in increasing link name order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, 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 link name order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for new link */ + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Get the link information for first link, in decreasing link name order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify the link information for first link */ + if(linfo.corder != 0) TEST_ERROR + + /* Success */ + return(0); + +error: + /* Failure */ + return(-1); +} /* end corder_info_check() */ + + +/*------------------------------------------------------------------------- * Function: corder_info_by_idx * * Purpose: Create a group with creation order indices and test querying @@ -5916,7 +6011,7 @@ error: *------------------------------------------------------------------------- */ static int -corder_info_by_idx(hid_t fapl) +corder_info_by_idx(hid_t fapl, hbool_t use_index) { hid_t file_id = (-1); /* File ID */ hid_t group_id = (-1), group_id2 = (-1); /* Group IDs */ @@ -5929,7 +6024,10 @@ corder_info_by_idx(hid_t fapl) unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ - TESTING("querying info by index") + if(use_index) + TESTING("querying info by index w/creation order index") + else + TESTING("querying info by index w/o creation order index") /* Create file */ /* (with creation order tracking for the root group) */ @@ -5940,7 +6038,8 @@ corder_info_by_idx(hid_t fapl) 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(use_index) + 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 */ @@ -5956,29 +6055,8 @@ 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 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 link information for new link */ + if(corder_info_check(group_id, (hsize_t)u, use_index) < 0) TEST_ERROR } /* end for */ /* Check for out of bound offset */ @@ -5996,39 +6074,109 @@ 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 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 state of group */ + if(H5G_is_new_dense_test(group_id) != TRUE) TEST_ERROR - /* Verify the link information for new link */ - if(linfo.corder != u) TEST_ERROR + /* Verify link information for new link */ + if(corder_info_check(group_id, (hsize_t)u, use_index) < 0) 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 + /* Close the group */ + if(H5Gclose(group_id) < 0) TEST_ERROR - /* Verify the link information for first link */ - if(linfo.corder != 0) TEST_ERROR + /* Close the group creation property list */ + if(H5Pclose(gcpl_id) < 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 + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR - /* Verify the link information for new link */ - if(linfo.corder != u) TEST_ERROR + PASSED(); + return 0; - /* 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 +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl_id); + H5Gclose(group_id); + H5Fclose(file_id); + } H5E_END_TRY; + return -1; +} /* end corder_info_by_idx() */ - /* Verify the link information for first link */ - if(linfo.corder != 0) TEST_ERROR + +/*------------------------------------------------------------------------- + * Function: corder_info_by_idx_old + * + * Purpose: Create a old-format group and test querying + * info by index. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, November 7, 2006 + * + *------------------------------------------------------------------------- + */ +static int +corder_info_by_idx_old(hid_t fapl) +{ + hid_t file_id = (-1); /* File ID */ + hid_t group_id = (-1), group_id2 = (-1); /* Group IDs */ + H5L_info_t linfo; /* Link info struct */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename[NAME_BUF_SIZE];/* File name */ + haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + TESTING("querying info by index in old-style group") + + /* 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 with creation order indexing & tracking on */ + if((group_id = H5Gcreate(file_id, CORDER_GROUP_NAME, (size_t)0)) < 0) TEST_ERROR + + /* Create several links */ + for(u = 0; u < CORDER_NLINKS; u++) { + H5G_stat_t sb; /* Buffer for querying object's info */ + + sprintf(objname, "filler %02u", u); + if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gget_objinfo(group_id2, ".", FALSE, &sb) < 0) TEST_ERROR +#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG + objno[u] = (haddr_t)sb.objno[0] | ((haddr_t)sb.objno[1] << (8 * sizeof(long))); +#else + objno[u] = (haddr_t)sb.objno[0]; +#endif + if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end for */ + + /* Verify link information for new link (in increasing order) */ + for(u = 0; u < CORDER_NLINKS; u++) { + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR + } /* end for */ + + /* Verify link information for new link (in decreasing order) */ + for(u = 0; u < CORDER_NLINKS; u++) { + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5F_addr_ne(linfo.u.address, objno[CORDER_NLINKS - (u + 1)])) TEST_ERROR + } /* end for */ + + /* Check for creation order index query */ + 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 /* Verify state of group */ - if(H5G_is_new_dense_test(group_id) != TRUE) TEST_ERROR + if(H5G_has_stab_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 @@ -6037,12 +6185,11 @@ corder_info_by_idx(hid_t fapl) error: H5E_BEGIN_TRY { - H5Pclose(gcpl_id); H5Gclose(group_id); H5Fclose(file_id); } H5E_END_TRY; return -1; -} /* end corder_create_dense() */ +} /* end corder_info_by_idx_old() */ /*------------------------------------------------------------------------- @@ -6137,7 +6284,7 @@ main(void) nerrors += check_all_closed((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0; - /* Creation order tests */ + /* New group revision feature tests */ if(new_format == TRUE) { nerrors += corder_create_empty(fapl2) < 0 ? 1 : 0; /* XXX: when creation order indexing is fully working, go back and add checks @@ -6148,8 +6295,13 @@ main(void) nerrors += corder_create_dense(fapl2) < 0 ? 1 : 0; nerrors += corder_transition(fapl2) < 0 ? 1 : 0; nerrors += corder_delete(fapl2) < 0 ? 1 : 0; - nerrors += corder_info_by_idx(fapl2) < 0 ? 1 : 0; + nerrors += corder_info_by_idx(fapl2, TRUE) < 0 ? 1 : 0; + nerrors += corder_info_by_idx(fapl2, FALSE) < 0 ? 1 : 0; } /* end if */ + else { + /* Test new API calls on old-style groups */ + nerrors += corder_info_by_idx_old(fapl) < 0 ? 1 : 0; + } } /* end for */ #else /* QAK */ nerrors += corder_create_empty(fapl2) < 0 ? 1 : 0; @@ -6161,7 +6313,11 @@ main(void) nerrors += corder_create_dense(fapl2) < 0 ? 1 : 0; nerrors += corder_transition(fapl2) < 0 ? 1 : 0; nerrors += corder_delete(fapl2) < 0 ? 1 : 0; - nerrors += corder_info_by_idx(fapl2) < 0 ? 1 : 0; + nerrors += corder_info_by_idx(fapl2, TRUE) < 0 ? 1 : 0; + nerrors += corder_info_by_idx(fapl2, FALSE) < 0 ? 1 : 0; + + /* Test new API calls on old-style groups */ + nerrors += corder_info_by_idx_old(fapl) < 0 ? 1 : 0; #endif /* QAK */ /* Close 2nd FAPL */ |