diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2010-02-16 17:23:38 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2010-02-16 17:23:38 (GMT) |
commit | feae1cb35ffd0199e9fa03d97f66100919e4094d (patch) | |
tree | 04f0297afa6831a48974196db64df75abbbe7972 | |
parent | bbd0b5515888c00ce4ed5f4c7af635d5c9aa2490 (diff) | |
download | hdf5-feae1cb35ffd0199e9fa03d97f66100919e4094d.zip hdf5-feae1cb35ffd0199e9fa03d97f66100919e4094d.tar.gz hdf5-feae1cb35ffd0199e9fa03d97f66100919e4094d.tar.bz2 |
[svn-r18263] Purpose: Fix bug in b-tree code
Description:
In certain cases, removal of an object in a v1 b-tree would cause the leftmost
key in the right neighbor to be overwritten. While this did not pose a problem
for group b-trees, with chunked datasets it would overwrite the offset value
of the neighbor's leftmost child, causing corruption. Reworked the code to
differentiate between b-trees whose children are fundamentally associated with
their left key and those who are associated with their right key.
Tested: jam, linew, amani (h5committest)
-rw-r--r-- | release_docs/RELEASE.txt | 3 | ||||
-rw-r--r-- | src/H5B.c | 508 | ||||
-rw-r--r-- | src/H5Bprivate.h | 10 | ||||
-rw-r--r-- | src/H5Dbtree.c | 3 | ||||
-rw-r--r-- | src/H5Gnode.c | 11 | ||||
-rw-r--r-- | test/set_extent.c | 982 |
6 files changed, 846 insertions, 671 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index ad5847c..6b42dec 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -106,6 +106,9 @@ Bug Fixes since HDF5-1.8.4 Library ------- + - Fixed an intermittent bug in the b-tree code which could be triggered + by expanding and shrinking chunked datasets in certain ways. + (NAF - 2010/02/16) - H5Tdetect_class said a VL string is a string type. But when it's in a compound type, it said it's a VL type (Bug #1584). I fixed it to be consistent. It always return string type. (SLU - 2009/12/10) @@ -850,72 +850,90 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type } /* end if */ else my_ins = H5B_INS_NOOP; - } else if(cmp < 0 && idx == 0 && bt->level > 0) { - /* - * The value being inserted is less than any value in this tree. - * Follow the minimum branch out of this node to a subtree. - */ - if((int)(my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, - H5B_NKEY(bt,shared,idx), lt_key_changed, md_key, - udata, H5B_NKEY(bt, shared, idx + 1), rt_key_changed, - &child_addr/*out*/)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum subtree") - } else if(cmp < 0 && idx == 0 && type->follow_min) { - /* - * The value being inserted is less than any leaf node out of this - * current node. Follow the minimum branch to a leaf node and let the - * subclass handle the problem. - */ - if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), - lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), - rt_key_changed, &child_addr/*out*/)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") } else if(cmp < 0 && idx == 0) { - /* - * The value being inserted is less than any leaf node out of the - * current node. Create a new minimum leaf node out of this B-tree - * node. This node is not empty (handled above). - */ - my_ins = H5B_INS_LEFT; - HDmemcpy(md_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey); - if((type->new_node)(f, dxpl_id, H5B_INS_LEFT, H5B_NKEY(bt, shared, idx), udata, - md_key, &child_addr/*out*/) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") - *lt_key_changed = TRUE; - } else if(cmp > 0 && idx + 1 >= bt->nchildren && bt->level > 0) { - /* - * The value being inserted is larger than any value in this tree. - * Follow the maximum branch out of this node to a subtree. - */ - idx = bt->nchildren - 1; - if((int)(my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, - H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, - H5B_NKEY(bt, shared, idx + 1), rt_key_changed, &child_addr/*out*/)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum subtree") - } else if(cmp > 0 && idx + 1 >= bt->nchildren && type->follow_max) { - /* - * The value being inserted is larger than any leaf node out of the - * current node. Follow the maximum branch to a leaf node and let the - * subclass handle the problem. - */ - idx = bt->nchildren - 1; - if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), - lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), - rt_key_changed, &child_addr/*out*/)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") + if(bt->level > 0) { + /* + * The value being inserted is less than any value in this tree. + * Follow the minimum branch out of this node to a subtree. + */ + if((int)(my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, + H5B_NKEY(bt,shared,idx), lt_key_changed, md_key, + udata, H5B_NKEY(bt, shared, idx + 1), rt_key_changed, + &child_addr/*out*/)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum subtree") + } else if(type->follow_min) { + /* + * The value being inserted is less than any leaf node out of this + * current node. Follow the minimum branch to a leaf node and let + * the subclass handle the problem. + */ + if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), + lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), + rt_key_changed, &child_addr/*out*/)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") + } else { + /* + * The value being inserted is less than any leaf node out of the + * current node. Create a new minimum leaf node out of this B-tree + * node. This node is not empty (handled above). + */ + my_ins = H5B_INS_LEFT; + HDmemcpy(md_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey); + if((type->new_node)(f, dxpl_id, H5B_INS_LEFT, H5B_NKEY(bt, shared, idx), udata, + md_key, &child_addr/*out*/) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") + *lt_key_changed = TRUE; + } /* end else */ + +#ifdef H5_STRICT_FORMAT_CHECKS + /* Since we are to the left of the leftmost key there must not be a left + * sibling */ + if(H5F_addr_defined(bt->left)) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "internal error: likely corrupt key values") +#endif /* H5_STRICT_FORMAT_CHECKS */ } else if(cmp > 0 && idx + 1 >= bt->nchildren) { - /* - * The value being inserted is larger than any leaf node out of the - * current node. Create a new maximum leaf node out of this B-tree - * node. - */ - idx = bt->nchildren - 1; - my_ins = H5B_INS_RIGHT; - HDmemcpy(md_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); - if((type->new_node)(f, dxpl_id, H5B_INS_RIGHT, md_key, udata, - H5B_NKEY(bt, shared, idx + 1), &child_addr/*out*/) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") - *rt_key_changed = TRUE; + if (bt->level > 0) { + /* + * The value being inserted is larger than any value in this tree. + * Follow the maximum branch out of this node to a subtree. + */ + idx = bt->nchildren - 1; + if((int)(my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, + H5B_NKEY(bt, shared, idx), lt_key_changed, md_key, udata, + H5B_NKEY(bt, shared, idx + 1), rt_key_changed, &child_addr/*out*/)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum subtree") + } else if(type->follow_max) { + /* + * The value being inserted is larger than any leaf node out of the + * current node. Follow the maximum branch to a leaf node and let + * the subclass handle the problem. + */ + idx = bt->nchildren - 1; + if((int)(my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt, shared, idx), + lt_key_changed, md_key, udata, H5B_NKEY(bt, shared, idx + 1), + rt_key_changed, &child_addr/*out*/)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") + } else { + /* + * The value being inserted is larger than any leaf node out of the + * current node. Create a new maximum leaf node out of this B-tree + * node. + */ + idx = bt->nchildren - 1; + my_ins = H5B_INS_RIGHT; + HDmemcpy(md_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + if((type->new_node)(f, dxpl_id, H5B_INS_RIGHT, md_key, udata, + H5B_NKEY(bt, shared, idx + 1), &child_addr/*out*/) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") + *rt_key_changed = TRUE; + } /* end else */ + +#ifdef H5_STRICT_FORMAT_CHECKS + /* Since we are to the right of the rightmost key there must not be a + * right sibling */ + if(H5F_addr_defined(bt->right)) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "internal error: likely corrupt key values") +#endif /* H5_STRICT_FORMAT_CHECKS */ } else if(cmp) { /* * We couldn't figure out which branch to follow out of this node. THIS @@ -951,17 +969,21 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ if(*lt_key_changed) { bt_flags |= H5AC__DIRTIED_FLAG; - if(idx > 0) - *lt_key_changed = FALSE; - else - HDmemcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); + if(idx > 0) { + HDassert(type->critical_key == H5B_LEFT); + *lt_key_changed = FALSE; + } /* end if */ + else + HDmemcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); } /* end if */ if(*rt_key_changed) { bt_flags |= H5AC__DIRTIED_FLAG; - if(idx + 1 < bt->nchildren) - *rt_key_changed = FALSE; - else - HDmemcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + if(idx + 1 < bt->nchildren) { + HDassert(type->critical_key == H5B_RIGHT); + *rt_key_changed = FALSE; + } /* end if */ + else + HDmemcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); } /* end if */ if(H5B_INS_CHANGE == my_ins) { /* @@ -1321,160 +1343,216 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * our right key and indicate that it changed. */ if(*lt_key_changed) { + HDassert(type->critical_key == H5B_LEFT); bt_flags |= H5AC__DIRTIED_FLAG; - if(idx > 0) + if(idx > 0) /* Don't propagate change out of this B-tree node */ - *lt_key_changed = FALSE; - else - HDmemcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); + *lt_key_changed = FALSE; + else + HDmemcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); } /* end if */ if(*rt_key_changed) { + HDassert(type->critical_key == H5B_RIGHT); bt_flags |= H5AC__DIRTIED_FLAG; - if(idx + 1 < bt->nchildren) { + if(idx + 1 < bt->nchildren) /* Don't propagate change out of this B-tree node */ - *rt_key_changed = FALSE; - } /* end if */ - else { - HDmemcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + *rt_key_changed = FALSE; + else + HDmemcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + } /* end if */ - /* Since our right key was changed, we must check for a right - * sibling and change it's left-most key as well. - * (Handle the ret_value==H5B_INS_REMOVE case below) + /* + * If the subtree returned H5B_INS_REMOVE then we should remove the + * subtree entry from the current node. There are four cases: + */ + if(H5B_INS_REMOVE == ret_value) { + /* Clients should not change keys when a node is removed. This function + * will handle it as appropriate, based on the value of bt->critical_key + */ + HDassert(!(*lt_key_changed)); + HDassert(!(*rt_key_changed)); + + if(1 == bt->nchildren) { + /* + * The subtree is the only child of this node. Discard both + * keys and the subtree pointer. Free this node (unless it's the + * root node) and return H5B_INS_REMOVE. */ - if(ret_value != H5B_INS_REMOVE && level > 0) { + /* Only delete the node if it is not the root node. Note that this + * "level" is the opposite of bt->level */ + if(level > 0) { + /* Fix siblings, making sure that the keys remain consistent + * between siblings. Overwrite the key that that is not + * "critical" for any child in its node to maintain this + * consistency (and avoid breaking key/child consistency) */ + if(H5F_addr_defined(bt->left)) { + if(NULL == (sibling = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, bt->left, type, udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load node from tree") + + /* Copy right-most key from deleted node to right-most key + * in its left neighbor, but only if it is not the critical + * key for the right-most child of the left neighbor */ + if(type->critical_key == H5B_LEFT) + HDmemcpy(H5B_NKEY(sibling, shared, sibling->nchildren), + H5B_NKEY(bt, shared, 1), type->sizeof_nkey); + + sibling->right = bt->right; + + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->left, sibling, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node from tree") + sibling = NULL; /* Make certain future references will be caught */ + } /* end if */ if(H5F_addr_defined(bt->right)) { if(NULL == (sibling = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, bt->right, type, udata, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to unlink node from tree") - /* Make certain the native key for the right sibling is set up */ - HDmemcpy(H5B_NKEY(sibling, shared, 0), H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + /* Copy left-most key from deleted node to left-most key in + * its right neighbor, but only if it is not the critical + * key for the left-most child of the right neighbor */ + if(type->critical_key == H5B_RIGHT) + HDmemcpy(H5B_NKEY(sibling, shared, 0), + H5B_NKEY(bt, shared, 0), type->sizeof_nkey); + + sibling->left = bt->left; if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node from tree") sibling = NULL; /* Make certain future references will be caught */ } /* end if */ - } /* end if */ - } /* end else */ - } /* end if */ - /* - * If the subtree returned H5B_INS_REMOVE then we should remove the - * subtree entry from the current node. There are four cases: - */ - if(H5B_INS_REMOVE == ret_value && 1 == bt->nchildren) { - /* - * The subtree is the only child of this node. Discard both - * keys and the subtree pointer. Free this node (unless it's the - * root node) and return H5B_INS_REMOVE. - */ - bt_flags |= H5AC__DIRTIED_FLAG; - bt->nchildren = 0; - if(level > 0) { - if(H5F_addr_defined(bt->left)) { - if(NULL == (sibling = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, bt->left, type, udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to load node from tree") - - sibling->right = bt->right; - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->left, sibling, H5AC__DIRTIED_FLAG) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node from tree") - sibling = NULL; /* Make certain future references will be caught */ - } /* end if */ - if(H5F_addr_defined(bt->right)) { - if(NULL == (sibling = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, bt->right, type, udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to unlink node from tree") - - /* Copy left-most key from deleted node to left-most key in it's right neighbor */ - HDmemcpy(H5B_NKEY(sibling, shared, 0), H5B_NKEY(bt, shared, 0), type->sizeof_nkey); - - sibling->left = bt->left; - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, H5AC__DIRTIED_FLAG) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node from tree") - sibling = NULL; /* Make certain future references will be caught */ - } /* end if */ - bt->left = HADDR_UNDEF; - bt->right = HADDR_UNDEF; - H5_CHECK_OVERFLOW(shared->sizeof_rnode, size_t, hsize_t); - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, bt_flags | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) { - bt = NULL; - bt_flags = H5AC__NO_FLAGS_SET; - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to free B-tree node") - } /* end if */ - bt = NULL; - bt_flags = H5AC__NO_FLAGS_SET; - } /* end if */ - } else if(H5B_INS_REMOVE == ret_value && 0 == idx) { - /* - * The subtree is the left-most child of this node. We discard the - * left-most key and the left-most child (the child has already been - * freed) and shift everything down by one. We copy the new left-most - * key into lt_key and notify the caller that the left key has - * changed. Return H5B_INS_NOOP. - */ - bt_flags |= H5AC__DIRTIED_FLAG; - bt->nchildren -= 1; - - HDmemmove(bt->native, - bt->native + type->sizeof_nkey, - (bt->nchildren + 1) * type->sizeof_nkey); - HDmemmove(bt->child, - bt->child + 1, - bt->nchildren * sizeof(haddr_t)); - HDmemcpy(lt_key, H5B_NKEY(bt, shared, 0), type->sizeof_nkey); - *lt_key_changed = TRUE; - ret_value = H5B_INS_NOOP; - } else if(H5B_INS_REMOVE == ret_value && idx + 1 == bt->nchildren) { - /* - * The subtree is the right-most child of this node. We discard the - * right-most key and the right-most child (the child has already been - * freed). We copy the new right-most key into rt_key and notify the - * caller that the right key has changed. Return H5B_INS_NOOP. - */ - bt_flags |= H5AC__DIRTIED_FLAG; - bt->nchildren -= 1; - HDmemcpy(rt_key, H5B_NKEY(bt, shared, bt->nchildren), type->sizeof_nkey); - *rt_key_changed = TRUE; - - /* Since our right key was changed, we must check for a right - * sibling and change it's left-most key as well. - * (Handle the ret_value==H5B_INS_REMOVE case below) - */ - if(level > 0) { - if(H5F_addr_defined(bt->right)) { - if(NULL == (sibling = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, bt->right, type, udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to unlink node from tree") + /* Update bt struct */ + bt->left = HADDR_UNDEF; + bt->right = HADDR_UNDEF; + bt->nchildren = 0; - HDmemcpy(H5B_NKEY(sibling, shared, 0), H5B_NKEY(bt, shared, bt->nchildren), type->sizeof_nkey); - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, H5AC__DIRTIED_FLAG) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node from tree") - sibling = NULL; /* Make certain future references will be caught */ - } /* end if */ - } /* end if */ - - ret_value = H5B_INS_NOOP; - } else if(H5B_INS_REMOVE == ret_value) { - /* - * There are subtrees out of this node to both the left and right of - * the subtree being removed. The key to the left of the subtree and - * the subtree are removed from this node and all keys and nodes to - * the right are shifted left by one place. The subtree has already - * been freed). Return H5B_INS_NOOP. - */ - bt_flags |= H5AC__DIRTIED_FLAG; - bt->nchildren -= 1; - - HDmemmove(bt->native + idx * type->sizeof_nkey, - bt->native + (idx + 1) * type->sizeof_nkey, - (bt->nchildren + 1 - idx) * type->sizeof_nkey); - HDmemmove(bt->child + idx, - bt->child + idx + 1, - (bt->nchildren - idx) * sizeof(haddr_t)); - ret_value = H5B_INS_NOOP; - } else - ret_value = H5B_INS_NOOP; + /* Delete the node from disk (via the metadata cache) */ + bt_flags |= H5AC__DIRTIED_FLAG; + H5_CHECK_OVERFLOW(shared->sizeof_rnode, size_t, hsize_t); + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, bt_flags | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) { + bt = NULL; + bt_flags = H5AC__NO_FLAGS_SET; + HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to free B-tree node") + } /* end if */ + bt = NULL; + bt_flags = H5AC__NO_FLAGS_SET; + } else { + /* We removed the last child in the root node, set the level + * back to 0 (as well as nchildren) */ + bt->nchildren = 0; + bt->level = 0; + bt_flags |= H5AC__DIRTIED_FLAG; + } /* end else */ + } else if(0 == idx) { + /* + * The subtree is the left-most child of this node. We update the + * key and child arrays and lt_key as appropriate, depending on the + * status of bt->critical_key. Return H5B_INS_NOOP. + */ + if(type->critical_key == H5B_LEFT) { + /* Slide all keys down 1, update lt_key */ + HDmemmove(H5B_NKEY(bt, shared, 0), H5B_NKEY(bt, shared, 1), + bt->nchildren * type->sizeof_nkey); + HDmemcpy(lt_key, H5B_NKEY(bt, shared, 0), type->sizeof_nkey); + *lt_key_changed = TRUE; + } else + /* Slide all but the leftmost 2 keys down, leaving the leftmost + * key intact (the right key of the leftmost child is + * overwritten) */ + HDmemmove(H5B_NKEY(bt, shared, 1), H5B_NKEY(bt, shared, 2), + (bt->nchildren - 1) * type->sizeof_nkey); + + HDmemmove(bt->child, + bt->child + 1, + (bt->nchildren - 1) * sizeof(haddr_t)); + + bt->nchildren -= 1; + bt_flags |= H5AC__DIRTIED_FLAG; + ret_value = H5B_INS_NOOP; + } else if(idx + 1 == bt->nchildren) { + /* + * The subtree is the right-most child of this node. We update the + * key and child arrays and rt_key as appropriate, depending on the + * status of bt->critical_key. Return H5B_INS_NOOP. + */ + if(type->critical_key == H5B_LEFT) + /* Slide the rightmost key down one, overwriting the left key of + * the deleted (righmost) child */ + HDmemmove(H5B_NKEY(bt, shared, bt->nchildren - 1), + H5B_NKEY(bt, shared, bt->nchildren), type->sizeof_nkey); + else { + /* Just update rt_key */ + HDmemcpy(rt_key, H5B_NKEY(bt, shared, bt->nchildren - 1), + type->sizeof_nkey); + *rt_key_changed = TRUE; + } /* end else */ + + bt->nchildren -= 1; + bt_flags |= H5AC__DIRTIED_FLAG; + ret_value = H5B_INS_NOOP; + } else { + /* + * There are subtrees out of this node to both the left and right of + * the subtree being removed. The subtree and its critical key are + * removed from this node and all keys and nodes to the right are + * shifted left by one place. The subtree has already been freed. + * Return H5B_INS_NOOP. + */ + if(type->critical_key == H5B_LEFT) + HDmemmove(H5B_NKEY(bt, shared, idx), + H5B_NKEY(bt, shared, idx + 1), + (bt->nchildren - idx) * type->sizeof_nkey); + else + HDmemmove(H5B_NKEY(bt, shared, idx + 1), + H5B_NKEY(bt, shared, idx + 2), + (bt->nchildren - 1 - idx) * type->sizeof_nkey); + + HDmemmove(bt->child + idx, + bt->child + idx + 1, + (bt->nchildren - idx) * sizeof(haddr_t)); + + bt->nchildren -= 1; + bt_flags |= H5AC__DIRTIED_FLAG; + ret_value = H5B_INS_NOOP; + } /* end else */ + } else /* H5B_INS_REMOVE != ret_value */ + ret_value = H5B_INS_NOOP; + + /* Patch keys in neighboring trees if necessary */ + if(*lt_key_changed && H5F_addr_defined(bt->left)) { + HDassert(type->critical_key == H5B_LEFT); + HDassert(level > 0); + + /* Update the rightmost key in the left sibling */ + if(NULL == (sibling = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, + bt->left, type, udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to unlink node from tree") + + HDmemcpy(H5B_NKEY(sibling, shared, sibling->nchildren), + H5B_NKEY(bt, shared, 0), type->sizeof_nkey); + + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->left, sibling, + H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node from tree") + sibling = NULL; /* Make certain future references will be caught */ + } /* end if */ + else if(*rt_key_changed && H5F_addr_defined(bt->right)) { + HDassert(type->critical_key == H5B_RIGHT); + HDassert(level > 0); + + /* Update the lefttmost key in the right sibling */ + if(NULL == (sibling = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, + bt->right, type, udata, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to unlink node from tree") + + HDmemcpy(H5B_NKEY(sibling, shared, 0), + H5B_NKEY(bt, shared, bt->nchildren), type->sizeof_nkey); + + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, + H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, H5B_INS_ERROR, "unable to release node from tree") + sibling = NULL; /* Make certain future references will be caught */ + } /* end else */ done: if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, bt_flags) < 0) @@ -1509,8 +1587,6 @@ H5B_remove(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void uint8_t *rt_key = (uint8_t*)_rt_key; /*right key*/ hbool_t lt_key_changed = FALSE; /*left key changed?*/ hbool_t rt_key_changed = FALSE; /*right key changed?*/ - unsigned bt_flags = H5AC__NO_FLAGS_SET; - H5B_t *bt = NULL; /*btree node */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B_remove, FAIL) @@ -1526,22 +1602,6 @@ H5B_remove(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void udata, rt_key, &rt_key_changed) == H5B_INS_ERROR) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to remove entry from B-tree") - /* - * If the B-tree is now empty then make sure we mark the root node as - * being at level zero - */ - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree root node") - - if(0 == bt->nchildren && 0 != bt->level) { - bt->level = 0; - bt_flags |= H5AC__DIRTIED_FLAG; - } /* end if */ - - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, bt_flags) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release node") - bt = NULL; /* Make certain future references will be caught */ - #ifdef H5B_DEBUG H5B_assert(f, dxpl_id, addr, type, udata); #endif diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index 716b608..b0ffa07 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -78,6 +78,13 @@ typedef enum H5B_ins_t { H5B_INS_REMOVE = 5 /*remove current node */ } H5B_ins_t; +/* Enum for specifying the direction of the critical key in relation to the + * child */ +typedef enum H5B_dir_t { + H5B_LEFT = 0, /* Critical key is to the left */ + H5B_RIGHT = 1 /* Critical key is to the right */ +} H5B_dir_t; + /* Define the operator callback function pointer for H5B_iterate() */ typedef int (*H5B_operator_t)(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr, const void *_rt_key, void *_udata); @@ -123,6 +130,9 @@ typedef struct H5B_class_t { hbool_t follow_min; hbool_t follow_max; + /* The direction of the key that is intrinsically associated with each node */ + H5B_dir_t critical_key; + /* remove existing data */ H5B_ins_t (*remove)(H5F_t*, hid_t, haddr_t, void*, hbool_t*, void*, void*, hbool_t*); diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index c12865f..89d2596 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -189,9 +189,10 @@ H5B_class_t H5B_BTREE[1] = {{ H5D_btree_cmp3, /*cmp3 */ H5D_btree_found, /*found */ H5D_btree_insert, /*insert */ + H5B_LEFT, /*critical key */ FALSE, /*follow min branch? */ FALSE, /*follow max branch? */ - H5D_btree_remove, /*remove */ + H5D_btree_remove, /*remove */ H5D_btree_decode_key, /*decode */ H5D_btree_encode_key, /*encode */ H5D_btree_debug_key, /*debug */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 18125df..4bd8a29 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -95,6 +95,7 @@ H5B_class_t H5B_SNODE[1] = {{ H5G_node_cmp3, /*cmp3 */ H5G_node_found, /*found */ H5G_node_insert, /*insert */ + H5B_RIGHT, /*critical key */ TRUE, /*follow min branch? */ TRUE, /*follow max branch? */ H5G_node_remove, /*remove */ @@ -860,14 +861,11 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, /* Remove the entry from the symbol table node */ if(1 == sn->nsyms) { /* - * We are about to remove the only symbol in this node. Copy the left - * key to the right key and mark the right key as dirty. Free this + * We are about to remove the only symbol in this node. Free this * node and indicate that the pointer to this node in the B-tree * should be removed also. */ HDassert(0 == idx); - *rt_key = *lt_key; - *rt_key_changed = TRUE; sn->nsyms = 0; sn_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; ret_value = H5B_INS_REMOVE; @@ -925,13 +923,10 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, } /* end for */ /* - * We are about to remove all the symbols in this node. Copy the left - * key to the right key and mark the right key as dirty. Free this + * We are about to remove all the symbols in this node. Free this * node and indicate that the pointer to this node in the B-tree * should be removed also. */ - *rt_key = *lt_key; - *rt_key_changed = TRUE; sn->nsyms = 0; sn_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; ret_value = H5B_INS_REMOVE; diff --git a/test/set_extent.c b/test/set_extent.c index c65e7d0..b35af8e 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -20,6 +20,8 @@ * Purpose: Tests the H5Dset_extent call */ +#include <time.h> +#include <stdlib.h> #include "hdf5.h" #include "h5test.h" @@ -36,6 +38,7 @@ const char *FILENAME[] = { "set_extent3", "set_extent4", "set_extent5", + "set_extent6", NULL }; @@ -43,6 +46,22 @@ const char *FILENAME[] = { #define EXT_FILE_NAME1 "ext1.bin" #define EXT_FILE_NAME2 "ext2.bin" +#define CONFIG_COMPRESS 0x01u +#define CONFIG_FILL 0x02u +#define CONFIG_EARLY_ALLOC 0x04u +#define CONFIG_ALL (CONFIG_COMPRESS + CONFIG_FILL \ + + CONFIG_EARLY_ALLOC) +#define FILL_VALUE -1 +#define DO_RANKS_PRINT_CONFIG(TEST) { \ + printf(" Config:\n"); \ + printf(" Test: %s\n", TEST); \ + printf(" Compression: %s\n", (config & CONFIG_COMPRESS ? "yes" \ + : "no")); \ + printf(" Fill value: %s\n", (do_fillvalue ? "yes" : "no")); \ + printf(" Early allocation: %s\n", (config & CONFIG_EARLY_ALLOC \ + ? "yes" : "no")); \ +} /* end DO_RANKS_PRINT_CONFIG */ + #define RANK1 1 #define RANK2 2 #define RANK3 3 @@ -56,28 +75,36 @@ const char *FILENAME[] = { #define DIME1 7 #define DIME2 7 #define ISTORE_IK 64 +#define RAND4_NITER 100 +#define RAND4_FAIL_DUMP(NDIM_SETS, J, K, L, M) { \ + H5_FAILED(); AT(); \ + test_random_rank4_dump(NDIM_SETS, dim_log, cdims, J, K, L, M); \ + goto error; \ +} /* end RAND4_FAIL_DUMP */ static int do_ranks( hid_t fapl ); static int do_layouts( hid_t fapl ); -static int test_rank1( hbool_t do_compress, +static int test_rank1( hid_t fapl, + hid_t dcpl, hbool_t do_fill_value, - hbool_t set_istore_k, - H5D_fill_time_t fill_time, - hid_t fapl); -static int test_rank2( hbool_t do_compress, + hbool_t set_istore_k); +static int test_rank2( hid_t fapl, + hid_t dcpl, hbool_t do_fill_value, - hbool_t set_istore_k, - H5D_fill_time_t fill_time, - hid_t fapl); -static int test_rank3( hbool_t do_compress, + hbool_t set_istore_k); +static int test_rank3( hid_t fapl, + hid_t dcpl, hbool_t do_fill_value, - hbool_t set_istore_k, - H5D_fill_time_t fill_time, - hid_t fapl); + hbool_t set_istore_k); +static int test_random_rank4( hid_t fapl, + hid_t dcpl, + hbool_t do_fillvalue); static int test_external( hid_t fapl ); static int test_layouts( H5D_layout_t layout, hid_t fapl ); +static void test_random_rank4_dump( unsigned ndim_sets, hsize_t dim_log[][4], + hsize_t cdims[4], int j, int k, int l, int m ); /*------------------------------------------------------------------------- * main @@ -92,6 +119,9 @@ int main( void ) hbool_t chunk_cache; /* Whether to enable chunk caching */ int nerrors = 0; + /* Initialize random number seed */ + HDsrandom((unsigned)HDtime(NULL)); + h5_reset(); fapl = h5_fileaccess(); @@ -177,148 +207,140 @@ error: static int do_ranks( hid_t fapl ) { - hbool_t do_compress = 0; - hbool_t do_fillvalue = 0; - hbool_t set_istore_k = 0; - - - TESTING_2("with fill value, no compression"); - - do_fillvalue = 1; - - if (test_rank1( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ALLOC, fapl ) < 0) - { - goto error; - } - if (test_rank1( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_IFSET, fapl ) < 0) - { - goto error; - } - if (test_rank2( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ALLOC, fapl ) < 0) - { - goto error; - } - if (test_rank2( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_IFSET, fapl ) < 0) - { - goto error; - } - if (test_rank3( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ALLOC, fapl ) < 0) - { - goto error; - } - if (test_rank3( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_IFSET, fapl ) < 0) - { - goto error; - } - - - - PASSED(); - - - TESTING_2("no fill value, no compression"); - - do_fillvalue = 0; - - if (test_rank1( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ERROR, fapl ) < 0) - { - goto error; - } - if (test_rank2( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ERROR, fapl ) < 0) - { - goto error; - } - if (test_rank3( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ERROR, fapl ) < 0) - { - goto error; - } - + hbool_t do_fillvalue = 0; + hid_t dcpl = -1; + int fillvalue = FILL_VALUE; + unsigned config; + TESTING_2("datasets with ranks 1 to 4 (all configurations)"); - PASSED(); - - TESTING_2("with fill value, with compression"); + /* Loop over different configurations for tests */ + for(config=0; config<=CONFIG_ALL; config++) { + /* Create DCPL and add appropriate settings */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + if(config & CONFIG_COMPRESS) { #ifdef H5_HAVE_FILTER_DEFLATE + if(H5Pset_deflate(dcpl, 9) < 0) + TEST_ERROR +#else /* H5_HAVE_FILTER_DEFLATE */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + continue; +#endif /* H5_HAVE_FILTER_DEFLATE */ + } /* end if */ - do_compress = 1; - do_fillvalue = 1; - - if (test_rank1( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ALLOC, fapl ) < 0) - { - goto error; - } - if (test_rank1( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_IFSET, fapl ) < 0) - { - goto error; - } - if (test_rank2( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ALLOC, fapl ) < 0) - { - goto error; - } - if (test_rank2( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_IFSET, fapl ) < 0) - { - goto error; - } - if (test_rank3( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ALLOC, fapl ) < 0) - { - goto error; - } - if (test_rank3( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_IFSET, fapl ) < 0) - { - goto error; - } - - - PASSED(); -#else - SKIPPED(); -#endif - - TESTING_2("no fill value, with compression"); - -#ifdef H5_HAVE_FILTER_DEFLATE + if(config & CONFIG_FILL) { + do_fillvalue = TRUE; + if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fillvalue) < 0) + TEST_ERROR + } /* end if */ + else + do_fillvalue = FALSE; - do_fillvalue = 0; + if(config & CONFIG_EARLY_ALLOC) + if(H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY) < 0) + TEST_ERROR - if (test_rank1( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ERROR, fapl ) < 0) - { - goto error; - } - if (test_rank2( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ERROR, fapl ) < 0) - { - goto error; - } - if (test_rank3( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ERROR, fapl ) < 0) - { - goto error; - } + /* Run tests */ + if(do_fillvalue) { + unsigned ifset; - PASSED(); -#else - SKIPPED(); -#endif + /* Iterate over different fill times */ + for(ifset=0; ifset<=1; ifset++) { + if(ifset) { + if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_IFSET) < 0) + TEST_ERROR + } /* end if */ + else + if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) + TEST_ERROR + + if(test_rank1(fapl, dcpl, do_fillvalue, FALSE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 1") + printf(" Fill time: %s\n", (ifset ? "H5D_FILL_TIME_IFSET" + : "H5D_FILL_TIME_ALLOC")); + goto error; + } /* end if */ + if(test_rank2(fapl, dcpl, do_fillvalue, FALSE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 2") + printf(" Fill time: %s\n", (ifset ? "H5D_FILL_TIME_IFSET" + : "H5D_FILL_TIME_ALLOC")); + goto error; + } /* end if */ + if(test_rank3(fapl, dcpl, do_fillvalue, FALSE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 3") + printf(" Fill time: %s\n", (ifset ? "H5D_FILL_TIME_IFSET" + : "H5D_FILL_TIME_ALLOC")); + goto error; + } /* end if */ + if(test_rank2(fapl, dcpl, do_fillvalue, TRUE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 2 with non-default indexed storage B-tree") + printf(" Fill time: %s\n", (ifset ? "H5D_FILL_TIME_IFSET" + : "H5D_FILL_TIME_ALLOC")); + goto error; + } /* end if */ + } /* end for */ + } /* end if */ + else { + /* These tests expect fill values to be written even if there is no + * fill value defined */ + if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) + TEST_ERROR - TESTING_2("with non-default indexed storage B-tree"); + if(test_rank1(fapl, dcpl, do_fillvalue, FALSE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 1") + goto error; + } /* end if */ + if(test_rank2(fapl, dcpl, do_fillvalue, FALSE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 2") + goto error; + } /* end if */ + if(test_rank3(fapl, dcpl, do_fillvalue, FALSE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 3") + goto error; + } /* end if */ + if(test_rank2(fapl, dcpl, do_fillvalue, TRUE) < 0) + { + DO_RANKS_PRINT_CONFIG("Rank 2 with non-default indexed storage B-tree") + goto error; + } /* end if */ + } /* end else */ - do_fillvalue = 1; - set_istore_k = 1; + /* The rank 4 test expects the fill value to be written only if + * defined */ + if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_IFSET) < 0) + TEST_ERROR - if (test_rank2( do_compress, do_fillvalue, set_istore_k, H5D_FILL_TIME_ALLOC, fapl ) < 0) - { - goto error; - } + if(test_random_rank4(fapl, dcpl, do_fillvalue) < 0) { + DO_RANKS_PRINT_CONFIG("Randomized rank 4") + goto error; + } /* end if */ + /* Close dcpl */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + } /* end for */ PASSED(); - return 0; - error: + H5E_BEGIN_TRY { + H5Pclose(dcpl); + } H5E_END_TRY + return -1; -} +} /* end do_ranks */ /*------------------------------------------------------------------------- @@ -328,7 +350,7 @@ error: static int do_layouts( hid_t fapl ) { - TESTING_2("storage layout use"); + TESTING("storage layout use"); if (test_layouts( H5D_COMPACT, fapl ) < 0) { @@ -353,17 +375,16 @@ error: *------------------------------------------------------------------------- */ -static int test_rank1( hbool_t do_compress, +static int test_rank1( hid_t fapl, + hid_t dcpl, hbool_t do_fill_value, - hbool_t set_istore_k, - H5D_fill_time_t fill_time, - hid_t fapl) + hbool_t set_istore_k) { hid_t fid=-1; hid_t did=-1; hid_t sid=-1; - hid_t dcpl=-1; + hid_t my_dcpl=-1; hid_t fcpl; hsize_t dims_o[RANK1] = {DIM0}; /* original dimensions */ hsize_t dims_s[RANK1] = {DIMS0}; /* shrinking dimensions */ @@ -376,13 +397,12 @@ static int test_rank1( hbool_t do_compress, int buf_e[DIME0]; int buf_r[DIM0]; int i; - int fillvalue = 1; int comp_value; char filename[NAME_BUF_SIZE]; if ( do_fill_value ) { - comp_value = fillvalue; + comp_value = FILL_VALUE; } else { @@ -399,7 +419,7 @@ static int test_rank1( hbool_t do_compress, /* create a file creation property list */ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { - goto error; + TEST_ERROR } if ( set_istore_k ) @@ -407,7 +427,7 @@ static int test_rank1( hbool_t do_compress, /* set non-default indexed storage B-tree internal 'K' value */ if (H5Pset_istore_k(fcpl,ISTORE_IK) < 0) { - goto error; + TEST_ERROR } } @@ -415,57 +435,29 @@ static int test_rank1( hbool_t do_compress, h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) { - goto error; + TEST_ERROR } /* close property list */ if(H5Pclose(fcpl) < 0) { - goto error; + TEST_ERROR } /* create the data space with unlimited dimensions. */ if ((sid = H5Screate_simple(RANK1, dims_o, maxdims)) < 0) { - goto error; + TEST_ERROR } /* modify dataset creation properties, i.e. enable chunking. */ - if ((dcpl = H5Pcreate (H5P_DATASET_CREATE)) < 0) - { - goto error; - } - if (H5Pset_chunk(dcpl, RANK1, dims_c) < 0) - { - goto error; - } - if ( do_fill_value ) - { - if (H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fillvalue) < 0) - { - goto error; - } - - if(H5Pset_fill_time(dcpl, fill_time) < 0) - { - goto error; - } - } - else + if ((my_dcpl = H5Pcopy (dcpl)) < 0) { - - if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) - { - goto error; - } - + TEST_ERROR } - if (do_compress) + if (H5Pset_chunk(my_dcpl, RANK1, dims_c) < 0) { - if(H5Pset_deflate(dcpl, 9) < 0) - { - goto error; - } + TEST_ERROR } /*------------------------------------------------------------------------- @@ -474,15 +466,15 @@ static int test_rank1( hbool_t do_compress, */ /* create a dataset */ - if ((did = H5Dcreate2(fid , "dset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid , "dset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, my_dcpl, H5P_DEFAULT)) < 0) { - goto error; + TEST_ERROR } /* write */ if (H5Dwrite(did , H5T_NATIVE_INT, sid, H5S_ALL, H5P_DEFAULT, buf_o) < 0) { - goto error; + TEST_ERROR } @@ -501,7 +493,7 @@ static int test_rank1( hbool_t do_compress, if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /*------------------------------------------------------------------------- @@ -512,24 +504,24 @@ static int test_rank1( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_e) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -537,12 +529,12 @@ static int test_rank1( hbool_t do_compress, for( i = 0; i < RANK1; i++ ) { if (dims_r[i] != dims_e[i]) - goto error; + TEST_ERROR } /* read */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_e) < 0) - goto error; + TEST_ERROR @@ -570,13 +562,13 @@ static int test_rank1( hbool_t do_compress, { printf("buf_e[%d] = %d\n", i, buf_e[i]); printf("value = %d\n", comp_value); - goto error; + TEST_ERROR } } else { if(buf_e[i] != buf_o[i]) - goto error; + TEST_ERROR } } @@ -592,31 +584,31 @@ static int test_rank1( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_s) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK1; i++ ) { if (dims_r[i] != dims_s[i]) - goto error; + TEST_ERROR } @@ -627,21 +619,21 @@ static int test_rank1( hbool_t do_compress, if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } if (H5Fclose(fid) < 0) { - goto error; + TEST_ERROR } if ((fid = H5Fopen( filename, H5F_ACC_RDWR, fapl ))<0) { - goto error; + TEST_ERROR } if ((did = H5Dopen2( fid , "dset1", H5P_DEFAULT ))<0) { - goto error; + TEST_ERROR } @@ -657,7 +649,7 @@ static int test_rank1( hbool_t do_compress, /* read */ if (H5Dread( did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_s ) < 0) { - goto error; + TEST_ERROR } #if defined (H5_SET_EXTENT_DEBUG) @@ -682,7 +674,7 @@ static int test_rank1( hbool_t do_compress, { printf("buf_s[%d] = %d\n", i, buf_s[i]); printf("buf_o[%d] = %d\n", i, buf_o[i]); - goto error; + TEST_ERROR } } @@ -695,24 +687,24 @@ static int test_rank1( hbool_t do_compress, /* set new dimensions for the array */ if (H5Dset_extent(did, dims_o) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions. */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -720,13 +712,13 @@ static int test_rank1( hbool_t do_compress, for( i = 0; i < RANK1; i++ ) { if (dims_r[i] != dims_o[i]) - goto error; + TEST_ERROR } /* read */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_r) < 0) - goto error; + TEST_ERROR #if defined (H5_SET_EXTENT_DEBUG) printf("\n"); @@ -751,13 +743,13 @@ static int test_rank1( hbool_t do_compress, { printf("buf_r[%d] = %d\n", i, buf_r[i] ); printf("value = %d\n", comp_value); - goto error; + TEST_ERROR } } else { if(buf_r[i] != buf_o[i]) - goto error; + TEST_ERROR } } @@ -773,31 +765,31 @@ static int test_rank1( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_s) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK1; i++ ) { if (dims_r[i] != dims_s[i]) - goto error; + TEST_ERROR } /*------------------------------------------------------------------------- @@ -807,7 +799,7 @@ static int test_rank1( hbool_t do_compress, if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } @@ -822,28 +814,28 @@ static int test_rank1( hbool_t do_compress, if ((sid = H5Screate_simple(RANK1, dims_o, maxdims)) < 0) { - goto error; + TEST_ERROR } - if ((did = H5Dcreate2(fid , "dset3", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid , "dset3", H5T_NATIVE_INT, sid, H5P_DEFAULT, my_dcpl, H5P_DEFAULT)) < 0) { - goto error; + TEST_ERROR } /* set new dimensions for the array */ dims_o[ 0 ] = 0; if (H5Dset_extent( did , dims_o ) < 0) { - goto error; + TEST_ERROR } if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -855,14 +847,14 @@ static int test_rank1( hbool_t do_compress, */ - if (H5Pclose(dcpl) < 0) + if (H5Pclose(my_dcpl) < 0) { - goto error; + TEST_ERROR } if (H5Fclose( fid ) < 0) { - goto error; + TEST_ERROR } @@ -876,7 +868,7 @@ error: { H5Dclose( did ); H5Sclose( sid ); - H5Pclose( dcpl ); + H5Pclose( my_dcpl ); H5Pclose( fcpl ); H5Fclose( fid ); } H5E_END_TRY; @@ -889,17 +881,16 @@ error: *------------------------------------------------------------------------- */ -static int test_rank2( hbool_t do_compress, +static int test_rank2( hid_t fapl, + hid_t dcpl, hbool_t do_fill_value, - hbool_t set_istore_k, - H5D_fill_time_t fill_time, - hid_t fapl) + hbool_t set_istore_k) { hid_t fid=-1; hid_t did=-1; hid_t sid=-1; - hid_t dcpl=-1; + hid_t my_dcpl=-1; hid_t fcpl; hsize_t dims_o[RANK2] = {DIM0,DIM1}; /* original dimensions */ hsize_t dims_s[RANK2] = {DIMS0,DIMS1}; /* shrinking dimensions */ @@ -912,13 +903,12 @@ static int test_rank2( hbool_t do_compress, int buf_e[DIME0][DIME1]; int buf_r[DIM0][DIM1]; int i, j; - int fillvalue = 1; int comp_value; char filename[NAME_BUF_SIZE]; if ( do_fill_value ) { - comp_value = fillvalue; + comp_value = FILL_VALUE; } else { @@ -937,7 +927,7 @@ static int test_rank2( hbool_t do_compress, /* create a file creation property list */ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { - goto error; + TEST_ERROR } if ( set_istore_k ) @@ -945,7 +935,7 @@ static int test_rank2( hbool_t do_compress, /* set non-default indexed storage B-tree internal 'K' value */ if (H5Pset_istore_k(fcpl,ISTORE_IK) < 0) { - goto error; + TEST_ERROR } } @@ -954,7 +944,7 @@ static int test_rank2( hbool_t do_compress, h5_fixname(FILENAME[1], fapl, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) { - goto error; + TEST_ERROR } @@ -962,45 +952,17 @@ static int test_rank2( hbool_t do_compress, /* create the data space with unlimited dimensions. */ if ((sid = H5Screate_simple(RANK2, dims_o, maxdims)) < 0) { - goto error; + TEST_ERROR } /* modify dataset creation properties, i.e. enable chunking. */ - if ((dcpl = H5Pcreate (H5P_DATASET_CREATE)) < 0) + if ((my_dcpl = H5Pcopy (dcpl)) < 0) { - goto error; + TEST_ERROR } - if (H5Pset_chunk(dcpl, RANK2, dims_c) < 0) + if (H5Pset_chunk(my_dcpl, RANK2, dims_c) < 0) { - goto error; - } - if ( do_fill_value ) - { - if (H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fillvalue) < 0) - { - goto error; - } - - if(H5Pset_fill_time(dcpl, fill_time) < 0) - { - goto error; - } - } - else - { - - if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) - { - goto error; - } - - } - if (do_compress) - { - if(H5Pset_deflate(dcpl, 9) < 0) - { - goto error; - } + TEST_ERROR } /*------------------------------------------------------------------------- @@ -1022,15 +984,15 @@ static int test_rank2( hbool_t do_compress, */ /* create a dataset */ - if ((did = H5Dcreate2(fid , "dset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid , "dset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, my_dcpl, H5P_DEFAULT)) < 0) { - goto error; + TEST_ERROR } /* write */ if (H5Dwrite(did , H5T_NATIVE_INT, sid, H5S_ALL, H5P_DEFAULT, buf_o) < 0) { - goto error; + TEST_ERROR } @@ -1050,7 +1012,7 @@ static int test_rank2( hbool_t do_compress, if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /*------------------------------------------------------------------------- @@ -1071,24 +1033,24 @@ static int test_rank2( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_e) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -1096,12 +1058,12 @@ static int test_rank2( hbool_t do_compress, for( i = 0; i < RANK2; i++ ) { if (dims_r[i] != dims_e[i]) - goto error; + TEST_ERROR } /* read */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_e) < 0) - goto error; + TEST_ERROR @@ -1131,13 +1093,13 @@ static int test_rank2( hbool_t do_compress, { printf("buf_e[%d][%d] = %d\n", i, j, buf_e[i][j]); printf("value = %d\n", comp_value); - goto error; + TEST_ERROR } } else { if(buf_e[i][j] != buf_o[i][j]) - goto error; + TEST_ERROR } } } @@ -1164,31 +1126,31 @@ static int test_rank2( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_s) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK2; i++ ) { if (dims_r[i] != dims_s[i]) - goto error; + TEST_ERROR } @@ -1199,21 +1161,21 @@ static int test_rank2( hbool_t do_compress, if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } if (H5Fclose(fid) < 0) { - goto error; + TEST_ERROR } if ((fid = H5Fopen( filename, H5F_ACC_RDWR, fapl ))<0) { - goto error; + TEST_ERROR } if ((did = H5Dopen2( fid , "dset1", H5P_DEFAULT ))<0) { - goto error; + TEST_ERROR } @@ -1229,7 +1191,7 @@ static int test_rank2( hbool_t do_compress, /* read */ if (H5Dread( did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_s ) < 0) { - goto error; + TEST_ERROR } #if defined (H5_SET_EXTENT_DEBUG2) @@ -1256,7 +1218,7 @@ static int test_rank2( hbool_t do_compress, { printf("buf_s[%d][%d] = %d\n", i, j, buf_s[i][j]); printf("buf_o[%d][%d] = %d\n", i, j, buf_o[i][j]); - goto error; + TEST_ERROR } } } @@ -1277,31 +1239,31 @@ static int test_rank2( hbool_t do_compress, /* set new dimensions for the array */ if (H5Dset_extent(did, dims_o) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions. */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK2; i++ ) { if (dims_r[i] != dims_o[i]) - goto error; + TEST_ERROR } @@ -1312,7 +1274,7 @@ static int test_rank2( hbool_t do_compress, /* read */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_r) < 0) - goto error; + TEST_ERROR #if defined (H5_SET_EXTENT_DEBUG2) printf("\n"); @@ -1339,13 +1301,13 @@ static int test_rank2( hbool_t do_compress, { printf("buf_r[%d][%d] = %d\n", i, j, buf_r[i][j]); printf("value = %d\n", comp_value); - goto error; + TEST_ERROR } } else { if(buf_r[i][j] != buf_o[i][j]) - goto error; + TEST_ERROR } } } @@ -1362,31 +1324,31 @@ static int test_rank2( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_s) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK2; i++ ) { if (dims_r[i] != dims_s[i]) - goto error; + TEST_ERROR } @@ -1397,7 +1359,7 @@ static int test_rank2( hbool_t do_compress, if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } @@ -1409,29 +1371,29 @@ static int test_rank2( hbool_t do_compress, if ((sid = H5Screate_simple(RANK2, dims_o, maxdims)) < 0) { - goto error; + TEST_ERROR } - if ((did = H5Dcreate2(fid , "dset3", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid , "dset3", H5T_NATIVE_INT, sid, H5P_DEFAULT, my_dcpl, H5P_DEFAULT)) < 0) { - goto error; + TEST_ERROR } /* set new dimensions for the array */ dims_o[ 0 ] = 0; dims_o[ 1 ] = 0; if (H5Dset_extent( did , dims_o ) < 0) { - goto error; + TEST_ERROR } if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -1443,20 +1405,20 @@ static int test_rank2( hbool_t do_compress, */ - if (H5Pclose(dcpl) < 0) + if (H5Pclose(my_dcpl) < 0) { - goto error; + TEST_ERROR } /* close file creation property list */ if(H5Pclose(fcpl) < 0) { - goto error; + TEST_ERROR } if (H5Fclose( fid ) < 0) { - goto error; + TEST_ERROR } @@ -1470,7 +1432,7 @@ error: { H5Dclose( did ); H5Sclose( sid ); - H5Pclose( dcpl ); + H5Pclose( my_dcpl ); H5Pclose( fcpl ); H5Fclose( fid ); } H5E_END_TRY; @@ -1486,17 +1448,16 @@ error: *------------------------------------------------------------------------- */ -static int test_rank3( hbool_t do_compress, +static int test_rank3( hid_t fapl, + hid_t dcpl, hbool_t do_fill_value, - hbool_t set_istore_k, - H5D_fill_time_t fill_time, - hid_t fapl) + hbool_t set_istore_k) { hid_t fid=-1; hid_t did=-1; hid_t sid=-1; - hid_t dcpl=-1; + hid_t my_dcpl=-1; hid_t fcpl; hsize_t dims_o[RANK3] = {DIM0,DIM1,DIM2}; /* original dimensions */ hsize_t dims_s[RANK3] = {DIMS0,DIMS1,DIMS2}; /* shrinking dimensions */ @@ -1509,13 +1470,12 @@ static int test_rank3( hbool_t do_compress, int buf_e[DIME0][DIME1][DIME2]; int buf_r[DIM0][DIM1][DIM2]; int i, j, k; - int fillvalue = 1; int comp_value; char filename[NAME_BUF_SIZE]; if ( do_fill_value ) { - comp_value = fillvalue; + comp_value = FILL_VALUE; } else { @@ -1537,7 +1497,7 @@ static int test_rank3( hbool_t do_compress, /* create a file creation property list */ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { - goto error; + TEST_ERROR } if ( set_istore_k ) @@ -1545,7 +1505,7 @@ static int test_rank3( hbool_t do_compress, /* set non-default indexed storage B-tree internal 'K' value */ if (H5Pset_istore_k(fcpl,ISTORE_IK) < 0) { - goto error; + TEST_ERROR } } @@ -1553,57 +1513,29 @@ static int test_rank3( hbool_t do_compress, h5_fixname(FILENAME[2], fapl, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) { - goto error; + TEST_ERROR } /* close property list */ if(H5Pclose(fcpl) < 0) { - goto error; + TEST_ERROR } /* create the data space with unlimited dimensions. */ if ((sid = H5Screate_simple(RANK3, dims_o, maxdims)) < 0) { - goto error; + TEST_ERROR } /* modify dataset creation properties, i.e. enable chunking. */ - if ((dcpl = H5Pcreate (H5P_DATASET_CREATE)) < 0) + if ((my_dcpl = H5Pcopy (dcpl)) < 0) { - goto error; + TEST_ERROR } - if (H5Pset_chunk(dcpl, RANK3, dims_c) < 0) + if (H5Pset_chunk(my_dcpl, RANK3, dims_c) < 0) { - goto error; - } - if ( do_fill_value ) - { - if (H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fillvalue) < 0) - { - goto error; - } - - if(H5Pset_fill_time(dcpl, fill_time) < 0) - { - goto error; - } - } - else - { - - if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) - { - goto error; - } - - } - if (do_compress) - { - if(H5Pset_deflate(dcpl, 9) < 0) - { - goto error; - } + TEST_ERROR } /*------------------------------------------------------------------------- @@ -1612,15 +1544,15 @@ static int test_rank3( hbool_t do_compress, */ /* create a dataset */ - if ((did = H5Dcreate2(fid , "dset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid , "dset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, my_dcpl, H5P_DEFAULT)) < 0) { - goto error; + TEST_ERROR } /* write */ if (H5Dwrite(did , H5T_NATIVE_INT, sid, H5S_ALL, H5P_DEFAULT, buf_o) < 0) { - goto error; + TEST_ERROR } @@ -1646,7 +1578,7 @@ static int test_rank3( hbool_t do_compress, if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /*------------------------------------------------------------------------- @@ -1658,24 +1590,24 @@ static int test_rank3( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_e) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -1683,12 +1615,12 @@ static int test_rank3( hbool_t do_compress, for( i = 0; i < RANK3; i++ ) { if (dims_r[i] != dims_e[i]) - goto error; + TEST_ERROR } /* read */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_e) < 0) - goto error; + TEST_ERROR @@ -1726,13 +1658,13 @@ static int test_rank3( hbool_t do_compress, { printf("buf_e[%d][%d][%d] = %d\n", i, j, k, buf_e[i][j][k] ); printf("value = %d\n", comp_value); - goto error; + TEST_ERROR } } else { if(buf_e[i][j][k] != buf_o[i][j][k] ) - goto error; + TEST_ERROR } } } @@ -1749,31 +1681,31 @@ static int test_rank3( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_s) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK3; i++ ) { if (dims_r[i] != dims_s[i]) - goto error; + TEST_ERROR } @@ -1784,21 +1716,21 @@ static int test_rank3( hbool_t do_compress, if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } if (H5Fclose(fid) < 0) { - goto error; + TEST_ERROR } if ((fid = H5Fopen( filename, H5F_ACC_RDWR, fapl ))<0) { - goto error; + TEST_ERROR } if ((did = H5Dopen2( fid , "dset1", H5P_DEFAULT ))<0) { - goto error; + TEST_ERROR } @@ -1814,7 +1746,7 @@ static int test_rank3( hbool_t do_compress, /* read */ if (H5Dread( did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_s ) < 0) { - goto error; + TEST_ERROR } #if defined (H5_SET_EXTENT_DEBUG3) @@ -1849,7 +1781,7 @@ static int test_rank3( hbool_t do_compress, { printf("buf_s[%d][%d][%d] = %d\n", i, j, k, buf_s[i][j][k] ); printf("buf_o[%d][%d][%d] = %d\n", i, j, k, buf_o[i][j][k] ); - goto error; + TEST_ERROR } } } @@ -1864,36 +1796,36 @@ static int test_rank3( hbool_t do_compress, /* set new dimensions for the array */ if (H5Dset_extent(did, dims_o) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions. */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK3; i++ ) { if (dims_r[i] != dims_o[i]) - goto error; + TEST_ERROR } /* read */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_r) < 0) - goto error; + TEST_ERROR #if defined (H5_SET_EXTENT_DEBUG3) printf("\n"); @@ -1929,13 +1861,13 @@ static int test_rank3( hbool_t do_compress, { printf("buf_r[%d][%d][%d] = %d\n", i, j, k, buf_r[i][j][k] ); printf("value = %d\n", comp_value); - goto error; + TEST_ERROR } } else { if(buf_r[i][j][k] != buf_o[i][j][k]) - goto error; + TEST_ERROR } } } @@ -1955,31 +1887,31 @@ static int test_rank3( hbool_t do_compress, /* set new dimensions for the array. */ if (H5Dset_extent(did , dims_s) < 0) { - goto error; + TEST_ERROR } /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK3; i++ ) { if (dims_r[i] != dims_s[i]) - goto error; + TEST_ERROR } @@ -1991,7 +1923,7 @@ static int test_rank3( hbool_t do_compress, if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } @@ -2003,11 +1935,11 @@ static int test_rank3( hbool_t do_compress, if ((sid = H5Screate_simple(RANK3, dims_o, maxdims)) < 0) { - goto error; + TEST_ERROR } - if ((did = H5Dcreate2(fid , "dset3", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid , "dset3", H5T_NATIVE_INT, sid, H5P_DEFAULT, my_dcpl, H5P_DEFAULT)) < 0) { - goto error; + TEST_ERROR } /* set new dimensions for the array */ dims_o[ 0 ] = 0; @@ -2015,18 +1947,18 @@ static int test_rank3( hbool_t do_compress, dims_o[ 2 ] = 0; if (H5Dset_extent( did , dims_o ) < 0) { - goto error; + TEST_ERROR } if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -2038,14 +1970,14 @@ static int test_rank3( hbool_t do_compress, */ - if (H5Pclose(dcpl) < 0) + if (H5Pclose(my_dcpl) < 0) { - goto error; + TEST_ERROR } if (H5Fclose( fid ) < 0) { - goto error; + TEST_ERROR } @@ -2059,7 +1991,7 @@ error: { H5Dclose( did ); H5Sclose( sid ); - H5Pclose( dcpl ); + H5Pclose( my_dcpl ); H5Pclose( fcpl ); H5Fclose( fid ); } H5E_END_TRY; @@ -2109,7 +2041,7 @@ static int test_external( hid_t fapl ) } } - TESTING_2("external file use"); + TESTING("external file use"); /* create a new file */ h5_fixname(FILENAME[3], fapl, filename, sizeof filename); @@ -2418,6 +2350,7 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) hid_t did=-1; hid_t sid=-1; hid_t dcpl=-1; + herr_t ret; hsize_t dims_o[RANK2] = {DIM0,DIM1}; /* original dimensions */ hsize_t dims_s[RANK2] = {DIMS0,DIMS1}; /* shrinking dimensions */ hsize_t dims_e[RANK2] = {DIME0,DIME1}; /* extended dimensions */ @@ -2440,36 +2373,36 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) h5_fixname(FILENAME[4], fapl, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) { - goto error; + TEST_ERROR } /* create the data space with unlimited dimensions. */ if ((sid = H5Screate_simple(RANK2, dims_o, NULL)) < 0) { - goto error; + TEST_ERROR } /* modify dataset creation properties */ if ((dcpl = H5Pcreate (H5P_DATASET_CREATE)) < 0) { - goto error; + TEST_ERROR } if (H5Pset_layout (dcpl, layout) < 0) { - goto error; + TEST_ERROR } /* create a dataset */ if ((did = H5Dcreate2(fid , "dset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) { - goto error; + TEST_ERROR } /* write */ if (H5Dwrite(did , H5T_NATIVE_INT, sid, H5S_ALL, H5P_DEFAULT, buf_o) < 0) { - goto error; + TEST_ERROR } @@ -2489,7 +2422,7 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /*------------------------------------------------------------------------- @@ -2501,31 +2434,31 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) H5E_BEGIN_TRY { - if (H5Dset_extent(did , dims_e) == SUCCEED) - { - goto error; - } + ret = H5Dset_extent(did , dims_e); } H5E_END_TRY; + if(ret >= 0) + TEST_ERROR + /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } @@ -2533,12 +2466,12 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) for( i = 0; i < RANK2; i++ ) { if (dims_r[i] != dims_o[i]) - goto error; + TEST_ERROR } /* read */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_r) < 0) - goto error; + TEST_ERROR @@ -2565,36 +2498,36 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) H5E_BEGIN_TRY { - if (H5Dset_extent(did , dims_s) == SUCCEED) - { - goto error; - } + ret = H5Dset_extent(did , dims_s); } H5E_END_TRY; + if(ret >= 0) + TEST_ERROR + /* get the space */ if ((sid = H5Dget_space(did)) < 0) { - goto error; + TEST_ERROR } /* get dimensions */ if (H5Sget_simple_extent_dims(sid, dims_r, NULL) < 0) { - goto error; + TEST_ERROR } if (H5Sclose(sid) < 0) { - goto error; + TEST_ERROR } /* check dimensions */ for( i = 0; i < RANK2; i++ ) { if (dims_r[i] != dims_o[i]) - goto error; + TEST_ERROR } @@ -2606,7 +2539,7 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) /* read */ if (H5Dread( did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf_r ) < 0) { - goto error; + TEST_ERROR } #if defined (H5_SET_EXTENT_DEBUG4) @@ -2630,17 +2563,17 @@ static int test_layouts( H5D_layout_t layout, hid_t fapl ) if (H5Dclose(did) < 0) { - goto error; + TEST_ERROR } if (H5Pclose(dcpl) < 0) { - goto error; + TEST_ERROR } if (H5Fclose( fid ) < 0) { - goto error; + TEST_ERROR } @@ -2661,3 +2594,176 @@ error: } + +/*------------------------------------------------------------------------- + * Function: test_random_rank4 + * + * Purpose: Test expanding and shrinking a rank 4 dataset in a + * randomized fashion. Verifies that data is preserved (and + * filled, if do_fillvalue is true) as expected. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Monday, January 11, 2010 + * + *------------------------------------------------------------------------- + */ +static int test_random_rank4( hid_t fapl, hid_t dcpl, hbool_t do_fillvalue ) +{ + hid_t file = -1; + hid_t dset = -1; + hid_t fspace = -1; + hid_t mspace = -1; + hid_t my_dcpl = -1; + hsize_t dims[4]; /* Dataset's dimensions */ + hsize_t old_dims[4]; /* Old dataset dimensions */ + hsize_t cdims[4]; /* Chunk dimensions */ + const hsize_t mdims[4] = {10, 10, 10, 10}; /* Memory buffer dimensions */ + const hsize_t start[4] = {0, 0, 0, 0}; /* Start for hyperslabe operations on memory */ + static int rbuf[10][10][10][10]; /* Read buffer */ + static int wbuf[10][10][10][10]; /* Write buffer */ + static hsize_t dim_log[RAND4_NITER+1][4]; /* Log of dataset dimensions */ + volatile unsigned i, j, k, l, m; /* Local indices */ + char filename[NAME_BUF_SIZE]; + + /* create a new file */ + h5_fixname(FILENAME[4], fapl, filename, sizeof filename); + if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Generate random chunk dimensions, 2-6 */ + for(i=0; i<4; i++) + cdims[i] = (hsize_t)((HDrandom() % 5) + 2); + + /* Generate initial dataset size, 1-10 */ + for(i=0; i<4; i++) { + dims[i] = (hsize_t)((HDrandom() % 10) + 1); + dim_log[0][i] = dims[i]; + } /* end for */ + + /* Create dataset */ + if((fspace = H5Screate_simple(4, dims, mdims)) < 0) + TEST_ERROR + if((my_dcpl = H5Pcopy(dcpl)) < 0) + TEST_ERROR + if(H5Pset_chunk(my_dcpl, 4, cdims) < 0) + TEST_ERROR + if((dset = H5Dcreate2(file, "dset", H5T_NATIVE_INT, fspace, H5P_DEFAULT, + my_dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Sclose(fspace) < 0) + TEST_ERROR + + /* Create memory space, and set initial selection */ + if((mspace = H5Screate_simple(4, mdims, NULL)) < 0) + TEST_ERROR + if(H5Sselect_hyperslab(mspace, H5S_SELECT_SET, start, NULL, dims, NULL) + < 0) + TEST_ERROR + + /* Main loop */ + for(i=0; i<RAND4_NITER; i++) { + /* Generate random write buffer */ + for(j=0; j<dims[0]; j++) + for(k=0; k<dims[1]; k++) + for(l=0; l<dims[2]; l++) + for(m=0; m<dims[3]; m++) + wbuf[j][k][l][m] = HDrandom(); + + /* Write data */ + if(H5Dwrite(dset, H5T_NATIVE_INT, mspace, H5S_ALL, H5P_DEFAULT, wbuf) + < 0) + RAND4_FAIL_DUMP(i+1, -1, -1, -1, -1) + + /* Generate new dataset size, 1-10 */ + for(j=0; j<4; j++) { + old_dims[j] = dims[j]; + dims[j] = (hsize_t)((HDrandom() % 10) + 1); + dim_log[i+1][j] = dims[j]; + } /* end for */ + + /* Resize dataset */ + if(H5Dset_extent(dset, dims) < 0) + RAND4_FAIL_DUMP(i+2, -1, -1, -1, -1) + + /* Read data from resized dataset */ + if(H5Sselect_hyperslab(mspace, H5S_SELECT_SET, start, NULL, dims, NULL) + < 0) + RAND4_FAIL_DUMP(i+2, -1, -1, -1, -1) + if(H5Dread(dset, H5T_NATIVE_INT, mspace, H5S_ALL, H5P_DEFAULT, rbuf) + < 0) + RAND4_FAIL_DUMP(i+2, -1, -1, -1, -1) + + /* Verify correctness of read data */ + if(do_fillvalue) { + for(j=0; j<dims[0]; j++) + for(k=0; k<dims[1]; k++) + for(l=0; l<dims[2]; l++) + for(m=0; m<dims[3]; m++) + if(j >= old_dims[0] || k >= old_dims[1] + || l >= old_dims[2] || m >= old_dims[3]) { + if(FILL_VALUE != rbuf[j][k][l][m]) + RAND4_FAIL_DUMP(i+2, (int)j, (int)k, (int)l, (int)m) + } /* end if */ + else + if(wbuf[j][k][l][m] != rbuf[j][k][l][m]) + RAND4_FAIL_DUMP(i+2, (int)j, (int)k, (int)l, (int)m) + } /* end if */ + else { + for(j=0; j<MIN(dims[0],old_dims[0]); j++) + for(k=0; k<MIN(dims[1],old_dims[1]); k++) + for(l=0; l<MIN(dims[2],old_dims[2]); l++) + for(m=0; m<MIN(dims[3],old_dims[3]); m++) + if(wbuf[j][k][l][m] != rbuf[j][k][l][m]) + RAND4_FAIL_DUMP(i+2, (int)j, (int)k, (int)l, (int)m) + } /* end else */ + } /* end for */ + + /* Close */ + if(H5Sclose(mspace) < 0) + TEST_ERROR + if(H5Pclose(my_dcpl) < 0) + TEST_ERROR + if(H5Dclose(dset) < 0) + TEST_ERROR + if(H5Fclose(file) < 0) + TEST_ERROR + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(fspace); + H5Sclose(mspace); + H5Pclose(dcpl); + H5Dclose(dset); + H5Fclose(file); + } H5E_END_TRY + return -1; +} /* end test_random_rank4 */ + +/* + * test_random_rank4_dump: Dump debugging info from test_random_rank4 to screen + * after failure. + */ +static void test_random_rank4_dump( unsigned ndim_sets, hsize_t dim_log[][4], + hsize_t cdims[4], int j, int k, int l, int m ) +{ + unsigned i; + + printf(" Chunk dimensions: ( %u, %u, %u, %u )\n", (unsigned)cdims[0], + (unsigned)cdims[1], (unsigned)cdims[2], (unsigned)cdims[3]); + printf(" Log of dataset dimensions (oldest first):\n"); + for(i=0; i<ndim_sets; i++) + printf(" Iteration %-3u: ( %2u, %2u, %2u, %2u )\n", i, + (unsigned)dim_log[i][0], (unsigned)dim_log[i][1], + (unsigned)dim_log[i][2], (unsigned)dim_log[i][3]); + if(j>=0) + printf(" First incorrect value read: ( %d, %d, %d, %d )\n", j, k, l, + m); + + return; +} /* end test_random_rank4_dump */ + |