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