summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Gbtree2.c4
-rw-r--r--src/H5Gdense.c42
-rw-r--r--src/H5Glink.c64
-rw-r--r--src/H5Gnode.c151
-rw-r--r--src/H5Gobj.c47
-rw-r--r--src/H5Gpkg.h83
-rw-r--r--src/H5Gstab.c272
-rw-r--r--src/H5Ostab.c2
-rw-r--r--test/links.c258
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, &ltable) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "error building table of links")
+
+ /* Copy link information */
+ if(NULL == H5O_copy(H5O_LINK_ID, &ltable.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(&ltable) < 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, &ltable) < 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, &ltable) < 0)
+ if(H5G_link_build_table(oloc, dxpl_id, linfo, idx_type, order, &ltable) < 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 */