diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-11-11 04:15:27 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-11-11 04:15:27 (GMT) |
commit | a9af13d9871afc2afdb308e999d2c0b823ab0033 (patch) | |
tree | fd093b58d06be1078db76a03faff4abed669ddef | |
parent | b7826900273e403c29810bafc32218e210a43a79 (diff) | |
download | hdf5-a9af13d9871afc2afdb308e999d2c0b823ab0033.zip hdf5-a9af13d9871afc2afdb308e999d2c0b823ab0033.tar.gz hdf5-a9af13d9871afc2afdb308e999d2c0b823ab0033.tar.bz2 |
[svn-r12890] Description:
Finished implementation of H5Lget_info_by_idx for all cases: old vs. new
group formats, compact vs. dense new link storage, increasing vs. decreasing
vs. native iteration order.
Also, refactor symbol table "foo by index" routines to be more generic
and share more code by using a single B-tree iteration callback which makes
callbacks to a specific "get <foo>" callback.
Tested on:
Mac OS X/32 10.4.8 (amazon)
FreeBSD/32 4.11 (sleipnir)
Linux/32 2.4 (heping)
Linux/64 2.4 (mir)
AIX/32 5.? (copper)
-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 */ |