Skip to content

Commit

Permalink
Fix for HDFFV-10579 H5Arename fails when creation order of attributes…
Browse files Browse the repository at this point in the history
… is tracked.

The attribute needs to be removed from the creation order index v2 B-tree before
re-inserting the renamed attribute via H5A__dense_insert().
  • Loading branch information
Vailin Choi committed Apr 12, 2019
1 parent 66184e5 commit 4e05249
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 38 deletions.
30 changes: 30 additions & 0 deletions src/H5Adense.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name,
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */
H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order ndex */
H5A_t *attr_copy = NULL; /* Copy of attribute to rename */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
Expand Down Expand Up @@ -976,6 +977,33 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name,
if(H5A__set_version(f, attr_copy) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version")

/* Need to remove the attribute from the creation order index v2 B-tree */
if(ainfo->index_corder) {
htri_t corder_attr_exists; /* Attribute exists in v2 B-tree */

/* Open the creation order index v2 B-tree */
HDassert(H5F_addr_defined(ainfo->corder_bt2_addr));
if(NULL == (bt2_corder = H5B2_open(f, ainfo->corder_bt2_addr, NULL)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation index")

/* Set up the creation order to search for */
udata.corder = attr_copy->shared->crt_idx;

if((corder_attr_exists = H5B2_find(bt2_corder, &udata, NULL, NULL)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")

if(corder_attr_exists) {
H5A_bt2_ud_rm_t rm_udata;

/* Set up the creation order in user data for the v2 B-tree 'record remove' callback */
rm_udata.common.corder = attr_copy->shared->crt_idx;

/* Remove the record from the creation order index v2 B-tree */
if(H5B2_remove(bt2_corder, &rm_udata, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from creation order index v2 B-tree")
}
}

/* Insert renamed attribute back into dense storage */
/* (Possibly making it shared) */
if(H5A__dense_insert(f, ainfo, attr_copy) < 0)
Expand Down Expand Up @@ -1023,6 +1051,8 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name,
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(bt2_name && H5B2_close(bt2_name) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index")
if(bt2_corder && H5B2_close(bt2_corder) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index")
if(attr_copy)
H5O_msg_free(H5O_ATTR_ID, attr_copy);

Expand Down
93 changes: 55 additions & 38 deletions test/tattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2626,6 +2626,7 @@ test_attr_dense_rename(hid_t fcpl, hid_t fapl)
H5O_info_t oinfo; /* Object info */
unsigned u; /* Local index variable */
int use_min_dset_oh = (dcpl_g != H5P_DEFAULT);
unsigned use_corder; /* Track creation order or not */
herr_t ret; /* Generic return value */

/* Output message about test being performed */
Expand Down Expand Up @@ -2671,61 +2672,77 @@ test_attr_dense_rename(hid_t fcpl, hid_t fapl)
CHECK(dcpl, FAIL, "H5Pcreate");
}

/* Create a dataset */
dataset = H5Dcreate2(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
CHECK(dataset, FAIL, "H5Dcreate2");

/* Retrieve limits for compact/dense attribute storage */
ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
CHECK(ret, FAIL, "H5Pget_attr_phase_change");

/* Close property list */
ret = H5Pclose(dcpl);
CHECK(ret, FAIL, "H5Pclose");
/* Using creation order or not */
for(use_corder = FALSE; use_corder <= TRUE; use_corder++) {

/* Check on dataset's attribute storage status */
is_dense = H5O__is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O__is_attr_dense_test");
if(use_corder) {
ret = H5Pset_attr_creation_order(dcpl, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED);
CHECK(ret, FAIL, "H5Pset_attr_creation_order");
}

/* Add attributes, until well into dense storage */
for(u = 0; u < (max_compact * 2); u++) {
/* Create attribute */
sprintf(attrname, "attr %02u", u);
attr = H5Acreate2(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT);
CHECK(attr, FAIL, "H5Acreate2");
/* Create a dataset */
dataset = H5Dcreate2(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
CHECK(dataset, FAIL, "H5Dcreate2");

/* Write data into the attribute */
ret = H5Awrite(attr, H5T_NATIVE_UINT, &u);
CHECK(ret, FAIL, "H5Awrite");
/* Check on dataset's attribute storage status */
is_dense = H5O__is_attr_dense_test(dataset);
VERIFY(is_dense, FALSE, "H5O__is_attr_dense_test");

/* Close attribute */
ret = H5Aclose(attr);
CHECK(ret, FAIL, "H5Aclose");
/* Add attributes, until well into dense storage */
for(u = 0; u < (max_compact * 2); u++) {
/* Create attribute */
sprintf(attrname, "attr %02u", u);
attr = H5Acreate2(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT);
CHECK(attr, FAIL, "H5Acreate2");

/* Rename attribute */
sprintf(new_attrname, "new attr %02u", u);
/* Write data into the attribute */
ret = H5Awrite(attr, H5T_NATIVE_UINT, &u);
CHECK(ret, FAIL, "H5Awrite");

/* Rename attribute */
ret = H5Arename_by_name(fid, DSET1_NAME, attrname, new_attrname, H5P_DEFAULT);
CHECK(ret, FAIL, "H5Arename_by_name");
/* Close attribute */
ret = H5Aclose(attr);
CHECK(ret, FAIL, "H5Aclose");

/* Check # of attributes */
ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS);
CHECK(ret, FAIL, "H5Oget_info");
VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info");
} /* end for */
/* Rename attribute */
sprintf(new_attrname, "new attr %02u", u);

/* Check on dataset's attribute storage status */
is_dense = H5O__is_attr_dense_test(dataset);
VERIFY(is_dense, TRUE, "H5O__is_attr_dense_test");
/* Rename attribute */
ret = H5Arename_by_name(fid, DSET1_NAME, attrname, new_attrname, H5P_DEFAULT);
CHECK(ret, FAIL, "H5Arename_by_name");

/* Check # of attributes */
ret = H5Oget_info2(dataset, &oinfo, H5O_INFO_NUM_ATTRS);
CHECK(ret, FAIL, "H5Oget_info");
VERIFY(oinfo.num_attrs, (u + 1), "H5Oget_info");
} /* end for */

/* Check on dataset's attribute storage status */
is_dense = H5O__is_attr_dense_test(dataset);
VERIFY(is_dense, TRUE, "H5O__is_attr_dense_test");

/* Close Dataset */
ret = H5Dclose(dataset);
CHECK(ret, FAIL, "H5Dclose");

if(!use_corder) {
/* Unlink dataset with attributes */
ret = H5Ldelete(fid, DSET1_NAME, H5P_DEFAULT);
CHECK(ret, FAIL, "H5Ldelete");
}

} /* end for use_corder */

/* Close dataspace */
ret = H5Sclose(sid);
CHECK(ret, FAIL, "H5Sclose");

/* Close Dataset */
ret = H5Dclose(dataset);
CHECK(ret, FAIL, "H5Dclose");
/* Close property list */
ret = H5Pclose(dcpl);
CHECK(ret, FAIL, "H5Pclose");

/* Close file */
ret = H5Fclose(fid);
Expand Down

0 comments on commit 4e05249

Please sign in to comment.