summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-02-13 14:50:48 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-02-13 14:50:48 (GMT)
commit56e63bdeea4bd94b46dd3e962e457959e4fe636c (patch)
treec1dcd9332f26691c1a12eb0bdb0c025fc1c91fd5 /src
parent46e24b92bfabd15d5cd09d2373914daa18e7bad3 (diff)
downloadhdf5-56e63bdeea4bd94b46dd3e962e457959e4fe636c.zip
hdf5-56e63bdeea4bd94b46dd3e962e457959e4fe636c.tar.gz
hdf5-56e63bdeea4bd94b46dd3e962e457959e4fe636c.tar.bz2
[svn-r13287] Description:
Add H5Aget_info_by_idx & H5Aget_name_by_idx routines, along with refactoring underlying indices code to handle those sort of queries. Simplify the link callback routines a bit. Minor other cleanups. Tested on: Mac OS X/32 10.4.8 (amazon) FreeBSD/32 6.2 (duty)
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c77
-rw-r--r--src/H5Adense.c61
-rw-r--r--src/H5Aint.c158
-rw-r--r--src/H5Apkg.h10
-rw-r--r--src/H5Apublic.h3
-rw-r--r--src/H5Gdense.c51
-rw-r--r--src/H5L.c259
-rw-r--r--src/H5Oattribute.c28
-rw-r--r--src/H5Opkg.h4
9 files changed, 351 insertions, 300 deletions
diff --git a/src/H5A.c b/src/H5A.c
index 116ee9e..35773df 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -1182,10 +1182,10 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
/* get the real attribute length */
nbytes = HDstrlen(attr->name);
- assert((ssize_t)nbytes>=0); /*overflow, pretty unlikey --rpm*/
+ HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/
/* compute the string length which will fit into the user's buffer */
- copy_len = MIN(buf_size-1, nbytes);
+ copy_len = MIN(buf_size - 1, nbytes);
/* Copy all/some of the name */
if(buf && copy_len > 0) {
@@ -1204,6 +1204,66 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Aget_name_by_idx
+ *
+ * Purpose: Retrieve name of an attribute, according to the
+ * order within an index.
+ *
+ * Same pattern of behavior as H5Iget_name.
+ *
+ * Return: Success: Non-negative length of name, with information
+ * in NAME buffer
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * February 8, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5Aget_name_by_idx(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t n, char *name /*out*/, size_t size)
+{
+ H5G_loc_t loc; /* Object location */
+ H5A_t *attr = NULL; /* Attribute object for name */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Aget_name_by_idx, FAIL)
+
+ /* Check args */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+
+ /* Open the attribute on the object header */
+ if(NULL == (attr = H5A_open_by_idx(&loc, idx_type, order, n, H5AC_ind_dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
+
+ /* Get the length of the name */
+ ret_value = (ssize_t)HDstrlen(attr->name);
+
+ /* Copy the name into the user's buffer, if given */
+ if(name) {
+ HDstrncpy(name, attr->name, MIN((size_t)(ret_value + 1), size));
+ if((size_t)ret_value >= size)
+ name[size - 1]='\0';
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(attr && H5A_close(attr) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Aget_name_by_idx() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Aget_storage_size
*
* Purpose: Returns the amount of storage size that is required for this
@@ -1367,7 +1427,7 @@ H5Aget_info_by_idx(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order,
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
done:
- /* Cleanup on failure */
+ /* Release resources */
if(attr && H5A_close(attr) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
@@ -1494,7 +1554,8 @@ H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data)
{
H5G_loc_t loc; /* Object location */
H5A_attr_iter_op_t attr_op; /* Attribute operator */
- unsigned start_idx; /* Index of attribute to start iterating at */
+ hsize_t start_idx; /* Index of attribute to start iterating at */
+ hsize_t last_attr; /* Index of last attribute examined */
herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Aiterate, FAIL)
@@ -1511,11 +1572,13 @@ H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data)
attr_op.u.app_op = op;
/* Call attribute iteration routine */
- start_idx = (attr_num ? (unsigned)*attr_num : 0);
-/* XXX: Uses "native" name index order currently - should use creation order */
- if((ret_value = H5O_attr_iterate(loc_id, loc.oloc, H5AC_ind_dxpl_id, H5_ITER_NATIVE, start_idx, attr_num, &attr_op, op_data)) < 0)
+ last_attr = start_idx = (hsize_t)(attr_num ? *attr_num : 0);
+ if((ret_value = H5O_attr_iterate(loc_id, loc.oloc, H5AC_ind_dxpl_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, start_idx, &last_attr, &attr_op, op_data)) < 0)
HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
+ /* Set the last attribute information */
+ *attr_num = (unsigned)last_attr;
+
done:
FUNC_LEAVE_API(ret_value)
} /* H5Aiterate() */
diff --git a/src/H5Adense.c b/src/H5Adense.c
index e56b0cb..78cdcc8 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -87,13 +87,13 @@ 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 */
+ H5HF_t *fheap; /* Fractal heap handle */
H5HF_t *shared_fheap; /* Fractal heap handle for shared messages */
+ hsize_t count; /* # of attributes examined */
/* downward (from application) */
hid_t loc_id; /* Object ID for application callback */
- unsigned skip; /* Number of attributes to skip */
- unsigned count; /* The # of attributes visited */
+ hsize_t skip; /* Number of attributes to skip */
const H5A_attr_iter_op_t *attr_op; /* Callback for each attribute */
void *op_data; /* Callback data for each attribute */
@@ -965,14 +965,15 @@ done:
*/
herr_t
H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, haddr_t attr_fheap_addr,
- haddr_t name_bt2_addr, H5_iter_order_t order, unsigned skip,
- unsigned *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data)
+ haddr_t name_bt2_addr, haddr_t corder_bt2_addr, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t skip, hsize_t *last_attr,
+ const H5A_attr_iter_op_t *attr_op, void *op_data)
{
- H5A_bt2_ud_it_t udata; /* User data for iterator callback */
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */
- hsize_t nrec; /* # of records in v2 B-tree */
+ 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; /* Return value */
FUNC_ENTER_NOAPI(H5A_dense_iterate, FAIL)
@@ -985,21 +986,34 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, haddr_t attr_fheap_addr
HDassert(H5F_addr_defined(name_bt2_addr));
HDassert(attr_op);
- /* Retrieve # of records in name index */
- /* (# of records in all indices the same) */
- if(H5B2_get_nrec(f, dxpl_id, H5A_BT2_NAME, name_bt2_addr, &nrec) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index")
-
- /* Check for skipping too many attributes */
- if(skip > 0) {
- /* Check for bad starting index */
- if((hsize_t)skip >= nrec)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
+ /* Determine the address of the index to use */
+ if(idx_type == H5_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) {
+ HDassert(H5F_addr_defined(name_bt2_addr));
+ bt2_addr = name_bt2_addr;
+ bt2_class = H5A_BT2_NAME;
+ } /* end if */
+ else
+ bt2_addr = HADDR_UNDEF;
} /* end if */
+ else {
+ HDassert(idx_type == H5_INDEX_CRT_ORDER);
+
+ /* This address may not be defined if creation order is tracked, but
+ * there's no index on it. If there's no v2 B-tree that indexes
+ * the links, a table will be built.
+ */
+ bt2_addr = corder_bt2_addr;
+ bt2_class = H5A_BT2_CORDER;
+ } /* end else */
/* Check on iteration order */
- /* ("native" iteration order is unordered for this attribute storage mechanism) */
- if(order == H5_ITER_NATIVE) {
+ if(order == H5_ITER_NATIVE && H5F_addr_defined(bt2_addr)) {
+ H5A_bt2_ud_it_t udata; /* User data for iterator callback */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
/* Open the fractal heap */
@@ -1039,18 +1053,17 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, haddr_t attr_fheap_addr
/* Iterate over the records in the v2 B-tree's "native" order */
/* (by hash of name) */
- if((ret_value = H5B2_iterate(f, dxpl_id, H5A_BT2_NAME, name_bt2_addr,
- H5A_dense_iterate_bt2_cb, &udata)) < 0)
+ if((ret_value = H5B2_iterate(f, dxpl_id, bt2_class, bt2_addr, H5A_dense_iterate_bt2_cb, &udata)) < 0)
HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed");
- /* Update last attribute looked at */
+ /* Update the last attribute examined, if requested */
if(last_attr)
*last_attr = udata.count;
} /* end if */
else {
/* Build the table of attributes for this object */
- if(H5A_dense_build_table(f, dxpl_id, nrec, attr_fheap_addr, name_bt2_addr,
- H5_INDEX_NAME, order, &atable) < 0)
+ /* (build table using the name index, but sort according to idx_type) */
+ if(H5A_dense_build_table(f, dxpl_id, attr_fheap_addr, name_bt2_addr, idx_type, order, &atable) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "error building table of attributes")
/* Iterate over attributes in table */
diff --git a/src/H5Aint.c b/src/H5Aint.c
index a3d895c..8b4f92a 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -57,6 +57,7 @@ typedef struct {
hid_t dxpl_id; /* DXPL for operation */
H5A_attr_table_t *atable; /* Pointer to attribute table to build */
size_t curr_attr; /* Current attribute to operate on */
+ hbool_t bogus_crt_idx; /* Whether bogus creation index values need to be set */
} H5A_compact_bt_ud_t;
/* Data exchange structure to use when building table of dense attributes for an object */
@@ -114,7 +115,7 @@ static herr_t H5A_attr_sort_table(H5A_attr_table_t *atable, H5_index_t idx_type,
*/
static herr_t
H5A_compact_build_table_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
- unsigned UNUSED sequence, unsigned UNUSED *oh_flags_ptr, void *_udata/*in,out*/)
+ unsigned sequence, unsigned UNUSED *oh_flags_ptr, void *_udata/*in,out*/)
{
H5A_compact_bt_ud_t *udata = (H5A_compact_bt_ud_t *)_udata; /* Operator user data */
herr_t ret_value = H5_ITER_CONT; /* Return value */
@@ -140,6 +141,10 @@ H5A_compact_build_table_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
if(NULL == H5A_copy(&udata->atable->attrs[udata->curr_attr], (const H5A_t *)mesg->native))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+ /* Assign [somewhat arbitrary] creation order value, if requested */
+ if(udata->bogus_crt_idx)
+ udata->atable->attrs[udata->curr_attr].crt_idx = sequence;
+
/* Increment current attribute */
udata->curr_attr++;
@@ -166,9 +171,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5A_compact_build_table(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
- H5_index_t UNUSED idx_type, H5_iter_order_t order,
- H5A_attr_table_t *atable, unsigned *oh_flags)
+H5A_compact_build_table(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_index_t idx_type,
+ H5_iter_order_t order, H5A_attr_table_t *atable, unsigned *oh_flags)
{
H5A_compact_bt_ud_t udata; /* User data for iteration callback */
H5O_mesg_operator_t op; /* Wrapper for operator */
@@ -190,6 +194,7 @@ H5A_compact_build_table(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
udata.dxpl_id = dxpl_id;
udata.atable = atable;
udata.curr_attr = 0;
+ udata.bogus_crt_idx = (oh->version == H5O_VERSION_1) ? TRUE : FALSE;
/* Iterate over existing attributes, checking for attribute with same name */
op.lib_op = H5A_compact_build_table_cb;
@@ -200,7 +205,7 @@ H5A_compact_build_table(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
atable->nattrs = udata.curr_attr;
/* Sort attribute table in correct iteration order */
- if(H5A_attr_sort_table(atable, H5_INDEX_NAME, order) < 0)
+ if(H5A_attr_sort_table(atable, idx_type, order) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSORT, FAIL, "error sorting attribute table")
done:
@@ -255,7 +260,8 @@ done:
* an object
*
* Note: Used for building table of attributes in non-native iteration
- * order for an index
+ * order for an index. Uses the "name" index to retrieve records,
+ * but the 'idx_type' index for sorting them.
*
* Return: Success: Non-negative
* Failure: Negative
@@ -266,11 +272,12 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, hsize_t nattrs, haddr_t attr_fheap_addr,
- haddr_t name_bt2_addr, H5_index_t UNUSED idx_type, H5_iter_order_t order,
+H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, haddr_t attr_fheap_addr,
+ haddr_t name_bt2_addr, H5_index_t idx_type, H5_iter_order_t order,
H5A_attr_table_t *atable)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hsize_t nrec; /* # of records in v2 B-tree */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_build_table)
@@ -280,9 +287,14 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, hsize_t nattrs, haddr_t attr_fhea
HDassert(H5F_addr_defined(name_bt2_addr));
HDassert(atable);
+ /* Retrieve # of records in "name" B-tree */
+ /* (should be same # of records in all indices) */
+ if(H5B2_get_nrec(f, dxpl_id, H5A_BT2_NAME, name_bt2_addr, &nrec) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index")
+
/* Set size of table */
- H5_CHECK_OVERFLOW(nattrs, /* From: */ hsize_t, /* To: */ size_t);
- atable->nattrs = (size_t)nattrs;
+ H5_CHECK_OVERFLOW(nrec, /* From: */ hsize_t, /* To: */ size_t);
+ atable->nattrs = (size_t)nrec;
/* Allocate space for the table entries */
if(atable->nattrs > 0) {
@@ -303,11 +315,12 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, hsize_t nattrs, haddr_t attr_fhea
/* Iterate over the links in the group, building a table of the link messages */
if(H5A_dense_iterate(f, dxpl_id, (hid_t)0, attr_fheap_addr, name_bt2_addr,
- H5_ITER_NATIVE, (unsigned)0, NULL, &attr_op, &udata) < 0)
+ HADDR_UNDEF, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL,
+ &attr_op, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
/* Sort attribute table in correct iteration order */
- if(H5A_attr_sort_table(atable, H5_INDEX_NAME, order) < 0)
+ if(H5A_attr_sort_table(atable, idx_type, order) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSORT, FAIL, "error sorting attribute table")
} /* end if */
else
@@ -332,7 +345,7 @@ done:
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
- * Dec 11 2005
+ * Dec 11 2006
*
*-------------------------------------------------------------------------
*/
@@ -346,6 +359,103 @@ H5A_attr_cmp_name_inc(const void *attr1, const void *attr2)
/*-------------------------------------------------------------------------
+ * Function: H5A_attr_cmp_name_dec
+ *
+ * Purpose: Callback routine for comparing two attribute names, in
+ * decreasing alphabetic order
+ *
+ * Return: An integer less than, equal to, or greater than zero if the
+ * second argument is considered to be respectively less than,
+ * equal to, or greater than the first. If two members compare
+ * as equal, their order in the sorted array is undefined.
+ * (i.e. opposite of strcmp())
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 8 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5A_attr_cmp_name_dec(const void *attr1, const void *attr2)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_name_dec)
+
+ FUNC_LEAVE_NOAPI(HDstrcmp(((const H5A_t *)attr2)->name, ((const H5A_t *)attr1)->name))
+} /* end H5A_attr_cmp_name_dec() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_attr_cmp_corder_inc
+ *
+ * Purpose: Callback routine for comparing two attributes, in
+ * increasing creation order
+ *
+ * Return: An integer less than, equal to, or greater than zero if the
+ * first argument is considered to be respectively less than,
+ * equal to, or greater than the second. If two members compare
+ * as equal, their order in the sorted array is undefined.
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 8 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5A_attr_cmp_corder_inc(const void *attr1, const void *attr2)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_corder_inc)
+
+ if(((const H5A_t *)attr1)->crt_idx < ((const H5A_t *)attr2)->crt_idx)
+ ret_value = -1;
+ else if(((const H5A_t *)attr1)->crt_idx > ((const H5A_t *)attr2)->crt_idx)
+ ret_value = 1;
+ else
+ ret_value = 0;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_attr_cmp_corder_inc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_attr_cmp_corder_dec
+ *
+ * Purpose: Callback routine for comparing two attributes, in
+ * decreasing creation order
+ *
+ * Return: An integer less than, equal to, or greater than zero if the
+ * second argument is considered to be respectively less than,
+ * equal to, or greater than the first. If two members compare
+ * as equal, their order in the sorted array is undefined.
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 8 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5A_attr_cmp_corder_dec(const void *attr1, const void *attr2)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_attr_cmp_corder_dec)
+
+ if(((const H5A_t *)attr1)->crt_idx < ((const H5A_t *)attr2)->crt_idx)
+ ret_value = 1;
+ else if(((const H5A_t *)attr1)->crt_idx > ((const H5A_t *)attr2)->crt_idx)
+ ret_value = -1;
+ else
+ ret_value = 0;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_attr_cmp_corder_dec() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5A_attr_sort_table
*
* Purpose: Sort table containing a list of attributes for an object
@@ -368,31 +478,23 @@ H5A_attr_sort_table(H5A_attr_table_t *atable, H5_index_t idx_type,
HDassert(atable);
/* Pick appropriate comparison routine */
-#ifdef NOT_YET
if(idx_type == H5_INDEX_NAME) {
-#else /* NOT_YET */
-HDassert(idx_type == H5_INDEX_NAME);
-#endif /* NOT_YET */
if(order == H5_ITER_INC)
HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_name_inc);
-#ifdef NOT_YET
else if(order == H5_ITER_DEC)
- HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_link_cmp_name_dec);
-#endif /* NOT_YET */
+ HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_name_dec);
else
HDassert(order == H5_ITER_NATIVE);
-#ifdef NOT_YET
} /* end if */
else {
HDassert(idx_type == H5_INDEX_CRT_ORDER);
if(order == H5_ITER_INC)
- HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_link_cmp_corder_inc);
+ HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_corder_inc);
else if(order == H5_ITER_DEC)
- HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_link_cmp_corder_dec);
+ HDqsort(atable->attrs, atable->nattrs, sizeof(H5A_t), H5A_attr_cmp_corder_dec);
else
HDassert(order == H5_ITER_NATIVE);
} /* end else */
-#endif /* NOT_YET */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5A_attr_sort_table() */
@@ -413,8 +515,8 @@ HDassert(idx_type == H5_INDEX_NAME);
*-------------------------------------------------------------------------
*/
herr_t
-H5A_attr_iterate_table(const H5A_attr_table_t *atable, unsigned skip,
- unsigned *last_attr, hid_t loc_id, const H5A_attr_iter_op_t *attr_op,
+H5A_attr_iterate_table(const H5A_attr_table_t *atable, hsize_t skip,
+ hsize_t *last_attr, hid_t loc_id, const H5A_attr_iter_op_t *attr_op,
void *op_data)
{
size_t u; /* Local index variable */
@@ -431,7 +533,7 @@ H5A_attr_iterate_table(const H5A_attr_table_t *atable, unsigned skip,
*last_attr = skip;
/* Iterate over attribute messages */
- H5_ASSIGN_OVERFLOW(/* To: */ u, /* From: */ skip, /* From: */ unsigned, /* To: */ size_t)
+ H5_ASSIGN_OVERFLOW(/* To: */ u, /* From: */ skip, /* From: */ hsize_t, /* To: */ size_t)
for(; u < atable->nattrs && !ret_value; u++) {
/* Check which type of callback to make */
switch(attr_op->op_type) {
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 708672a..fda8a02 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -194,9 +194,9 @@ H5_DLL herr_t H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh,
H5_DLL herr_t H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh,
const char *old_name, const char *new_name);
H5_DLL herr_t H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id,
- haddr_t attr_fheap_addr, haddr_t name_bt2_addr, H5_iter_order_t order,
- unsigned skip, unsigned *last_attr, const H5A_attr_iter_op_t *attr_op,
- void *op_data);
+ haddr_t attr_fheap_addr, haddr_t name_bt2_addr, haddr_t corder_bt2_addr,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
+ hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data);
H5_DLL herr_t H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh,
const char *name);
H5_DLL htri_t H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh,
@@ -206,11 +206,11 @@ H5_DLL htri_t H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh,
H5_DLL herr_t H5A_compact_build_table(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
H5_index_t idx_type, H5_iter_order_t order, H5A_attr_table_t *atable,
unsigned *oh_flags);
-H5_DLL herr_t H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, hsize_t nattrs,
+H5_DLL herr_t H5A_dense_build_table(H5F_t *f, hid_t dxpl_id,
haddr_t attr_fheap_addr, haddr_t name_bt2_addr, H5_index_t idx_type,
H5_iter_order_t order, H5A_attr_table_t *atable);
H5_DLL herr_t H5A_attr_iterate_table(const H5A_attr_table_t *atable,
- unsigned skip, unsigned *last_attr, hid_t loc_id,
+ hsize_t skip, hsize_t *last_attr, hid_t loc_id,
const H5A_attr_iter_op_t *attr_op, void *op_data);
H5_DLL herr_t H5A_attr_release_table(H5A_attr_table_t *atable);
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index 0bcf8d6..bec794c 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -56,6 +56,9 @@ H5_DLL hsize_t H5Aget_storage_size(hid_t attr_id);
H5_DLL herr_t H5Aget_info(hid_t loc_id, const char *name, H5A_info_t *ainfo /*out*/);
H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo /*out*/);
+H5_DLL ssize_t H5Aget_name_by_idx(hid_t loc_id,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+ char *name /*out*/, size_t size);
H5_DLL herr_t H5Arename(hid_t loc_id, const char *old_name, const char *new_name);
H5_DLL herr_t H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op,
void *op_data);
diff --git a/src/H5Gdense.c b/src/H5Gdense.c
index 865c93f..5cea19c 100644
--- a/src/H5Gdense.c
+++ b/src/H5Gdense.c
@@ -86,12 +86,12 @@ 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 */
+ H5HF_t *fheap; /* Fractal heap handle */
+ hsize_t count; /* # of links examined */
/* downward (from application) */
hid_t gid; /* Group ID for application callback */
hsize_t skip; /* Number of links to skip */
- hsize_t count; /* Count of records operated on */
const H5G_link_iterate_t *lnk_op; /* Callback for each link */
void *op_data; /* Callback data for each link */
@@ -858,7 +858,7 @@ H5G_dense_iterate_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
* this routine because this fractal heap 'op' callback routine is called
* with the direct block protected and if the callback routine invokes an
* HDF5 routine, it could attempt to re-protect that direct block for the
- * heap, causing the HDF5 routine called to fail)
+ * heap, causing the HDF5 routine called to fail - QAK)
*/
if(NULL == (udata->lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
@@ -968,6 +968,8 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
{
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5G_link_table_t ltable = {0, NULL}; /* Table of links */
+ 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; /* Return value */
FUNC_ENTER_NOAPI(H5G_dense_iterate, FAIL)
@@ -979,23 +981,33 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
HDassert(linfo);
HDassert(lnk_op && lnk_op->u.lib_op);
- /* Check for skipping too many links */
- if(skip > 0) {
- hsize_t nrec; /* # of records in v2 B-tree */
-
- /* Retrieve # of records in name index */
- /* (# of records in all indices the same) */
- if(H5B2_get_nrec(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &nrec) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve # of records in index")
-
- /* Check for bad starting index */
- if(skip >= nrec)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
+ /* Determine the address of the index to use */
+ if(idx_type == H5_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) {
+ HDassert(H5F_addr_defined(linfo->name_bt2_addr));
+ bt2_addr = linfo->name_bt2_addr;
+ bt2_class = H5G_BT2_NAME;
+ } /* end if */
+ else
+ bt2_addr = HADDR_UNDEF;
} /* end if */
+ else {
+ HDassert(idx_type == H5_INDEX_CRT_ORDER);
+
+ /* This address may not be defined if creation order is tracked, but
+ * 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;
+ } /* end else */
/* Check on iteration order */
- /* ("native" iteration order is unordered for this link storage mechanism) */
- if(order == H5_ITER_NATIVE) {
+ if(order == H5_ITER_NATIVE && H5F_addr_defined(bt2_addr)) {
H5G_bt2_ud_it_t udata; /* User data for iterator callback */
/* Open the fractal heap */
@@ -1014,11 +1026,10 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Iterate over the records in the v2 B-tree's "native" order */
/* (by hash of name) */
- if((ret_value = H5B2_iterate(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr,
- H5G_dense_iterate_bt2_cb, &udata)) < 0)
+ if((ret_value = H5B2_iterate(f, dxpl_id, bt2_class, bt2_addr, H5G_dense_iterate_bt2_cb, &udata)) < 0)
HERROR(H5E_SYM, H5E_BADITER, "link iteration failed");
- /* Update last link looked at */
+ /* Update the last link examined, if requested */
if(last_lnk)
*last_lnk = udata.count;
} /* end if */
diff --git a/src/H5L.c b/src/H5L.c
index e39e787..5943ec0 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -130,14 +130,15 @@ typedef struct {
/* User data for path traversal routine for getting name by index */
typedef struct {
/* In */
- H5_index_t idx_type; /* Index to use */
+ H5_index_t idx_type; /* Index to use */
H5_iter_order_t order; /* Order to iterate in index */
hsize_t n; /* Offset of link within index */
size_t size; /* Size of name buffer */
hid_t dxpl_id; /* DXPL to use in callback */
/* Out */
- char *name; /* Buffer to return name to user */
+ char *name; /* Buffer to return name to user */
+ ssize_t name_len; /* Length of full name */
} H5L_trav_gnbi_t;
/********************/
@@ -158,18 +159,12 @@ static herr_t H5L_get_val_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
static herr_t H5L_get_val_by_idx_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_val_by_idx(H5G_loc_t *loc, const char *group_name,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t n, void *buf/*out*/,
- size_t size, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5L_delete_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_delete_by_idx_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_delete_by_idx(H5G_loc_t *loc, const char *group_name,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id,
- hid_t dxpl_id);
static herr_t H5L_move_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*/);
@@ -182,15 +177,9 @@ static herr_t H5L_get_info_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
static herr_t H5L_get_info_by_idx_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_by_idx(const H5G_loc_t *loc, const char *group_name,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
- H5L_info_t *linfo/*out*/, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5L_get_name_by_idx_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_name_by_idx(const H5G_loc_t *loc, const char *group_name,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
- char *name/*out*/, size_t size, hid_t lapl_id, hid_t dxpl_id);
/*********************/
/* Package Variables */
@@ -693,6 +682,7 @@ H5Ldelete_by_idx(hid_t loc_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id)
{
H5G_loc_t loc; /* Group's location */
+ H5L_trav_rmbi_t udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Ldelete_by_idx, FAIL)
@@ -713,9 +703,15 @@ H5Ldelete_by_idx(hid_t loc_id, const char *group_name,
if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
- /* Unlink */
- if(H5L_delete_by_idx(&loc, group_name, idx_type, order, n, lapl_id, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
+ /* Set up user data for unlink operation */
+ udata.idx_type = idx_type;
+ udata.order = order;
+ udata.n = n;
+ udata.dxpl_id = H5AC_dxpl_id;
+
+ /* Traverse the group hierarchy to remove the link */
+ if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, H5L_delete_by_idx_cb, &udata, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
done:
FUNC_LEAVE_API(ret_value)
@@ -795,6 +791,7 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
hid_t lapl_id)
{
H5G_loc_t loc; /* Group location for location to query */
+ H5L_trav_gvbi_t udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lget_val_by_idx, FAIL)
@@ -816,9 +813,18 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
- /* Get the link value */
- if(H5L_get_val_by_idx(&loc, group_name, idx_type, order, n, buf, size, lapl_id, H5AC_ind_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value")
+ /* Set up user data for retrieving information */
+ udata.idx_type = idx_type;
+ udata.order = order;
+ udata.n = n;
+ udata.dxpl_id = H5AC_ind_dxpl_id;
+ udata.buf = buf;
+ udata.size = size;
+
+ /* Traverse the group hierarchy to locate the object to get info about */
+ if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L_get_val_by_idx_cb, &udata, lapl_id, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
+
done:
FUNC_LEAVE_API(ret_value)
@@ -889,6 +895,7 @@ H5Lget_info_by_idx(hid_t loc_id, const char *group_name,
H5L_info_t *linfo /*out*/, hid_t lapl_id)
{
H5G_loc_t loc; /* Group location for group to query */
+ H5L_trav_gibi_t udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lget_info_by_idx, FAIL)
@@ -910,10 +917,18 @@ H5Lget_info_by_idx(hid_t loc_id, const char *group_name,
if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
- /* Get the link information */
- if(H5L_get_info_by_idx(&loc, group_name, idx_type, order, n, linfo, lapl_id, H5AC_ind_dxpl_id) < 0)
+ /* Set up user data for callback */
+ udata.idx_type = idx_type;
+ udata.order = order;
+ udata.n = n;
+ udata.dxpl_id = H5AC_ind_dxpl_id;
+ udata.linfo = linfo;
+
+ /* Traverse the group hierarchy to locate the object to get info about */
+ if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_info_by_idx_cb, &udata, lapl_id, H5AC_ind_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info")
+
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Lget_info_by_idx() */
@@ -1054,7 +1069,8 @@ done:
*
* Same pattern of behavior as H5Iget_name.
*
- * Return: Success: Non-negative with information in NAME buffer
+ * Return: Success: Non-negative length of name, with information
+ * in NAME buffer
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -1068,6 +1084,7 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name,
char *name /*out*/, size_t size, hid_t lapl_id)
{
H5G_loc_t loc; /* Location of group */
+ H5L_trav_gnbi_t udata; /* User data for callback */
ssize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Lget_name_by_idx, FAIL)
@@ -1089,9 +1106,21 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name,
if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
- /* Get the link's name */
- if((ret_value = H5L_get_name_by_idx(&loc, group_name, idx_type, order, n, name, size, lapl_id, H5AC_ind_dxpl_id)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link's name")
+ /* Set up user data for callback */
+ udata.idx_type = idx_type;
+ udata.order = order;
+ udata.n = n;
+ udata.dxpl_id = H5AC_ind_dxpl_id;
+ udata.name = name;
+ udata.size = size;
+ udata.name_len = -1;
+
+ /* Traverse the group hierarchy to locate the link to get name of */
+ if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_name_by_idx_cb, &udata, lapl_id, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
+
+ /* Set the return value */
+ ret_value = udata.name_len;
done:
FUNC_LEAVE_API(ret_value)
@@ -1970,56 +1999,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5L_get_val_by_idx
- *
- * Purpose: Returns the value of a symbolic link or the udata for a
- * user-defined link.
- *
- * Return: Success: Non-negative, with at most SIZE bytes of the
- * link value copied into the BUF buffer. If the
- * link value is larger than SIZE characters
- * counting the null terminator then the BUF
- * result will not be null terminated.
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * Monday, November 13, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5L_get_val_by_idx(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type,
- H5_iter_order_t order, hsize_t n, void *buf/*out*/, size_t size,
- hid_t lapl_id, hid_t dxpl_id)
-{
- H5L_trav_gvbi_t udata; /* User data for callback */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5L_get_val_by_idx)
-
- /* Sanity check */
- HDassert(loc);
- HDassert(group_name && *group_name);
-
- /* Set up user data for retrieving information */
- udata.idx_type = idx_type;
- udata.order = order;
- udata.n = n;
- udata.dxpl_id = dxpl_id;
- udata.buf = buf;
- udata.size = size;
-
- /* Traverse the group hierarchy to locate the object to get info about */
- if(H5G_traverse(loc, group_name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L_get_val_by_idx_cb, &udata, lapl_id, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5L_get_val_by_idx() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5L_delete_cb
*
* Purpose: Callback for deleting a link. This routine
@@ -2150,47 +2129,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5L_delete_by_idx
- *
- * Purpose: Delete a link from a group, according to the order within an
- * index.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Monday, November 13, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5L_delete_by_idx(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type,
- H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t dxpl_id)
-{
- H5L_trav_rmbi_t udata; /* User data for callback */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5L_delete_by_idx)
-
- /* Sanity check */
- HDassert(loc);
- HDassert(group_name && *group_name);
-
- /* Set up user data for unlink operation */
- udata.idx_type = idx_type;
- udata.order = order;
- udata.n = n;
- udata.dxpl_id = dxpl_id;
-
- /* Traverse the group hierarchy to remove the link */
- if(H5G_traverse(loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, H5L_delete_by_idx_cb, &udata, lapl_id, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5L_delete_by_idx() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5L_move_dest_cb
*
* Purpose: Second callback for moving and renaming an object. This routine
@@ -2650,49 +2588,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5L_get_info_by_idx
- *
- * Purpose: Returns metadata about a link, according to an order within
- * an index.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Monday, November 6 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5L_get_info_by_idx(const H5G_loc_t *loc, const char *group_name,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
- H5L_info_t *linfo/*out*/, hid_t lapl_id, hid_t dxpl_id)
-{
- H5L_trav_gibi_t udata; /* User data for callback */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5L_get_info_by_idx)
-
- /* Sanity check */
- HDassert(loc);
- HDassert(group_name && *group_name);
-
- /* Set up user data for callback */
- udata.idx_type = idx_type;
- udata.order = order;
- udata.n = n;
- udata.dxpl_id = dxpl_id;
- udata.linfo = linfo;
-
- /* Traverse the group hierarchy to locate the object to get info about */
- if(H5G_traverse(loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_info_by_idx_cb, &udata, lapl_id, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5L_get_info_by_idx() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5L_get_default_lcpl
*
* Purpose: Accessor for the default Link Creation Property List
@@ -2748,8 +2643,8 @@ H5L_get_name_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group doesn't exist")
/* Query link */
- if(H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order,
- udata->n, udata->name, udata->size, udata->dxpl_id) < 0)
+ if((udata->name_len = H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order,
+ udata->n, udata->name, udata->size, udata->dxpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "link not found")
done:
@@ -2760,43 +2655,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_get_name_by_idx_cb() */
-
-/*-------------------------------------------------------------------------
- * Function: H5L_get_name_by_idx
- *
- * Purpose: Returns name of a link, according to an order within
- * an index.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Saturday, November 11 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5L_get_name_by_idx(const H5G_loc_t *loc, const char *group_name,
- H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
- char *name/*out*/, size_t size, hid_t lapl_id, hid_t dxpl_id)
-{
- H5L_trav_gnbi_t udata; /* User data for callback */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5L_get_name_by_idx)
-
- /* Set up user data for callback */
- udata.idx_type = idx_type;
- udata.order = order;
- udata.n = n;
- udata.dxpl_id = dxpl_id;
- udata.name = name;
- udata.size = size;
-
- /* Traverse the group hierarchy to locate the object to get info about */
- if(H5G_traverse(loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_name_by_idx_cb, &udata, lapl_id, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5L_get_name_by_idx() */
-
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 781572b..2f8a1ea 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -427,7 +427,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_attr_open_by_idx
+ * Function: H5O_attr_open_by_idx_cb
*
* Purpose: Callback routine opening an attribute by index
*
@@ -491,7 +491,7 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
attr_op.u.lib_op = H5O_attr_open_by_idx_cb;
/* Iterate over attributes to locate correct one */
- if(H5O_attr_iterate((hid_t)-1, loc, dxpl_id, H5_ITER_INC, (unsigned)n, NULL, &attr_op, &ret_value) < 0)
+ if(H5O_attr_iterate((hid_t)-1, loc, dxpl_id, idx_type, order, n, NULL, &attr_op, &ret_value) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADITER, NULL, "can't locate attribute")
done:
@@ -950,8 +950,8 @@ done:
*/
herr_t
H5O_attr_iterate(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
- H5_iter_order_t order, unsigned skip, unsigned *last_attr,
- const H5A_attr_iter_op_t *attr_op, void *op_data)
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
+ hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data)
{
H5O_t *oh = NULL; /* Pointer to actual object header */
unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */
@@ -972,10 +972,16 @@ H5O_attr_iterate(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
if(oh->version > H5O_VERSION_1 && H5F_addr_defined(oh->attr_fheap_addr)) {
haddr_t attr_fheap_addr; /* Address of fractal heap for dense attribute storage */
haddr_t name_bt2_addr; /* Address of v2 B-tree for name index on dense attribute storage */
+ haddr_t corder_bt2_addr; /* Address of v2 B-tree for creation order index on dense attribute storage */
+
+ /* Check for skipping too many attributes */
+ if(skip > 0 && skip >= oh->nattrs)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
/* Retrieve the information about dense attribute storage */
attr_fheap_addr = oh->attr_fheap_addr;
name_bt2_addr = oh->name_bt2_addr;
+ corder_bt2_addr = oh->corder_bt2_addr;
/* Release the object header */
if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
@@ -984,12 +990,13 @@ H5O_attr_iterate(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
/* Iterate over attributes in dense storage */
if((ret_value = H5A_dense_iterate(loc->file, dxpl_id, loc_id, attr_fheap_addr,
- name_bt2_addr, order, skip, last_attr, attr_op, op_data)) < 0)
+ name_bt2_addr, corder_bt2_addr, idx_type, order, skip,
+ last_attr, attr_op, op_data)) < 0)
HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
} /* end if */
else {
/* Build table of attributes for compact storage */
- if(H5A_compact_build_table(loc->file, dxpl_id, oh, H5_INDEX_NAME, H5_ITER_INC, &atable, &oh_flags) < 0)
+ if(H5A_compact_build_table(loc->file, dxpl_id, oh, idx_type, order, &atable, &oh_flags) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "error building attribute table")
/* Release the object header */
@@ -998,11 +1005,8 @@ H5O_attr_iterate(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
oh = NULL;
/* Check for skipping too many attributes */
- if(skip > 0) {
- /* Check for bad starting index */
- if(skip >= atable.nattrs)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
- } /* end if */
+ if(skip > 0 && skip >= atable.nattrs)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
/* Iterate over attributes in table */
if((ret_value = H5A_attr_iterate_table(&atable, skip, last_attr, loc_id, attr_op, op_data)) < 0)
@@ -1148,7 +1152,7 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
size_t u; /* Local index */
/* Build the table of attributes for this object */
- if(H5A_dense_build_table(loc->file, dxpl_id, oh->nattrs, oh->attr_fheap_addr, oh->name_bt2_addr, H5_INDEX_NAME, H5_ITER_NATIVE, &atable) < 0)
+ if(H5A_dense_build_table(loc->file, dxpl_id, oh->attr_fheap_addr, oh->name_bt2_addr, H5_INDEX_NAME, H5_ITER_NATIVE, &atable) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "error building attribute table")
/* Inspect attributes in table for ones that can't be converted back
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 2d106da..d3ff9c9 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -482,8 +482,8 @@ H5_DLL herr_t H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id,
H5_DLL herr_t H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id,
const char *old_name, const char *new_name);
H5_DLL herr_t H5O_attr_iterate(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
- H5_iter_order_t order, unsigned skip, unsigned *last_attr,
- const H5A_attr_iter_op_t *op, void *op_data);
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
+ hsize_t *last_attr, const H5A_attr_iter_op_t *op, void *op_data);
H5_DLL herr_t H5O_attr_remove(const H5O_loc_t *loc, const char *name,
hid_t dxpl_id);
H5_DLL int H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id);