diff options
Diffstat (limited to 'src')
127 files changed, 5526 insertions, 4480 deletions
@@ -22,6 +22,8 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5lib_settings.h" /* Library build setings */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ @@ -760,6 +760,11 @@ H5AC_dest(H5F_t *f, hid_t dxpl_id) HDassert(f); HDassert(f->shared->cache); +#if H5AC_DUMP_STATS_ON_CLOSE + /* Dump debugging info */ + H5AC_stats(f); +#endif /* H5AC_DUMP_STATS_ON_CLOSE */ + #if H5AC__TRACE_FILE_ENABLED if(H5AC_close_trace_file(f->shared->cache) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_close_trace_file() failed.") @@ -847,8 +852,8 @@ H5AC_expunge_entry(H5F_t *f, H5AC_t * cache_ptr = f->shared->cache; - /* For the expunge entry call, only the addr, and type id are really - * necessary in the trace file. Write the return value to catch occult + /* For the expunge entry call, only the addr, and type id are really + * necessary in the trace file. Write the return value to catch occult * errors. */ if ( ( cache_ptr != NULL ) && @@ -1207,19 +1212,21 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, #endif /* H5AC__TRACE_FILE_ENABLED */ #ifdef H5_HAVE_PARALLEL - if ( ( aux_ptr != NULL ) && - ( aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold ) ) { - - result = H5AC_propagate_flushed_and_still_clean_entries_list(f, - H5AC_noblock_dxpl_id, - f->shared->cache, - TRUE); - if ( result < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ - "Can't propagate clean entries list.") - } - } + /* Check if we should try to flush */ + if(aux_ptr && (aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold)) { + hbool_t evictions_enabled; + + /* Query if evictions are allowed */ + if(H5C_get_evictions_enabled((const H5C_t *)f->shared->cache, &evictions_enabled) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "H5C_get_evictions_enabled() failed.") + + /* Flush if evictions are allowed */ + if(evictions_enabled) { + if(H5AC_propagate_flushed_and_still_clean_entries_list(f, + H5AC_noblock_dxpl_id, f->shared->cache, TRUE) < 0 ) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't propagate clean entries list.") + } /* end if */ + } /* end if */ #endif /* H5_HAVE_PARALLEL */ done: @@ -1489,19 +1496,21 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad } #ifdef H5_HAVE_PARALLEL - if ( ( aux_ptr != NULL ) && - ( aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold ) ) { - - result = H5AC_propagate_flushed_and_still_clean_entries_list(f, - H5AC_noblock_dxpl_id, - f->shared->cache, - TRUE); - if ( result < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ - "Can't propagate clean entries list.") - } - } + /* Check if we should try to flush */ + if(aux_ptr && (aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold)) { + hbool_t evictions_enabled; + + /* Query if evictions are allowed */ + if(H5C_get_evictions_enabled((const H5C_t *)f->shared->cache, &evictions_enabled) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "H5C_get_evictions_enabled() failed.") + + /* Flush if evictions are allowed */ + if(evictions_enabled) { + if(H5AC_propagate_flushed_and_still_clean_entries_list(f, + H5AC_noblock_dxpl_id, f->shared->cache, TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't propagate clean entries list.") + } /* end if */ + } /* end if */ #endif /* H5_HAVE_PARALLEL */ done: @@ -2183,20 +2192,21 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, } #ifdef H5_HAVE_PARALLEL - if ( ( aux_ptr != NULL ) && - ( aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold ) ) { - - result = H5AC_propagate_flushed_and_still_clean_entries_list(f, - H5AC_noblock_dxpl_id, - f->shared->cache, - TRUE); - - if ( result < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ - "Can't propagate clean entries list.") - } - } + /* Check if we should try to flush */ + if(aux_ptr && (aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold)) { + hbool_t evictions_enabled; + + /* Query if evictions are allowed */ + if(H5C_get_evictions_enabled((const H5C_t *)f->shared->cache, &evictions_enabled) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "H5C_get_evictions_enabled() failed.") + + /* Flush if evictions are allowed */ + if(evictions_enabled) { + if(H5AC_propagate_flushed_and_still_clean_entries_list(f, + H5AC_noblock_dxpl_id, f->shared->cache, TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't propagate clean entries list.") + } /* end if */ + } /* end if */ #endif /* H5_HAVE_PARALLEL */ done: diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c index eb2c741..31dcb66 100644 --- a/src/H5Abtree2.c +++ b/src/H5Abtree2.c @@ -326,7 +326,8 @@ H5A_dense_btree2_name_encode(uint8_t *raw, const void *_nrecord, void UNUSED *ct FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_name_encode) /* Encode the record's fields */ - UINT64ENCODE(raw, nrecord->id); + HDmemcpy(raw, nrecord->id.id, (size_t)H5O_FHEAP_ID_LEN); + raw += H5O_FHEAP_ID_LEN; *raw++ = nrecord->flags; UINT32ENCODE(raw, nrecord->corder) UINT32ENCODE(raw, nrecord->hash) @@ -356,7 +357,8 @@ H5A_dense_btree2_name_decode(const uint8_t *raw, void *_nrecord, void UNUSED *ct FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_name_decode) /* Decode the record's fields */ - UINT64DECODE(raw, nrecord->id); + HDmemcpy(nrecord->id.id, raw, (size_t)H5O_FHEAP_ID_LEN); + raw += H5O_FHEAP_ID_LEN; nrecord->flags = *raw++; UINT32DECODE(raw, nrecord->corder) UINT32DECODE(raw, nrecord->hash) @@ -388,7 +390,7 @@ H5A_dense_btree2_name_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dx HDfprintf(stream, "%*s%-*s {%016Hx, %02x, %u, %08lx}\n", indent, "", fwidth, "Record:", - (hsize_t)nrecord->id, (unsigned)nrecord->flags, (unsigned)nrecord->corder, (unsigned long)nrecord->hash); + (hsize_t)nrecord->id.val, (unsigned)nrecord->flags, (unsigned)nrecord->corder, (unsigned long)nrecord->hash); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A_dense_btree2_name_debug() */ @@ -484,7 +486,8 @@ H5A_dense_btree2_corder_encode(uint8_t *raw, const void *_nrecord, void UNUSED * FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_encode) /* Encode the record's fields */ - UINT64ENCODE(raw, nrecord->id); + HDmemcpy(raw, nrecord->id.id, (size_t)H5O_FHEAP_ID_LEN); + raw += H5O_FHEAP_ID_LEN; *raw++ = nrecord->flags; UINT32ENCODE(raw, nrecord->corder) @@ -513,7 +516,8 @@ H5A_dense_btree2_corder_decode(const uint8_t *raw, void *_nrecord, void UNUSED * FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_btree2_corder_decode) /* Decode the record's fields */ - UINT64DECODE(raw, nrecord->id); + HDmemcpy(nrecord->id.id, raw, (size_t)H5O_FHEAP_ID_LEN); + raw += H5O_FHEAP_ID_LEN; nrecord->flags = *raw++; UINT32DECODE(raw, nrecord->corder) @@ -544,7 +548,7 @@ H5A_dense_btree2_corder_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED HDfprintf(stream, "%*s%-*s {%016Hx, %02x, %u}\n", indent, "", fwidth, "Record:", - (hsize_t)nrecord->id, (unsigned)nrecord->flags, (unsigned)nrecord->corder); + (hsize_t)nrecord->id.val, (unsigned)nrecord->flags, (unsigned)nrecord->corder); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A_dense_btree2_corder_debug() */ diff --git a/src/H5Aint.c b/src/H5Aint.c index a89c1c9..63f7e60 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -269,6 +269,10 @@ H5A_dense_build_table_cb(const H5A_t *attr, void *_udata) HDassert(udata); HDassert(udata->curr_attr < udata->atable->nattrs); + /* Allocate attribute for entry in the table */ + if(NULL == (udata->atable->attrs[udata->curr_attr] = H5FL_CALLOC(H5A_t))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, H5_ITER_ERROR, "can't allocate attribute") + /* Copy attribute information. Share the attribute object in copying. */ if(NULL == H5A_copy(udata->atable->attrs[udata->curr_attr], attr)) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute") @@ -333,17 +337,11 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, if(atable->nattrs > 0) { H5A_dense_bt_ud_t udata; /* User data for iteration callback */ H5A_attr_iter_op_t attr_op; /* Attribute operator */ - unsigned i; /* Allocate the table to store the attributes */ - if((atable->attrs = (H5A_t **)H5FL_SEQ_MALLOC(H5A_t_ptr, atable->nattrs)) == NULL) + if((atable->attrs = (H5A_t **)H5FL_SEQ_CALLOC(H5A_t_ptr, atable->nattrs)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* Allocate pointers for each entry in the table */ - for(i=0; i<atable->nattrs; i++) - if((atable->attrs[i] = (H5A_t *)H5FL_CALLOC(H5A_t)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* Set up user data for iteration */ udata.atable = atable; udata.curr_attr = 0; @@ -638,15 +636,11 @@ done: * Programmer: Quincey Koziol * Dec 11, 2006 * - * Modification: Raymond Lu - * 4 June 2008 - * Changed from H5A_free to H5A_close to release attributes. *------------------------------------------------------------------------- */ herr_t H5A_attr_release_table(H5A_attr_table_t *atable) { - size_t u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5A_attr_release_table) @@ -656,11 +650,12 @@ H5A_attr_release_table(H5A_attr_table_t *atable) /* Release attribute info, if any. */ if(atable->nattrs > 0) { + size_t u; /* Local index variable */ + /* Free attribute message information */ - for(u = 0; u < atable->nattrs; u++) { - if(H5A_close((atable->attrs[u])) < 0) + for(u = 0; u < atable->nattrs; u++) + if(atable->attrs[u] && H5A_close(atable->attrs[u]) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute") - } } /* end if */ else HDassert(atable->attrs == NULL); @@ -1154,7 +1149,7 @@ H5A_dense_copy_file_cb(const H5A_t *attr_src, void *_udata) HDassert(udata->file); HDassert(udata->cpy_info); - if ( NULL == (attr_dst=H5A_attr_copy_file(attr_src, udata->file, + if ( NULL == (attr_dst=H5A_attr_copy_file(attr_src, udata->file, udata->recompute_size, udata->cpy_info, udata->dxpl_id))) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute") @@ -1190,7 +1185,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +herr_t H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst, const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id) { @@ -1275,7 +1270,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +herr_t H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t *ainfo_src, H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info) { diff --git a/src/H5Apkg.h b/src/H5Apkg.h index de57e79..27f500e 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -283,7 +283,7 @@ H5_DLL H5A_t *H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t H5O_copy_t *cpy_info, hid_t dxpl_id); H5_DLL herr_t H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *mesg_src, H5O_loc_t *dst_oloc, const H5A_t *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info); -H5_DLL herr_t H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst, +H5_DLL herr_t H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst, const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id); H5_DLL herr_t H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t * ainfo_src, H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info); diff --git a/src/H5Atest.c b/src/H5Atest.c index df88472..845c6c8 100644 --- a/src/H5Atest.c +++ b/src/H5Atest.c @@ -37,6 +37,7 @@ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Apkg.h" /* Attributes */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ #include "H5SMprivate.h" /* Shared object header messages */ @@ -233,6 +233,7 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata, bt->nchildren = 0; if(NULL == (bt->rc_shared = (type->get_shared)(f, udata))) HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree node buffer") + H5RC_INC(bt->rc_shared); shared=(H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); HDassert(shared); if(NULL == (bt->native = H5FL_BLK_MALLOC(native_block, shared->sizeof_keys)) || @@ -321,7 +322,7 @@ H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *u while(lt < rt && cmp) { idx = (lt + rt) / 2; /* compare */ - if((cmp = (type->cmp3)(f, dxpl_id, H5B_NKEY(bt, shared, idx), udata, H5B_NKEY(bt, shared, (idx + 1)))) < 0) + if((cmp = (type->cmp3)(H5B_NKEY(bt, shared, idx), udata, H5B_NKEY(bt, shared, (idx + 1)))) < 0) rt = idx; else lt = idx + 1; @@ -823,7 +824,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type while(lt < rt && cmp) { idx = (lt + rt) / 2; - if((cmp = (type->cmp3)(f, dxpl_id, H5B_NKEY(bt, shared, idx), udata, H5B_NKEY(bt, shared, idx + 1))) < 0) + if((cmp = (type->cmp3)(H5B_NKEY(bt, shared, idx), udata, H5B_NKEY(bt, shared, idx + 1))) < 0) rt = idx; else lt = idx + 1; @@ -850,72 +851,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 +970,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) { /* @@ -1013,7 +1036,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * The max key in the original left node must be equal to the min key * in the new node. */ - cmp = (type->cmp2)(f, dxpl_id, H5B_NKEY(bt, shared, bt->nchildren), udata, + cmp = (type->cmp2)(H5B_NKEY(bt, shared, bt->nchildren), udata, H5B_NKEY(twin, shared, 0)); HDassert(0 == cmp); #endif @@ -1271,7 +1294,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type rt = bt->nchildren; while(lt < rt && cmp) { idx = (lt + rt) / 2; - if((cmp = (type->cmp3)(f, dxpl_id, H5B_NKEY(bt, shared, idx), udata, H5B_NKEY(bt, shared, idx + 1))) < 0) + if((cmp = (type->cmp3)(H5B_NKEY(bt, shared, idx), udata, H5B_NKEY(bt, shared, idx + 1))) < 0) rt = idx; else lt = idx + 1; @@ -1321,160 +1344,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 +1588,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 +1603,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 @@ -1651,6 +1712,8 @@ H5B_shared_new(const H5F_t *f, const H5B_class_t *type, size_t sizeof_rkey) /* Set up the "global" information for this file's groups */ shared->type = type; shared->two_k = 2 * H5F_KVALUE(f, type); + shared->sizeof_addr = H5F_SIZEOF_ADDR(f); + shared->sizeof_len = H5F_SIZEOF_SIZE(f); shared->sizeof_rkey = sizeof_rkey; HDassert(shared->sizeof_rkey); shared->sizeof_keys = (shared->two_k + 1) * type->sizeof_nkey; @@ -174,7 +174,7 @@ H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, void *ctx_udat done: if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, NULL, "unable to release v2 B-tree header") - if(!ret_value && bt2) + if(!ret_value && bt2) if(H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close v2 B-tree") @@ -239,7 +239,7 @@ H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata) done: if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, NULL, "unable to release v2 B-tree header") - if(!ret_value && bt2) + if(!ret_value && bt2) if(H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close v2 B-tree") diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c index 696eb89..668bce4 100644 --- a/src/H5B2hdr.c +++ b/src/H5B2hdr.c @@ -264,9 +264,6 @@ H5B2_hdr_alloc(H5F_t *f) ret_value = hdr; done: - if(!ret_value && hdr) - if(H5B2_hdr_free(hdr) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to free shared v2 B-tree info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_hdr_alloc() */ @@ -602,7 +599,7 @@ H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id) done: /* Unprotect the header with appropriate flags */ - if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, cache_flags) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, cache_flags) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header") FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index c336227..5817d22 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -275,14 +275,14 @@ H5_DLL H5B2_internal_t *H5B2_protect_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, /* Routines for allocating nodes */ H5_DLL herr_t H5B2_split_root(H5B2_hdr_t *hdr, hid_t dxpl_id); -H5_DLL herr_t H5B2_create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, +H5_DLL herr_t H5B2_create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *node_ptr); /* Routines for inserting records */ -H5_DLL herr_t H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, +H5_DLL herr_t H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr, void *udata); -H5_DLL herr_t H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, +H5_DLL herr_t H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, void *udata); /* Routines for iterating over nodes/records */ diff --git a/src/H5Bcache.c b/src/H5Bcache.c index cc5bbbf..99cd0cd 100644 --- a/src/H5Bcache.c +++ b/src/H5Bcache.c @@ -54,9 +54,6 @@ /* Local Prototypes */ /********************/ -/* General routines */ -static herr_t H5B_serialize(const H5F_t *f, const H5B_t *bt); - /* Metadata cache callbacks */ static H5B_t *H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata); static herr_t H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *b, unsigned UNUSED * flags_ptr); @@ -86,78 +83,6 @@ const H5AC_class_t H5AC_BT[1] = {{ /*------------------------------------------------------------------------- - * Function: H5B_serialize - * - * Purpose: Serialize the data structure for writing to disk. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Bill Wendling - * wendling@ncsa.uiuc.edu - * Sept. 15, 2003 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5B_serialize(const H5F_t *f, const H5B_t *bt) -{ - H5B_shared_t *shared=NULL; /* Pointer to shared B-tree info */ - unsigned u; - uint8_t *p; /* Pointer into raw data buffer */ - uint8_t *native; /* Pointer to native keys */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5B_serialize, FAIL) - - /* check arguments */ - HDassert(f); - HDassert(bt); - HDassert(bt->rc_shared); - shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); - HDassert(shared); - - p = shared->page; - - /* magic number */ - HDmemcpy(p, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC); - p += 4; - - /* node type and level */ - *p++ = (uint8_t)shared->type->id; - H5_CHECK_OVERFLOW(bt->level, unsigned, uint8_t); - *p++ = (uint8_t)bt->level; - - /* entries used */ - UINT16ENCODE(p, bt->nchildren); - - /* sibling pointers */ - H5F_addr_encode(f, &p, bt->left); - H5F_addr_encode(f, &p, bt->right); - - /* child keys and pointers */ - native = bt->native; - for(u = 0; u < bt->nchildren; ++u) { - /* encode the key */ - if(shared->type->encode(f, bt, p, native) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key") - p += shared->sizeof_rkey; - native += shared->type->sizeof_nkey; - - /* encode the child address */ - H5F_addr_encode(f, &p, bt->child[u]); - } /* end for */ - if(bt->nchildren > 0) { - /* Encode the final key */ - if(shared->type->encode(f, bt, p, native) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key") - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5B_serialize() */ - - -/*------------------------------------------------------------------------- * Function: H5B_load * * Purpose: Loads a B-tree node from the disk. @@ -194,8 +119,12 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't allocate B-tree struct") HDmemset(&bt->cache_info, 0, sizeof(H5AC_info_t)); + /* Set & increment the ref-counted "shared" B-tree information for the node */ if(NULL == (bt->rc_shared = (type->get_shared)(f, udata))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't retrieve B-tree node buffer") + H5RC_INC(bt->rc_shared); + + /* Get a pointer to the shared info, for convenience */ shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); HDassert(shared); @@ -232,7 +161,7 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) native = bt->native; for(u = 0; u < bt->nchildren; u++) { /* Decode native key value */ - if((type->decode)(f, bt, p, native) < 0) + if((type->decode)(shared, p, native) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key") p += shared->sizeof_rkey; native += type->sizeof_nkey; @@ -244,7 +173,7 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) /* Decode final key */ if(bt->nchildren > 0) { /* Decode native key value */ - if((type->decode)(f, bt, p, native) < 0) + if((type->decode)(shared, p, native) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key") } /* end if */ @@ -290,8 +219,45 @@ H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt, uns HDassert(shared->type->encode); if(bt->cache_info.is_dirty) { - if(H5B_serialize(f, bt) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTSERIALIZE, FAIL, "unable to serialize B-tree") + uint8_t *p; /* Pointer into raw data buffer */ + uint8_t *native; /* Pointer to native keys */ + unsigned u; /* Local index variable */ + + p = shared->page; + + /* magic number */ + HDmemcpy(p, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC); + p += 4; + + /* node type and level */ + *p++ = (uint8_t)shared->type->id; + H5_CHECK_OVERFLOW(bt->level, unsigned, uint8_t); + *p++ = (uint8_t)bt->level; + + /* entries used */ + UINT16ENCODE(p, bt->nchildren); + + /* sibling pointers */ + H5F_addr_encode(f, &p, bt->left); + H5F_addr_encode(f, &p, bt->right); + + /* child keys and pointers */ + native = bt->native; + for(u = 0; u < bt->nchildren; ++u) { + /* encode the key */ + if(shared->type->encode(shared, p, native) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key") + p += shared->sizeof_rkey; + native += shared->type->sizeof_nkey; + + /* encode the child address */ + H5F_addr_encode(f, &p, bt->child[u]); + } /* end for */ + if(bt->nchildren > 0) { + /* Encode the final key */ + if(shared->type->encode(shared, p, native) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key") + } /* end if */ /* * Write the disk page. We always write the header, but we don't diff --git a/src/H5Bdbg.c b/src/H5Bdbg.c index aafb999..dff2380 100644 --- a/src/H5Bdbg.c +++ b/src/H5Bdbg.c @@ -126,14 +126,14 @@ H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), "Left Key:"); HDassert(H5B_NKEY(bt,shared,u)); - (void)(type->debug_key)(stream, f, dxpl_id, indent + 6, MAX(0, fwidth - 6), + (void)(type->debug_key)(stream, indent + 6, MAX(0, fwidth - 6), H5B_NKEY(bt, shared, u), udata); /* Decode the 'right' key & print it */ HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), "Right Key:"); HDassert(H5B_NKEY(bt, shared, u + 1)); - (void)(type->debug_key)(stream, f, dxpl_id, indent + 6, MAX (0, fwidth - 6), + (void)(type->debug_key)(stream, indent + 6, MAX (0, fwidth - 6), H5B_NKEY(bt, shared, u + 1), udata); } /* end if */ } /* end for */ @@ -239,8 +239,7 @@ H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void tail = tmp; /* Check that the keys are monotonically increasing */ - cmp = (type->cmp2)(f, dxpl_id, H5B_NKEY(bt, shared, i), udata, - H5B_NKEY(bt, shared, i + 1)); + cmp = (type->cmp2)(H5B_NKEY(bt, shared, i), udata, H5B_NKEY(bt, shared, i + 1)); HDassert(cmp < 0); } /* end for */ } /* end if */ diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h index 7aedd00..79b5e8a 100644 --- a/src/H5Bpkg.h +++ b/src/H5Bpkg.h @@ -32,6 +32,9 @@ #include "H5Bprivate.h" /* Other private headers needed by this file */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5RCprivate.h" /* Reference counted objects */ /**************************/ @@ -47,9 +50,9 @@ /****************************/ /* The B-tree node as stored in memory... */ -struct H5B_t { - H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ - /* first field in structure */ +typedef struct H5B_t { + H5AC_info_t cache_info; /* Information for H5AC cache functions */ + /* _must_ be first field in structure */ H5RC_t *rc_shared; /*ref-counted shared info */ unsigned level; /*node level */ unsigned nchildren; /*number of child pointers */ @@ -57,7 +60,7 @@ struct H5B_t { haddr_t right; /*address of right sibling */ uint8_t *native; /*array of keys in native format */ haddr_t *child; /*2k child pointers */ -}; +} H5B_t; /*****************************/ /* Package Private Variables */ @@ -75,6 +78,7 @@ H5FL_BLK_EXTERN(native_block); /* Declare a free list to manage the H5B_t struct */ H5FL_EXTERN(H5B_t); + /******************************/ /* Package Private Prototypes */ /******************************/ diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index 716b608..83a357b 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -33,9 +33,7 @@ /* Private headers needed by this file */ #include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ #include "H5Fprivate.h" /* File access */ -#include "H5FLprivate.h" /* Free Lists */ #include "H5RCprivate.h" /* Reference counted object functions */ /**************************/ @@ -78,13 +76,17 @@ 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); -/* Typedef for B-tree in memory (defined in H5Bpkg.h) */ -typedef struct H5B_t H5B_t; - /* Each B-tree has certain information that can be shared across all * the instances of nodes in that B-tree. */ @@ -94,6 +96,8 @@ typedef struct H5B_shared_t { size_t sizeof_rkey; /* Size of raw (disk) key */ size_t sizeof_rnode; /* Size of raw (disk) node */ size_t sizeof_keys; /* Size of native (memory) key node */ + size_t sizeof_addr; /* Size of file address (in bytes) */ + size_t sizeof_len; /* Size of file lengths (in bytes) */ uint8_t *page; /* Disk page */ size_t *nkey; /* Offsets of each native key in native key buffer */ } H5B_shared_t; @@ -111,8 +115,8 @@ typedef struct H5B_class_t { size_t sizeof_nkey; /*size of native (memory) key*/ H5RC_t * (*get_shared)(const H5F_t*, const void*); /*shared info for node */ herr_t (*new_node)(H5F_t*, hid_t, H5B_ins_t, void*, void*, void*, haddr_t*); - int (*cmp2)(H5F_t*, hid_t, void*, void*, void*); /*compare 2 keys */ - int (*cmp3)(H5F_t*, hid_t, void*, void*, void*); /*compare 3 keys */ + int (*cmp2)(void*, void*, void*); /*compare 2 keys */ + int (*cmp3)(void*, void*, void*); /*compare 3 keys */ htri_t (*found)(H5F_t*, hid_t, haddr_t, const void*, void*); /* insert new data */ @@ -123,14 +127,17 @@ 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*); /* encode, decode, debug key values */ - herr_t (*decode)(const H5F_t*, const struct H5B_t*, const uint8_t*, void*); - herr_t (*encode)(const H5F_t*, const struct H5B_t*, uint8_t*, void*); - herr_t (*debug_key)(FILE*, H5F_t*, hid_t, int, int, const void*, const void*); + herr_t (*decode)(const H5B_shared_t*, const uint8_t*, void*); + herr_t (*encode)(const H5B_shared_t*, uint8_t*, const void*); + herr_t (*debug_key)(FILE*, int, int, const void*, const void*); } H5B_class_t; /* Information about B-tree */ @@ -112,2587 +112,6 @@ #include "H5SLprivate.h" /* Skip lists */ -/**************************************************************************** - * - * We maintain doubly linked lists of instances of H5C_cache_entry_t for a - * variety of reasons -- protected list, LRU list, and the clean and dirty - * LRU lists at present. The following macros support linking and unlinking - * of instances of H5C_cache_entry_t by both their regular and auxilary next - * and previous pointers. - * - * The size and length fields are also maintained. - * - * Note that the relevant pair of prev and next pointers are presumed to be - * NULL on entry in the insertion macros. - * - * Finally, observe that the sanity checking macros evaluate to the empty - * string when H5C_DO_SANITY_CHECKS is FALSE. They also contain calls - * to the HGOTO_ERROR macro, which may not be appropriate in all cases. - * If so, we will need versions of the insertion and deletion macros which - * do not reference the sanity checking macros. - * JRM - 5/5/04 - * - * Changes: - * - * - Removed the line: - * - * ( ( (Size) == (entry_ptr)->size ) && ( (len) != 1 ) ) || - * - * from the H5C__DLL_PRE_REMOVE_SC macro. With the addition of the - * epoch markers used in the age out based cache size reduction algorithm, - * this invarient need not hold, as the epoch markers are of size 0. - * - * One could argue that I should have given the epoch markers a positive - * size, but this would break the index_size = LRU_list_size + pl_size - * + pel_size invarient. - * - * Alternatively, I could pass the current decr_mode in to the macro, - * and just skip the check whenever epoch markers may be in use. - * - * However, any size errors should be caught when the cache is flushed - * and destroyed. Until we are tracking such an error, this should be - * good enough. - * JRM - 12/9/04 - * - * - * - In the H5C__DLL_PRE_INSERT_SC macro, replaced the lines: - * - * ( ( (len) == 1 ) && - * ( ( (head_ptr) != (tail_ptr) ) || ( (Size) <= 0 ) || - * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) - * ) - * ) || - * - * with: - * - * ( ( (len) == 1 ) && - * ( ( (head_ptr) != (tail_ptr) ) || - * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) - * ) - * ) || - * - * Epoch markers have size 0, so we can now have a non-empty list with - * zero size. Hence the "( (Size) <= 0 )" clause cause false failures - * in the sanity check. Since "Size" is typically a size_t, it can't - * take on negative values, and thus the revised clause "( (Size) < 0 )" - * caused compiler warnings. - * JRM - 12/22/04 - * - * - In the H5C__DLL_SC macro, replaced the lines: - * - * ( ( (len) == 1 ) && - * ( ( (head_ptr) != (tail_ptr) ) || ( (cache_ptr)->size <= 0 ) || - * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) - * ) - * ) || - * - * with - * - * ( ( (len) == 1 ) && - * ( ( (head_ptr) != (tail_ptr) ) || - * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) - * ) - * ) || - * - * Epoch markers have size 0, so we can now have a non-empty list with - * zero size. Hence the "( (Size) <= 0 )" clause cause false failures - * in the sanity check. Since "Size" is typically a size_t, it can't - * take on negative values, and thus the revised clause "( (Size) < 0 )" - * caused compiler warnings. - * JRM - 1/10/05 - * - * - Added the H5C__DLL_UPDATE_FOR_SIZE_CHANGE macro and the associated - * sanity checking macros. These macro are used to update the size of - * a DLL when one of its entries changes size. - * - * JRM - 9/8/05 - * - ****************************************************************************/ - -#if H5C_DO_SANITY_CHECKS - -#define H5C__DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ -if ( ( (head_ptr) == NULL ) || \ - ( (tail_ptr) == NULL ) || \ - ( (entry_ptr) == NULL ) || \ - ( (len) <= 0 ) || \ - ( (Size) < (entry_ptr)->size ) || \ - ( ( (entry_ptr)->prev == NULL ) && ( (head_ptr) != (entry_ptr) ) ) || \ - ( ( (entry_ptr)->next == NULL ) && ( (tail_ptr) != (entry_ptr) ) ) || \ - ( ( (len) == 1 ) && \ - ( ! ( ( (head_ptr) == (entry_ptr) ) && \ - ( (tail_ptr) == (entry_ptr) ) && \ - ( (entry_ptr)->next == NULL ) && \ - ( (entry_ptr)->prev == NULL ) && \ - ( (Size) == (entry_ptr)->size ) \ - ) \ - ) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL pre remove SC failed") \ -} - -#define H5C__DLL_SC(head_ptr, tail_ptr, len, Size, fv) \ -if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ - ( (head_ptr) != (tail_ptr) ) \ - ) || \ - ( (len) < 0 ) || \ - ( (Size) < 0 ) || \ - ( ( (len) == 1 ) && \ - ( ( (head_ptr) != (tail_ptr) ) || \ - ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) \ - ) \ - ) || \ - ( ( (len) >= 1 ) && \ - ( ( (head_ptr) == NULL ) || ( (head_ptr)->prev != NULL ) || \ - ( (tail_ptr) == NULL ) || ( (tail_ptr)->next != NULL ) \ - ) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL sanity check failed") \ -} - -#define H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ -if ( ( (entry_ptr) == NULL ) || \ - ( (entry_ptr)->next != NULL ) || \ - ( (entry_ptr)->prev != NULL ) || \ - ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ - ( (head_ptr) != (tail_ptr) ) \ - ) || \ - ( (len) < 0 ) || \ - ( ( (len) == 1 ) && \ - ( ( (head_ptr) != (tail_ptr) ) || \ - ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) \ - ) \ - ) || \ - ( ( (len) >= 1 ) && \ - ( ( (head_ptr) == NULL ) || ( (head_ptr)->prev != NULL ) || \ - ( (tail_ptr) == NULL ) || ( (tail_ptr)->next != NULL ) \ - ) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL pre insert SC failed") \ -} - -#define H5C__DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) \ -if ( ( (dll_len) <= 0 ) || \ - ( (dll_size) <= 0 ) || \ - ( (old_size) <= 0 ) || \ - ( (old_size) > (dll_size) ) || \ - ( (new_size) <= 0 ) || \ - ( ( (dll_len) == 1 ) && ( (old_size) != (dll_size) ) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "DLL pre size update SC failed") \ -} - -#define H5C__DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) \ -if ( ( (new_size) > (dll_size) ) || \ - ( ( (dll_len) == 1 ) && ( (new_size) != (dll_size) ) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "DLL post size update SC failed") \ -} - -#else /* H5C_DO_SANITY_CHECKS */ - -#define H5C__DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) -#define H5C__DLL_SC(head_ptr, tail_ptr, len, Size, fv) -#define H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) -#define H5C__DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) -#define H5C__DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) - -#endif /* H5C_DO_SANITY_CHECKS */ - - -#define H5C__DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \ - H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ - fail_val) \ - if ( (head_ptr) == NULL ) \ - { \ - (head_ptr) = (entry_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - else \ - { \ - (tail_ptr)->next = (entry_ptr); \ - (entry_ptr)->prev = (tail_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - (len)++; \ - (Size) += (entry_ptr)->size; - -#define H5C__DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \ - H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ - fail_val) \ - if ( (head_ptr) == NULL ) \ - { \ - (head_ptr) = (entry_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - else \ - { \ - (head_ptr)->prev = (entry_ptr); \ - (entry_ptr)->next = (head_ptr); \ - (head_ptr) = (entry_ptr); \ - } \ - (len)++; \ - (Size) += entry_ptr->size; - -#define H5C__DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \ - H5C__DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ - fail_val) \ - { \ - if ( (head_ptr) == (entry_ptr) ) \ - { \ - (head_ptr) = (entry_ptr)->next; \ - if ( (head_ptr) != NULL ) \ - { \ - (head_ptr)->prev = NULL; \ - } \ - } \ - else \ - { \ - (entry_ptr)->prev->next = (entry_ptr)->next; \ - } \ - if ( (tail_ptr) == (entry_ptr) ) \ - { \ - (tail_ptr) = (entry_ptr)->prev; \ - if ( (tail_ptr) != NULL ) \ - { \ - (tail_ptr)->next = NULL; \ - } \ - } \ - else \ - { \ - (entry_ptr)->next->prev = (entry_ptr)->prev; \ - } \ - entry_ptr->next = NULL; \ - entry_ptr->prev = NULL; \ - (len)--; \ - (Size) -= entry_ptr->size; \ - } - -#define H5C__DLL_UPDATE_FOR_SIZE_CHANGE(dll_len, dll_size, old_size, new_size) \ - H5C__DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) \ - (dll_size) -= (old_size); \ - (dll_size) += (new_size); \ - H5C__DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) - -#if H5C_DO_SANITY_CHECKS - -#define H5C__AUX_DLL_PRE_REMOVE_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) \ -if ( ( (hd_ptr) == NULL ) || \ - ( (tail_ptr) == NULL ) || \ - ( (entry_ptr) == NULL ) || \ - ( (len) <= 0 ) || \ - ( (Size) < (entry_ptr)->size ) || \ - ( ( (Size) == (entry_ptr)->size ) && ( ! ( (len) == 1 ) ) ) || \ - ( ( (entry_ptr)->aux_prev == NULL ) && ( (hd_ptr) != (entry_ptr) ) ) || \ - ( ( (entry_ptr)->aux_next == NULL ) && ( (tail_ptr) != (entry_ptr) ) ) || \ - ( ( (len) == 1 ) && \ - ( ! ( ( (hd_ptr) == (entry_ptr) ) && ( (tail_ptr) == (entry_ptr) ) && \ - ( (entry_ptr)->aux_next == NULL ) && \ - ( (entry_ptr)->aux_prev == NULL ) && \ - ( (Size) == (entry_ptr)->size ) \ - ) \ - ) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "aux DLL pre remove SC failed") \ -} - -#define H5C__AUX_DLL_SC(head_ptr, tail_ptr, len, Size, fv) \ -if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ - ( (head_ptr) != (tail_ptr) ) \ - ) || \ - ( (len) < 0 ) || \ - ( (Size) < 0 ) || \ - ( ( (len) == 1 ) && \ - ( ( (head_ptr) != (tail_ptr) ) || ( (Size) <= 0 ) || \ - ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) \ - ) \ - ) || \ - ( ( (len) >= 1 ) && \ - ( ( (head_ptr) == NULL ) || ( (head_ptr)->aux_prev != NULL ) || \ - ( (tail_ptr) == NULL ) || ( (tail_ptr)->aux_next != NULL ) \ - ) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "AUX DLL sanity check failed") \ -} - -#define H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) \ -if ( ( (entry_ptr) == NULL ) || \ - ( (entry_ptr)->aux_next != NULL ) || \ - ( (entry_ptr)->aux_prev != NULL ) || \ - ( ( ( (hd_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ - ( (hd_ptr) != (tail_ptr) ) \ - ) || \ - ( (len) < 0 ) || \ - ( ( (len) == 1 ) && \ - ( ( (hd_ptr) != (tail_ptr) ) || ( (Size) <= 0 ) || \ - ( (hd_ptr) == NULL ) || ( (hd_ptr)->size != (Size) ) \ - ) \ - ) || \ - ( ( (len) >= 1 ) && \ - ( ( (hd_ptr) == NULL ) || ( (hd_ptr)->aux_prev != NULL ) || \ - ( (tail_ptr) == NULL ) || ( (tail_ptr)->aux_next != NULL ) \ - ) \ - ) \ - ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "AUX DLL pre insert SC failed") \ -} - -#else /* H5C_DO_SANITY_CHECKS */ - -#define H5C__AUX_DLL_PRE_REMOVE_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) -#define H5C__AUX_DLL_SC(head_ptr, tail_ptr, len, Size, fv) -#define H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) - -#endif /* H5C_DO_SANITY_CHECKS */ - - -#define H5C__AUX_DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val)\ - H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ - fail_val) \ - if ( (head_ptr) == NULL ) \ - { \ - (head_ptr) = (entry_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - else \ - { \ - (tail_ptr)->aux_next = (entry_ptr); \ - (entry_ptr)->aux_prev = (tail_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - (len)++; \ - (Size) += entry_ptr->size; - -#define H5C__AUX_DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ - H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ - fv) \ - if ( (head_ptr) == NULL ) \ - { \ - (head_ptr) = (entry_ptr); \ - (tail_ptr) = (entry_ptr); \ - } \ - else \ - { \ - (head_ptr)->aux_prev = (entry_ptr); \ - (entry_ptr)->aux_next = (head_ptr); \ - (head_ptr) = (entry_ptr); \ - } \ - (len)++; \ - (Size) += entry_ptr->size; - -#define H5C__AUX_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ - H5C__AUX_DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ - fv) \ - { \ - if ( (head_ptr) == (entry_ptr) ) \ - { \ - (head_ptr) = (entry_ptr)->aux_next; \ - if ( (head_ptr) != NULL ) \ - { \ - (head_ptr)->aux_prev = NULL; \ - } \ - } \ - else \ - { \ - (entry_ptr)->aux_prev->aux_next = (entry_ptr)->aux_next; \ - } \ - if ( (tail_ptr) == (entry_ptr) ) \ - { \ - (tail_ptr) = (entry_ptr)->aux_prev; \ - if ( (tail_ptr) != NULL ) \ - { \ - (tail_ptr)->aux_next = NULL; \ - } \ - } \ - else \ - { \ - (entry_ptr)->aux_next->aux_prev = (entry_ptr)->aux_prev; \ - } \ - entry_ptr->aux_next = NULL; \ - entry_ptr->aux_prev = NULL; \ - (len)--; \ - (Size) -= entry_ptr->size; \ - } - - -/*********************************************************************** - * - * Stats collection macros - * - * The following macros must handle stats collection when this collection - * is enabled, and evaluate to the empty string when it is not. - * - * The sole exception to this rule is - * H5C__UPDATE_CACHE_HIT_RATE_STATS(), which is always active as - * the cache hit rate stats are always collected and available. - * - * Changes: - * - * JRM -- 3/21/06 - * Added / updated macros for pinned entry related stats. - * - * JRM -- 8/9/06 - * More pinned entry stats related updates. - * - * JRM -- 3/31/07 - * Updated H5C__UPDATE_STATS_FOR_PROTECT() to keep stats on - * read and write protects. - * - * MAM -- 1/15/09 - * Created H5C__UPDATE_MAX_INDEX_SIZE_STATS to contain - * common code within macros that update the maximum - * index, clean_index, and dirty_index statistics fields. - * - ***********************************************************************/ - -#define H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit) \ - (cache_ptr->cache_accesses)++; \ - if ( hit ) { \ - (cache_ptr->cache_hits)++; \ - } \ - -#if H5C_COLLECT_CACHE_STATS - -#define H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ - (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ - if ( (cache_ptr)->clean_index_size > \ - (cache_ptr)->max_clean_index_size ) \ - (cache_ptr)->max_clean_index_size = \ - (cache_ptr)->clean_index_size; \ - if ( (cache_ptr)->dirty_index_size > \ - (cache_ptr)->max_dirty_index_size ) \ - (cache_ptr)->max_dirty_index_size = \ - (cache_ptr)->dirty_index_size; - -#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) \ - (((cache_ptr)->dirty_pins)[(entry_ptr)->type->id])++; - -#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) \ - if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ - (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ - if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ - if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; - -#define H5C__UPDATE_STATS_FOR_RENAME(cache_ptr, entry_ptr) \ - if ( cache_ptr->flush_in_progress ) { \ - ((cache_ptr)->cache_flush_renames[(entry_ptr)->type->id])++; \ - } \ - if ( entry_ptr->flush_in_progress ) { \ - ((cache_ptr)->entry_flush_renames[(entry_ptr)->type->id])++; \ - } \ - (((cache_ptr)->renames)[(entry_ptr)->type->id])++; - -#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size)\ - if ( cache_ptr->flush_in_progress ) { \ - ((cache_ptr)->cache_flush_size_changes[(entry_ptr)->type->id])++; \ - } \ - if ( entry_ptr->flush_in_progress ) { \ - ((cache_ptr)->entry_flush_size_changes[(entry_ptr)->type->id])++; \ - } \ - if ( (entry_ptr)->size < (new_size) ) { \ - ((cache_ptr)->size_increases[(entry_ptr)->type->id])++; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ - if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ - (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ - } else if ( (entry_ptr)->size > (new_size) ) { \ - ((cache_ptr)->size_decreases[(entry_ptr)->type->id])++; \ - } - -#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ - (cache_ptr)->total_ht_insertions++; - -#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ - (cache_ptr)->total_ht_deletions++; - -#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) \ - if ( success ) { \ - (cache_ptr)->successful_ht_searches++; \ - (cache_ptr)->total_successful_ht_search_depth += depth; \ - } else { \ - (cache_ptr)->failed_ht_searches++; \ - (cache_ptr)->total_failed_ht_search_depth += depth; \ - } - -#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) \ - ((cache_ptr)->unpins)[(entry_ptr)->type->id]++; - -#if H5C_COLLECT_CACHE_ENTRY_STATS - -#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) \ - (entry_ptr)->accesses = 0; \ - (entry_ptr)->clears = 0; \ - (entry_ptr)->flushes = 0; \ - (entry_ptr)->pins = 0; - -#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ - (((cache_ptr)->clears)[(entry_ptr)->type->id])++; \ - if ( (entry_ptr)->is_pinned ) { \ - (((cache_ptr)->pinned_clears)[(entry_ptr)->type->id])++; \ - } \ - ((entry_ptr)->clears)++; - -#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ - (((cache_ptr)->flushes)[(entry_ptr)->type->id])++; \ - if ( (entry_ptr)->is_pinned ) { \ - (((cache_ptr)->pinned_flushes)[(entry_ptr)->type->id])++; \ - } \ - ((entry_ptr)->flushes)++; - -#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr) \ - (((cache_ptr)->evictions)[(entry_ptr)->type->id])++; \ - if ( (entry_ptr)->accesses > \ - ((cache_ptr)->max_accesses)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_accesses)[(entry_ptr)->type->id] \ - = (entry_ptr)->accesses; \ - } \ - if ( (entry_ptr)->accesses < \ - ((cache_ptr)->min_accesses)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->min_accesses)[(entry_ptr)->type->id] \ - = (entry_ptr)->accesses; \ - } \ - if ( (entry_ptr)->clears > \ - ((cache_ptr)->max_clears)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_clears)[(entry_ptr)->type->id] \ - = (entry_ptr)->clears; \ - } \ - if ( (entry_ptr)->flushes > \ - ((cache_ptr)->max_flushes)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_flushes)[(entry_ptr)->type->id] \ - = (entry_ptr)->flushes; \ - } \ - if ( (entry_ptr)->size > \ - ((cache_ptr)->max_size)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_size)[(entry_ptr)->type->id] \ - = (entry_ptr)->size; \ - } \ - if ( (entry_ptr)->pins > \ - ((cache_ptr)->max_pins)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_pins)[(entry_ptr)->type->id] \ - = (entry_ptr)->pins; \ - } - -#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ - (((cache_ptr)->insertions)[(entry_ptr)->type->id])++; \ - if ( (entry_ptr)->is_pinned ) { \ - (((cache_ptr)->pinned_insertions)[(entry_ptr)->type->id])++; \ - ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ - (entry_ptr)->pins++; \ - if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ - } \ - if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ - (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ - if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ - if ( (entry_ptr)->size > \ - ((cache_ptr)->max_size)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_size)[(entry_ptr)->type->id] \ - = (entry_ptr)->size; \ - } - -#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ - if ( hit ) \ - ((cache_ptr)->hits)[(entry_ptr)->type->id]++; \ - else \ - ((cache_ptr)->misses)[(entry_ptr)->type->id]++; \ - if ( ! ((entry_ptr)->is_read_only) ) { \ - ((cache_ptr)->write_protects)[(entry_ptr)->type->id]++; \ - } else { \ - ((cache_ptr)->read_protects)[(entry_ptr)->type->id]++; \ - if ( ((entry_ptr)->ro_ref_count) > \ - ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] = \ - ((entry_ptr)->ro_ref_count); \ - } \ - } \ - if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \ - (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ - if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ - (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ - if ( (entry_ptr)->size > \ - ((cache_ptr)->max_size)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_size)[(entry_ptr)->type->id] \ - = (entry_ptr)->size; \ - } \ - ((entry_ptr)->accesses)++; - -#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ - ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ - (entry_ptr)->pins++; \ - if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; - -#else /* H5C_COLLECT_CACHE_ENTRY_STATS */ - -#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) - -#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ - if ( (entry_ptr)->is_pinned ) { \ - (((cache_ptr)->pinned_clears)[(entry_ptr)->type->id])++; \ - } \ - (((cache_ptr)->clears)[(entry_ptr)->type->id])++; - -#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ - (((cache_ptr)->flushes)[(entry_ptr)->type->id])++; \ - if ( (entry_ptr)->is_pinned ) { \ - (((cache_ptr)->pinned_flushes)[(entry_ptr)->type->id])++; \ - } - -#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr) \ - (((cache_ptr)->evictions)[(entry_ptr)->type->id])++; - -#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ - (((cache_ptr)->insertions)[(entry_ptr)->type->id])++; \ - if ( (entry_ptr)->is_pinned ) { \ - (((cache_ptr)->pinned_insertions)[(entry_ptr)->type->id])++; \ - ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ - if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ - } \ - if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ - (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ - if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ - (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; - -#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ - if ( hit ) \ - ((cache_ptr)->hits)[(entry_ptr)->type->id]++; \ - else \ - ((cache_ptr)->misses)[(entry_ptr)->type->id]++; \ - if ( ! ((entry_ptr)->is_read_only) ) { \ - ((cache_ptr)->write_protects)[(entry_ptr)->type->id]++; \ - } else { \ - ((cache_ptr)->read_protects)[(entry_ptr)->type->id]++; \ - if ( ((entry_ptr)->ro_ref_count) > \ - ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] ) { \ - ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] = \ - ((entry_ptr)->ro_ref_count); \ - } \ - } \ - if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ - (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ - if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \ - (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ - if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ - (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; - -#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ - ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ - if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ - (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ - if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ - (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; - -#endif /* H5C_COLLECT_CACHE_ENTRY_STATS */ - -#else /* H5C_COLLECT_CACHE_STATS */ - -#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) -#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) -#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) -#define H5C__UPDATE_STATS_FOR_RENAME(cache_ptr, entry_ptr) -#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) -#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) -#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) -#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) -#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) -#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) -#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) -#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr) -#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) -#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) -#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) - -#endif /* H5C_COLLECT_CACHE_STATS */ - - -/*********************************************************************** - * - * Hash table access and manipulation macros: - * - * The following macros handle searches, insertions, and deletion in - * the hash table. - * - * When modifying these macros, remember to modify the similar macros - * in tst/cache.c - * - * Changes: - * - * - Updated existing index macros and sanity check macros to maintain - * the clean_index_size and dirty_index_size fields of H5C_t. Also - * added macros to allow us to track entry cleans and dirties. - * - * JRM -- 11/5/08 - * - ***********************************************************************/ - -/* H5C__HASH_TABLE_LEN is defined in H5Cpkg.h. It mut be a power of two. */ - -#define H5C__HASH_MASK ((size_t)(H5C__HASH_TABLE_LEN - 1) << 3) - -#define H5C__HASH_FCN(x) (int)(((x) & H5C__HASH_MASK) >> 3) - -#if H5C_DO_SANITY_CHECKS - -#define H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ -if ( ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ - ( (entry_ptr) == NULL ) || \ - ( ! H5F_addr_defined((entry_ptr)->addr) ) || \ - ( (entry_ptr)->ht_next != NULL ) || \ - ( (entry_ptr)->ht_prev != NULL ) || \ - ( (entry_ptr)->size <= 0 ) || \ - ( (k = H5C__HASH_FCN((entry_ptr)->addr)) < 0 ) || \ - ( k >= H5C__HASH_TABLE_LEN ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + \ - (cache_ptr)->dirty_index_size) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ - "Pre HT insert SC failed") \ -} - -#define H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr) \ -if ( ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ - ( (cache_ptr)->index_len < 1 ) || \ - ( (entry_ptr) == NULL ) || \ - ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ - ( ! H5F_addr_defined((entry_ptr)->addr) ) || \ - ( (entry_ptr)->size <= 0 ) || \ - ( H5C__HASH_FCN((entry_ptr)->addr) < 0 ) || \ - ( H5C__HASH_FCN((entry_ptr)->addr) >= H5C__HASH_TABLE_LEN ) || \ - ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] \ - == NULL ) || \ - ( ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] \ - != (entry_ptr) ) && \ - ( (entry_ptr)->ht_prev == NULL ) ) || \ - ( ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] == \ - (entry_ptr) ) && \ - ( (entry_ptr)->ht_prev != NULL ) ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + \ - (cache_ptr)->dirty_index_size) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Pre HT remove SC failed") \ -} - -#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \ -if ( ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) || \ - ( ! H5F_addr_defined(Addr) ) || \ - ( H5C__HASH_FCN(Addr) < 0 ) || \ - ( H5C__HASH_FCN(Addr) >= H5C__HASH_TABLE_LEN ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, "Pre HT search SC failed") \ -} - -#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) \ -if ( ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ - ( (cache_ptr)->index_len < 1 ) || \ - ( (entry_ptr) == NULL ) || \ - ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) || \ - ( H5F_addr_ne((entry_ptr)->addr, (Addr)) ) || \ - ( (entry_ptr)->size <= 0 ) || \ - ( ((cache_ptr)->index)[k] == NULL ) || \ - ( ( ((cache_ptr)->index)[k] != (entry_ptr) ) && \ - ( (entry_ptr)->ht_prev == NULL ) ) || \ - ( ( ((cache_ptr)->index)[k] == (entry_ptr) ) && \ - ( (entry_ptr)->ht_prev != NULL ) ) || \ - ( ( (entry_ptr)->ht_prev != NULL ) && \ - ( (entry_ptr)->ht_prev->ht_next != (entry_ptr) ) ) || \ - ( ( (entry_ptr)->ht_next != NULL ) && \ - ( (entry_ptr)->ht_next->ht_prev != (entry_ptr) ) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ - "Post successful HT search SC failed") \ -} - -#define H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) \ -if ( ( (cache_ptr) == NULL ) || \ - ( ((cache_ptr)->index)[k] != (entry_ptr) ) || \ - ( (entry_ptr)->ht_prev != NULL ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ - "Post HT shift to front SC failed") \ -} - -#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr, was_clean) \ -if ( ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->index_len <= 0 ) || \ - ( (cache_ptr)->index_size <= 0 ) || \ - ( (new_size) <= 0 ) || \ - ( (old_size) > (cache_ptr)->index_size ) || \ - ( (new_size) <= 0 ) || \ - ( ( (cache_ptr)->index_len == 1 ) && \ - ( (cache_ptr)->index_size != (old_size) ) ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + \ - (cache_ptr)->dirty_index_size) ) || \ - ( (entry_ptr == NULL) ) || \ - ( ( !( was_clean ) || \ - ( (cache_ptr)->clean_index_size < (old_size) ) ) && \ - ( ( (was_clean) ) || \ - ( (cache_ptr)->dirty_index_size < (old_size) ) ) ) \ - ( (entry_ptr) == NULL ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Pre HT entry size change SC failed") \ -} - -#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr) \ -if ( ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->index_len <= 0 ) || \ - ( (cache_ptr)->index_size <= 0 ) || \ - ( (new_size) > (cache_ptr)->index_size ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + \ - (cache_ptr)->dirty_index_size) ) || \ - ( ( !((entry_ptr)->is_dirty ) || \ - ( (cache_ptr)->dirty_index_size < (new_size) ) ) && \ - ( ( ((entry_ptr)->is_dirty) ) || \ - ( (cache_ptr)->clean_index_size < (new_size) ) ) ) \ - ( ( (cache_ptr)->index_len == 1 ) && \ - ( (cache_ptr)->index_size != (new_size) ) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Post HT entry size change SC failed") \ -} - -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ -if ( \ - ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ - ( (cache_ptr)->index_len <= 0 ) || \ - ( (entry_ptr) == NULL ) || \ - ( (entry_ptr)->is_dirty != FALSE ) || \ - ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ - ( (cache_ptr)->dirty_index_size < (entry_ptr)->size ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Pre HT update for entry clean SC failed") \ -} - -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ -if ( \ - ( (cache_ptr) == NULL ) || \ - ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ - ( (cache_ptr)->index_len <= 0 ) || \ - ( (entry_ptr) == NULL ) || \ - ( (entry_ptr)->is_dirty != TRUE ) || \ - ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ - ( (cache_ptr)->clean_index_size < (entry_ptr)->size ) || \ - ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Pre HT update for entry dirty SC failed") \ -} - -#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ -if ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Post HT update for entry clean SC failed") \ -} - -#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ -if ( (cache_ptr)->index_size != \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Post HT update for entry dirty SC failed") \ -} - -#else /* H5C_DO_SANITY_CHECKS */ - -#define H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) -#define H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr) -#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) -#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) -#define H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) -#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr, was_clean) -#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr) -#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) -#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) - -#endif /* H5C_DO_SANITY_CHECKS */ - - -#define H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, fail_val) \ -{ \ - int k; \ - H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ - k = H5C__HASH_FCN((entry_ptr)->addr); \ - if ( ((cache_ptr)->index)[k] == NULL ) \ - { \ - ((cache_ptr)->index)[k] = (entry_ptr); \ - } \ - else \ - { \ - (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ - (entry_ptr)->ht_next->ht_prev = (entry_ptr); \ - ((cache_ptr)->index)[k] = (entry_ptr); \ - } \ - (cache_ptr)->index_len++; \ - (cache_ptr)->index_size += (entry_ptr)->size; \ - if ( (entry_ptr)->is_dirty ) { \ - (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ - } else { \ - (cache_ptr)->clean_index_size += (entry_ptr)->size; \ - } \ - H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ -} - -#define H5C__DELETE_FROM_INDEX(cache_ptr, entry_ptr) \ -{ \ - int k; \ - H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr) \ - k = H5C__HASH_FCN((entry_ptr)->addr); \ - if ( (entry_ptr)->ht_next ) \ - { \ - (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ - } \ - if ( (entry_ptr)->ht_prev ) \ - { \ - (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ - } \ - if ( ((cache_ptr)->index)[k] == (entry_ptr) ) \ - { \ - ((cache_ptr)->index)[k] = (entry_ptr)->ht_next; \ - } \ - (entry_ptr)->ht_next = NULL; \ - (entry_ptr)->ht_prev = NULL; \ - (cache_ptr)->index_len--; \ - (cache_ptr)->index_size -= (entry_ptr)->size; \ - if ( (entry_ptr)->is_dirty ) { \ - (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ - } else { \ - (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ - } \ - H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ -} - -#define H5C__SEARCH_INDEX(cache_ptr, Addr, entry_ptr, fail_val) \ -{ \ - int k; \ - int depth = 0; \ - H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \ - k = H5C__HASH_FCN(Addr); \ - entry_ptr = ((cache_ptr)->index)[k]; \ - while ( ( entry_ptr ) && ( H5F_addr_ne(Addr, (entry_ptr)->addr) ) ) \ - { \ - (entry_ptr) = (entry_ptr)->ht_next; \ - (depth)++; \ - } \ - if ( entry_ptr ) \ - { \ - H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) \ - if ( entry_ptr != ((cache_ptr)->index)[k] ) \ - { \ - if ( (entry_ptr)->ht_next ) \ - { \ - (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ - } \ - HDassert( (entry_ptr)->ht_prev != NULL ); \ - (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ - ((cache_ptr)->index)[k]->ht_prev = (entry_ptr); \ - (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ - (entry_ptr)->ht_prev = NULL; \ - ((cache_ptr)->index)[k] = (entry_ptr); \ - H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) \ - } \ - } \ - H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, (entry_ptr != NULL), depth) \ -} - -#define H5C__SEARCH_INDEX_NO_STATS(cache_ptr, Addr, entry_ptr, fail_val) \ -{ \ - int k; \ - int depth = 0; \ - H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \ - k = H5C__HASH_FCN(Addr); \ - entry_ptr = ((cache_ptr)->index)[k]; \ - while ( ( entry_ptr ) && ( H5F_addr_ne(Addr, (entry_ptr)->addr) ) ) \ - { \ - (entry_ptr) = (entry_ptr)->ht_next; \ - (depth)++; \ - } \ - if ( entry_ptr ) \ - { \ - H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) \ - if ( entry_ptr != ((cache_ptr)->index)[k] ) \ - { \ - if ( (entry_ptr)->ht_next ) \ - { \ - (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ - } \ - HDassert( (entry_ptr)->ht_prev != NULL ); \ - (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ - ((cache_ptr)->index)[k]->ht_prev = (entry_ptr); \ - (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ - (entry_ptr)->ht_prev = NULL; \ - ((cache_ptr)->index)[k] = (entry_ptr); \ - H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) \ - } \ - } \ -} - -#define H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN(cache_ptr, entry_ptr) \ -{ \ - H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \ - (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ - (cache_ptr)->clean_index_size += (entry_ptr)->size; \ - H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \ -} - -#define H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr) \ -{ \ - H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \ - (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ - (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ - H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \ -} - -#define H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size, \ - entry_ptr, was_clean) \ -{ \ - H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ - entry_ptr, was_clean) \ - (cache_ptr)->index_size -= (old_size); \ - (cache_ptr)->index_size += (new_size); \ - if ( was_clean ) { \ - (cache_ptr)->clean_index_size -= (old_size); \ - } else { \ - (cache_ptr)->dirty_index_size -= (old_size); \ - } \ - if ( (entry_ptr)->is_dirty ) { \ - (cache_ptr)->dirty_index_size += (new_size); \ - } else { \ - (cache_ptr)->clean_index_size += (new_size); \ - } \ - H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, entry_ptr) \ -} - - -/************************************************************************** - * - * Skip list insertion and deletion macros: - * - * These used to be functions, but I converted them to macros to avoid some - * function call overhead. - * - **************************************************************************/ - -/*------------------------------------------------------------------------- - * - * Macro: H5C__INSERT_ENTRY_IN_SLIST - * - * Purpose: Insert the specified instance of H5C_cache_entry_t into - * the skip list in the specified instance of H5C_t. Update - * the associated length and size fields. - * - * Return: N/A - * - * Programmer: John Mainzer, 5/10/04 - * - * Modifications: - * - * JRM -- 7/21/04 - * Updated function to set the in_tree flag when inserting - * an entry into the tree. Also modified the function to - * update the tree size and len fields instead of the similar - * index fields. - * - * All of this is part of the modifications to support the - * hash table. - * - * JRM -- 7/27/04 - * Converted the function H5C_insert_entry_in_tree() into - * the macro H5C__INSERT_ENTRY_IN_TREE in the hopes of - * wringing a little more speed out of the cache. - * - * Note that we don't bother to check if the entry is already - * in the tree -- if it is, H5SL_insert() will fail. - * - * QAK -- 11/27/04 - * Switched over to using skip list routines. - * - * JRM -- 6/27/06 - * Added fail_val parameter. - * - * JRM -- 8/25/06 - * Added the H5C_DO_SANITY_CHECKS version of the macro. - * - * This version maintains the slist_len_increase and - * slist_size_increase fields that are used in sanity - * checks in the flush routines. - * - * All this is needed as the fractal heap needs to be - * able to dirty, resize and/or rename entries during the - * flush. - * - *------------------------------------------------------------------------- - */ - -#if H5C_DO_SANITY_CHECKS - -#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( (entry_ptr)->size > 0 ); \ - HDassert( H5F_addr_defined((entry_ptr)->addr) ); \ - HDassert( !((entry_ptr)->in_slist) ); \ - \ - if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &(entry_ptr)->addr) \ - < 0 ) \ - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), \ - "Can't insert entry in skip list") \ - \ - (entry_ptr)->in_slist = TRUE; \ - (cache_ptr)->slist_len++; \ - (cache_ptr)->slist_size += (entry_ptr)->size; \ - (cache_ptr)->slist_len_increase++; \ - (cache_ptr)->slist_size_increase += (entry_ptr)->size; \ - \ - HDassert( (cache_ptr)->slist_len > 0 ); \ - HDassert( (cache_ptr)->slist_size > 0 ); \ - \ -} /* H5C__INSERT_ENTRY_IN_SLIST */ - -#else /* H5C_DO_SANITY_CHECKS */ - -#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( (entry_ptr)->size > 0 ); \ - HDassert( H5F_addr_defined((entry_ptr)->addr) ); \ - HDassert( !((entry_ptr)->in_slist) ); \ - \ - if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &(entry_ptr)->addr) \ - < 0 ) \ - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), \ - "Can't insert entry in skip list") \ - \ - (entry_ptr)->in_slist = TRUE; \ - (cache_ptr)->slist_len++; \ - (cache_ptr)->slist_size += (entry_ptr)->size; \ - \ - HDassert( (cache_ptr)->slist_len > 0 ); \ - HDassert( (cache_ptr)->slist_size > 0 ); \ - \ -} /* H5C__INSERT_ENTRY_IN_SLIST */ - -#endif /* H5C_DO_SANITY_CHECKS */ - - -/*------------------------------------------------------------------------- - * - * Function: H5C__REMOVE_ENTRY_FROM_SLIST - * - * Purpose: Remove the specified instance of H5C_cache_entry_t from the - * index skip list in the specified instance of H5C_t. Update - * the associated length and size fields. - * - * Return: N/A - * - * Programmer: John Mainzer, 5/10/04 - * - * Modifications: - * - * JRM -- 7/21/04 - * Updated function for the addition of the hash table. - * - * JRM - 7/27/04 - * Converted from the function H5C_remove_entry_from_tree() - * to the macro H5C__REMOVE_ENTRY_FROM_TREE in the hopes of - * wringing a little more performance out of the cache. - * - * QAK -- 11/27/04 - * Switched over to using skip list routines. - * - * JRM -- 3/28/07 - * Updated sanity checks for the new is_read_only and - * ro_ref_count fields in H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - HDassert( (entry_ptr)->in_slist ); \ - HDassert( (cache_ptr)->slist_ptr ); \ - \ - if ( H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \ - != (entry_ptr) ) \ - \ - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ - "Can't delete entry from skip list.") \ - \ - HDassert( (cache_ptr)->slist_len > 0 ); \ - (cache_ptr)->slist_len--; \ - HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \ - (cache_ptr)->slist_size -= (entry_ptr)->size; \ - (entry_ptr)->in_slist = FALSE; \ -} /* H5C__REMOVE_ENTRY_FROM_SLIST */ - - -/*------------------------------------------------------------------------- - * - * Function: H5C__UPDATE_SLIST_FOR_SIZE_CHANGE - * - * Purpose: Update cache_ptr->slist_size for a change in the size of - * and entry in the slist. - * - * Return: N/A - * - * Programmer: John Mainzer, 9/07/05 - * - * Modifications: - * - * JRM -- 8/27/06 - * Added the H5C_DO_SANITY_CHECKS version of the macro. - * - * This version maintains the slist_size_increase field - * that are used in sanity checks in the flush routines. - * - * All this is needed as the fractal heap needs to be - * able to dirty, resize and/or rename entries during the - * flush. - * - *------------------------------------------------------------------------- - */ - -#if H5C_DO_SANITY_CHECKS - -#define H5C__UPDATE_SLIST_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (old_size) > 0 ); \ - HDassert( (new_size) > 0 ); \ - HDassert( (old_size) <= (cache_ptr)->slist_size ); \ - HDassert( (cache_ptr)->slist_len > 0 ); \ - HDassert( ((cache_ptr)->slist_len > 1) || \ - ( (cache_ptr)->slist_size == (old_size) ) ); \ - \ - (cache_ptr)->slist_size -= (old_size); \ - (cache_ptr)->slist_size += (new_size); \ - \ - (cache_ptr)->slist_size_increase -= (int64_t)(old_size); \ - (cache_ptr)->slist_size_increase += (int64_t)(new_size); \ - \ - HDassert( (new_size) <= (cache_ptr)->slist_size ); \ - HDassert( ( (cache_ptr)->slist_len > 1 ) || \ - ( (cache_ptr)->slist_size == (new_size) ) ); \ -} /* H5C__REMOVE_ENTRY_FROM_SLIST */ - -#else /* H5C_DO_SANITY_CHECKS */ - -#define H5C__UPDATE_SLIST_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (old_size) > 0 ); \ - HDassert( (new_size) > 0 ); \ - HDassert( (old_size) <= (cache_ptr)->slist_size ); \ - HDassert( (cache_ptr)->slist_len > 0 ); \ - HDassert( ((cache_ptr)->slist_len > 1) || \ - ( (cache_ptr)->slist_size == (old_size) ) ); \ - \ - (cache_ptr)->slist_size -= (old_size); \ - (cache_ptr)->slist_size += (new_size); \ - \ - HDassert( (new_size) <= (cache_ptr)->slist_size ); \ - HDassert( ( (cache_ptr)->slist_len > 1 ) || \ - ( (cache_ptr)->slist_size == (new_size) ) ); \ -} /* H5C__REMOVE_ENTRY_FROM_SLIST */ - -#endif /* H5C_DO_SANITY_CHECKS */ - - -/************************************************************************** - * - * Replacement policy update macros: - * - * These used to be functions, but I converted them to macros to avoid some - * function call overhead. - * - **************************************************************************/ - -/*------------------------------------------------------------------------- - * - * Macro: H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS - * - * Purpose: For efficiency, we sometimes change the order of flushes -- - * but doing so can confuse the replacement policy. This - * macro exists to allow us to specify an entry as the - * most recently touched so we can repair any such - * confusion. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the macro - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 10/13/05 - * - * Modifications: - * - * JRM -- 3/20/06 - * Modified macro to ignore pinned entries. Pinned entries - * do not appear in the data structures maintained by the - * replacement policy code, and thus this macro has nothing - * to do if called for such an entry. - * - * JRM -- 3/28/07 - * Added sanity checks using the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list, and re-insert it at the head.\ - */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Use the dirty flag to infer whether the entry is on the clean or \ - * dirty LRU list, and remove it. Then insert it at the head of \ - * the same LRU list. \ - * \ - * At least initially, all entries should be clean. That may \ - * change, so we may as well deal with both cases now. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - /* End modified LRU specific code. */ \ - } \ -} /* H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list, and re-insert it at the head \ - */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - } \ -} /* H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_EVICTION - * - * Purpose: Update the replacement policy data structures for an - * eviction of the specified cache entry. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the function - * should switch on the current policy and act accordingly. - * - * Return: Non-negative on success/Negative on failure. - * - * Programmer: John Mainzer, 5/10/04 - * - * Modifications: - * - * JRM - 7/27/04 - * Converted the function H5C_update_rp_for_eviction() to the - * macro H5C__UPDATE_RP_FOR_EVICTION in an effort to squeeze - * a bit more performance out of the cache. - * - * At least for the first cut, I am leaving the comments and - * white space in the macro. If they cause dificulties with - * the pre-processor, I'll have to remove them. - * - * JRM - 7/28/04 - * Split macro into two version, one supporting the clean and - * dirty LRU lists, and the other not. Yet another attempt - * at optimization. - * - * JRM - 3/20/06 - * Pinned entries can't be evicted, so this entry should never - * be called on a pinned entry. Added assert to verify this. - * - * JRM -- 3/28/07 - * Added sanity checks for the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( !((entry_ptr)->is_pinned) ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list. */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* If the entry is clean when it is evicted, it should be on the \ - * clean LRU list, if it was dirty, it should be on the dirty LRU list. \ - * Remove it from the appropriate list according to the value of the \ - * dirty flag. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ -} /* H5C__UPDATE_RP_FOR_EVICTION */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( !((entry_ptr)->is_pinned) ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list. */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ -} /* H5C__UPDATE_RP_FOR_EVICTION */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_FLUSH - * - * Purpose: Update the replacement policy data structures for a flush - * of the specified cache entry. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the function - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 5/6/04 - * - * Modifications: - * - * JRM - 7/27/04 - * Converted the function H5C_update_rp_for_flush() to the - * macro H5C__UPDATE_RP_FOR_FLUSH in an effort to squeeze - * a bit more performance out of the cache. - * - * At least for the first cut, I am leaving the comments and - * white space in the macro. If they cause dificulties with - * pre-processor, I'll have to remove them. - * - * JRM - 7/28/04 - * Split macro into two versions, one supporting the clean and - * dirty LRU lists, and the other not. Yet another attempt - * at optimization. - * - * JRM - 3/20/06 - * While pinned entries can be flushed, they don't reside in - * the replacement policy data structures when unprotected. - * Thus I modified this macro to do nothing if the entry is - * pinned. - * - * JRM - 3/28/07 - * Added sanity checks based on the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_FLUSH(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list, and re-insert it at the \ - * head. \ - */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* since the entry is being flushed or cleared, one would think \ - * that it must be dirty -- but that need not be the case. Use the \ - * dirty flag to infer whether the entry is on the clean or dirty \ - * LRU list, and remove it. Then insert it at the head of the \ - * clean LRU list. \ - * \ - * The function presumes that a dirty entry will be either cleared \ - * or flushed shortly, so it is OK if we put a dirty entry on the \ - * clean LRU list. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - } \ -} /* H5C__UPDATE_RP_FOR_FLUSH */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_FLUSH(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list, and re-insert it at the \ - * head. \ - */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - } \ -} /* H5C__UPDATE_RP_FOR_FLUSH */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_INSERTION - * - * Purpose: Update the replacement policy data structures for an - * insertion of the specified cache entry. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the function - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 5/17/04 - * - * Modifications: - * - * JRM - 7/27/04 - * Converted the function H5C_update_rp_for_insertion() to the - * macro H5C__UPDATE_RP_FOR_INSERTION in an effort to squeeze - * a bit more performance out of the cache. - * - * At least for the first cut, I am leaving the comments and - * white space in the macro. If they cause dificulties with - * pre-processor, I'll have to remove them. - * - * JRM - 7/28/04 - * Split macro into two version, one supporting the clean and - * dirty LRU lists, and the other not. Yet another attempt - * at optimization. - * - * JRM - 3/10/06 - * This macro should never be called on a pinned entry. - * Inserted an assert to verify this. - * - * JRM - 8/9/06 - * Not any more. We must now allow insertion of pinned - * entries. Updated macro to support this. - * - * JRM - 3/28/07 - * Added sanity checks using the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* insert the entry at the head of the LRU list. */ \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* insert the entry at the head of the clean or dirty LRU list as \ - * appropriate. \ - */ \ - \ - if ( entry_ptr->is_dirty ) { \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - } else { \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - /* End modified LRU specific code. */ \ - } \ -} - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* insert the entry at the head of the LRU list. */ \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - } \ -} - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_PROTECT - * - * Purpose: Update the replacement policy data structures for a - * protect of the specified cache entry. - * - * To do this, unlink the specified entry from any data - * structures used by the replacement policy, and add the - * entry to the protected list. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the function - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 5/17/04 - * - * Modifications: - * - * JRM - 7/27/04 - * Converted the function H5C_update_rp_for_protect() to the - * macro H5C__UPDATE_RP_FOR_PROTECT in an effort to squeeze - * a bit more performance out of the cache. - * - * At least for the first cut, I am leaving the comments and - * white space in the macro. If they cause dificulties with - * pre-processor, I'll have to remove them. - * - * JRM - 7/28/04 - * Split macro into two version, one supporting the clean and - * dirty LRU lists, and the other not. Yet another attempt - * at optimization. - * - * JRM - 3/17/06 - * Modified macro to attempt to remove pinned entriese from - * the pinned entry list instead of from the data structures - * maintained by the replacement policy. - * - * JRM - 3/28/07 - * Added sanity checks based on the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_PROTECT(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - HDassert( (cache_ptr)->pel_len >= 0 ); \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list. */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Similarly, remove the entry from the clean or dirty LRU list \ - * as appropriate. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - \ - } else { \ - \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - /* End modified LRU specific code. */ \ - } \ - \ - /* Regardless of the replacement policy, or whether the entry is \ - * pinned, now add the entry to the protected list. \ - */ \ - \ - H5C__DLL_APPEND((entry_ptr), (cache_ptr)->pl_head_ptr, \ - (cache_ptr)->pl_tail_ptr, \ - (cache_ptr)->pl_len, \ - (cache_ptr)->pl_size, (fail_val)) \ -} /* H5C__UPDATE_RP_FOR_PROTECT */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_PROTECT(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - HDassert( (cache_ptr)->pel_len >= 0 ); \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list. */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - } \ - \ - /* Regardless of the replacement policy, or whether the entry is \ - * pinned, now add the entry to the protected list. \ - */ \ - \ - H5C__DLL_APPEND((entry_ptr), (cache_ptr)->pl_head_ptr, \ - (cache_ptr)->pl_tail_ptr, \ - (cache_ptr)->pl_len, \ - (cache_ptr)->pl_size, (fail_val)) \ -} /* H5C__UPDATE_RP_FOR_PROTECT */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_RENAME - * - * Purpose: Update the replacement policy data structures for a - * rename of the specified cache entry. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the function - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 5/17/04 - * - * Modifications: - * - * JRM - 7/27/04 - * Converted the function H5C_update_rp_for_rename() to the - * macro H5C__UPDATE_RP_FOR_RENAME in an effort to squeeze - * a bit more performance out of the cache. - * - * At least for the first cut, I am leaving the comments and - * white space in the macro. If they cause dificulties with - * pre-processor, I'll have to remove them. - * - * JRM - 7/28/04 - * Split macro into two version, one supporting the clean and - * dirty LRU lists, and the other not. Yet another attempt - * at optimization. - * - * JRM - 6/23/05 - * Added the was_dirty parameter. It is possible that - * the entry was clean when it was renamed -- if so it - * it is in the clean LRU regardless of the current - * value of the is_dirty field. - * - * At present, all renamed entries are forced to be - * dirty. This macro is a bit more general that that, - * to allow it to function correctly should that policy - * be relaxed in the future. - * - * JRM - 3/17/06 - * Modified macro to do nothing if the entry is pinned. - * In this case, the entry is on the pinned entry list, not - * in the replacement policy data structures, so there is - * nothing to be done. - * - * JRM - 3/28/07 - * Added sanity checks using the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_RENAME(cache_ptr, entry_ptr, was_dirty, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list, and re-insert it at the head. \ - */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* remove the entry from either the clean or dirty LUR list as \ - * indicated by the was_dirty parameter \ - */ \ - if ( was_dirty ) { \ - \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - \ - } else { \ - \ - H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - /* insert the entry at the head of either the clean or dirty LRU \ - * list as appropriate. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - \ - } else { \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - /* End modified LRU specific code. */ \ - } \ -} /* H5C__UPDATE_RP_FOR_RENAME */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_RENAME(cache_ptr, entry_ptr, was_dirty, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - if ( ! ((entry_ptr)->is_pinned) ) { \ - \ - /* modified LRU specific code */ \ - \ - /* remove the entry from the LRU list, and re-insert it at the head. \ - */ \ - \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - } \ -} /* H5C__UPDATE_RP_FOR_RENAME */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_SIZE_CHANGE - * - * Purpose: Update the replacement policy data structures for a - * size change of the specified cache entry. - * - * To do this, determine if the entry is pinned. If it is, - * update the size of the pinned entry list. - * - * If it isn't pinned, the entry must handled by the - * replacement policy. Update the appropriate replacement - * policy data structures. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the function - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 8/23/06 - * - * Modifications: - * - * JRM -- 3/28/07 - * Added sanity checks based on the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - HDassert( new_size > 0 ); \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, \ - (entry_ptr)->size, \ - (new_size)); \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* Update the size of the LRU list */ \ - \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, \ - (entry_ptr)->size, \ - (new_size)); \ - \ - /* Similarly, update the size of the clean or dirty LRU list as \ - * appropriate. At present, the entry must be clean, but that \ - * could change. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, \ - (entry_ptr)->size, \ - (new_size)); \ - \ - } else { \ - \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, \ - (entry_ptr)->size, \ - (new_size)); \ - } \ - \ - /* End modified LRU specific code. */ \ - } \ - \ -} /* H5C__UPDATE_RP_FOR_SIZE_CHANGE */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->size > 0 ); \ - HDassert( new_size > 0 ); \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, \ - (entry_ptr)->size, \ - (new_size)); \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* Update the size of the LRU list */ \ - \ - H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, \ - (entry_ptr)->size, \ - (new_size)); \ - \ - /* End modified LRU specific code. */ \ - } \ - \ -} /* H5C__UPDATE_RP_FOR_SIZE_CHANGE */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_UNPIN - * - * Purpose: Update the replacement policy data structures for an - * unpin of the specified cache entry. - * - * To do this, unlink the specified entry from the protected - * entry list, and re-insert it in the data structures used - * by the current replacement policy. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the macro - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 3/22/06 - * - * Modifications: - * - * JRM -- 3/28/07 - * Added sanity checks based on the new is_read_only and - * ro_ref_count fields of struct H5C_cache_entry_t. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->is_pinned); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - /* Regardless of the replacement policy, remove the entry from the \ - * pinned entry list. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - HDassert( (cache_ptr)->pel_len >= 0 ); \ - \ - /* modified LRU specific code */ \ - \ - /* insert the entry at the head of the LRU list. */ \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Similarly, insert the entry at the head of either the clean or \ - * dirty LRU list as appropriate. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - \ - } else { \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - /* End modified LRU specific code. */ \ - \ -} /* H5C__UPDATE_RP_FOR_UNPIN */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( !((entry_ptr)->is_protected) ); \ - HDassert( !((entry_ptr)->is_read_only) ); \ - HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ - HDassert( (entry_ptr)->is_pinned); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - /* Regardless of the replacement policy, remove the entry from the \ - * pinned entry list. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - HDassert( (cache_ptr)->pel_len >= 0 ); \ - \ - /* modified LRU specific code */ \ - \ - /* insert the entry at the head of the LRU list. */ \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - \ -} /* H5C__UPDATE_RP_FOR_UNPIN */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - -/*------------------------------------------------------------------------- - * - * Macro: H5C__UPDATE_RP_FOR_UNPROTECT - * - * Purpose: Update the replacement policy data structures for an - * unprotect of the specified cache entry. - * - * To do this, unlink the specified entry from the protected - * list, and re-insert it in the data structures used by the - * current replacement policy. - * - * At present, we only support the modified LRU policy, so - * this function deals with that case unconditionally. If - * we ever support other replacement policies, the function - * should switch on the current policy and act accordingly. - * - * Return: N/A - * - * Programmer: John Mainzer, 5/19/04 - * - * Modifications: - * - * JRM - 7/27/04 - * Converted the function H5C_update_rp_for_unprotect() to - * the macro H5C__UPDATE_RP_FOR_UNPROTECT in an effort to - * squeeze a bit more performance out of the cache. - * - * At least for the first cut, I am leaving the comments and - * white space in the macro. If they cause dificulties with - * pre-processor, I'll have to remove them. - * - * JRM - 7/28/04 - * Split macro into two version, one supporting the clean and - * dirty LRU lists, and the other not. Yet another attempt - * at optimization. - * - * JRM - 3/17/06 - * Modified macro to put pinned entries on the pinned entry - * list instead of inserting them in the data structures - * maintained by the replacement policy. - * - *------------------------------------------------------------------------- - */ - -#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS - -#define H5C__UPDATE_RP_FOR_UNPROTECT(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( (entry_ptr)->is_protected); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - /* Regardless of the replacement policy, remove the entry from the \ - * protected list. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pl_head_ptr, \ - (cache_ptr)->pl_tail_ptr, (cache_ptr)->pl_len, \ - (cache_ptr)->pl_size, (fail_val)) \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* insert the entry at the head of the LRU list. */ \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* Similarly, insert the entry at the head of either the clean or \ - * dirty LRU list as appropriate. \ - */ \ - \ - if ( (entry_ptr)->is_dirty ) { \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ - (cache_ptr)->dLRU_tail_ptr, \ - (cache_ptr)->dLRU_list_len, \ - (cache_ptr)->dLRU_list_size, (fail_val)) \ - \ - } else { \ - \ - H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ - (cache_ptr)->cLRU_tail_ptr, \ - (cache_ptr)->cLRU_list_len, \ - (cache_ptr)->cLRU_list_size, (fail_val)) \ - } \ - \ - /* End modified LRU specific code. */ \ - } \ - \ -} /* H5C__UPDATE_RP_FOR_UNPROTECT */ - -#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - -#define H5C__UPDATE_RP_FOR_UNPROTECT(cache_ptr, entry_ptr, fail_val) \ -{ \ - HDassert( (cache_ptr) ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (entry_ptr) ); \ - HDassert( (entry_ptr)->is_protected); \ - HDassert( (entry_ptr)->size > 0 ); \ - \ - /* Regardless of the replacement policy, remove the entry from the \ - * protected list. \ - */ \ - H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pl_head_ptr, \ - (cache_ptr)->pl_tail_ptr, (cache_ptr)->pl_len, \ - (cache_ptr)->pl_size, (fail_val)) \ - \ - if ( (entry_ptr)->is_pinned ) { \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ - (cache_ptr)->pel_tail_ptr, \ - (cache_ptr)->pel_len, \ - (cache_ptr)->pel_size, (fail_val)) \ - \ - } else { \ - \ - /* modified LRU specific code */ \ - \ - /* insert the entry at the head of the LRU list. */ \ - \ - H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ - (cache_ptr)->LRU_tail_ptr, \ - (cache_ptr)->LRU_list_len, \ - (cache_ptr)->LRU_list_size, (fail_val)) \ - \ - /* End modified LRU specific code. */ \ - } \ -} /* H5C__UPDATE_RP_FOR_UNPROTECT */ - -#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ - - /* * Private file-scope variables. */ @@ -3005,7 +424,7 @@ done: * * JRM -- 11/5/08 * Added initialization for the new clean_index_size and - * dirty_index_size fields of H5C_t. + * dirty_index_size fields of H5C_t. * *------------------------------------------------------------------------- */ @@ -4649,7 +2068,7 @@ H5C_get_trace_file_ptr(const H5C_t *cache_ptr, FILE **trace_file_ptr_ptr) * Purpose: Get the trace_file_ptr field from the cache, via an entry. * * This field will either be NULL (which indicates that trace - * file logging is turned off), or contain a pointer to the + * file logging is turned off), or contain a pointer to the * open file to which trace file data is to be written. * * Return: Non-negative on success/Negative on failure @@ -4759,26 +2178,26 @@ H5C_get_trace_file_ptr_from_entry(const H5C_cache_entry_t *entry_ptr, * field. * * JRM -- 11/13/08 - * Moved test to see if we already have an entry with the - * specified address in the cache. This was necessary as + * Moved test to see if we already have an entry with the + * specified address in the cache. This was necessary as * we used to modify some fields in the entry to be inserted * priort to this test, which got the cache confused if the * insertion failed because the entry was already present. * * Also revised the function to call H5C_make_space_in_cache() - * if the min_clean_size is not met at present, not just if - * there is insufficient space in the cache for the new + * if the min_clean_size is not met at present, not just if + * there is insufficient space in the cache for the new * entry. * * The purpose of this modification is to avoid "metadata - * blizzards" in the write only case. In such instances, + * blizzards" in the write only case. In such instances, * the cache was allowed to fill with dirty metadata. When * we finally needed to evict an entry to make space, we had * to flush out a whole cache full of metadata -- which has - * interesting performance effects. We hope to avoid (or - * perhaps more accurately hide) this effect by maintaining + * interesting performance effects. We hope to avoid (or + * perhaps more accurately hide) this effect by maintaining * the min_clean_size, which should force us to start flushing - * entries long before we actually have to evict something + * entries long before we actually have to evict something * to make space. * *------------------------------------------------------------------------- @@ -4938,17 +2357,17 @@ H5C_insert_entry(H5F_t * f, } - if ( ( cache_ptr->evictions_enabled ) + if ( ( cache_ptr->evictions_enabled ) && ( ( (cache_ptr->index_size + entry_ptr->size) > - cache_ptr->max_cache_size - ) + cache_ptr->max_cache_size + ) || ( ( ( empty_space + cache_ptr->clean_index_size ) < cache_ptr->min_clean_size ) - ) - ) + ) + ) ) { size_t space_needed; @@ -5510,9 +2929,9 @@ done: * 5/15/06 * * JRM -- 11/5/08 - * Added call to H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY() to + * Added call to H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY() to * update the new clean_index_size and dirty_index_size - * fields of H5C_t in the case that the entry was clean + * fields of H5C_t in the case that the entry was clean * prior to this call, and is pinned and not protected. * *------------------------------------------------------------------------- @@ -5549,7 +2968,7 @@ H5C_mark_pinned_or_protected_entry_dirty(void *thing) entry_ptr->is_dirty = TRUE; if ( was_pinned_unprotected_and_clean ) { - + H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr); } @@ -5611,7 +3030,7 @@ done: * * JRM -- 11/5/08 * On review this function looks like no change is needed to - * support the new clean_index_size and dirty_index_size + * support the new clean_index_size and dirty_index_size * fields of H5C_t. * *------------------------------------------------------------------------- @@ -6068,14 +3487,14 @@ done: * enough space for and entry that has just been loaded. * * The purpose of this modification is to avoid "metadata - * blizzards" in the write only case. In such instances, + * blizzards" in the write only case. In such instances, * the cache was allowed to fill with dirty metadata. When * we finally needed to evict an entry to make space, we had * to flush out a whole cache full of metadata -- which has - * interesting performance effects. We hope to avoid (or - * perhaps more accurately hide) this effect by maintaining + * interesting performance effects. We hope to avoid (or + * perhaps more accurately hide) this effect by maintaining * the min_clean_size, which should force us to start flushing - * entries long before we actually have to evict something + * entries long before we actually have to evict something * to make space. * *------------------------------------------------------------------------- @@ -6189,17 +3608,17 @@ H5C_protect(H5F_t * f, * regardless if the min_free_space requirement is not met. */ - if ( ( cache_ptr->evictions_enabled ) + if ( ( cache_ptr->evictions_enabled ) && ( ( (cache_ptr->index_size + entry_ptr->size) > - cache_ptr->max_cache_size - ) + cache_ptr->max_cache_size + ) || ( ( ( empty_space + cache_ptr->clean_index_size ) < cache_ptr->min_clean_size ) - ) - ) + ) + ) ) { size_t space_needed; @@ -6207,7 +3626,7 @@ H5C_protect(H5F_t * f, if ( empty_space <= entry_ptr->size ) { cache_ptr->cache_full = TRUE; - + } if ( cache_ptr->check_write_permitted != NULL ) { @@ -7028,12 +4447,12 @@ done: * read_protects, and max_read_protects fields. * * JRM -- 11/13/08 - * Added code displaying the max_clean_index_size and + * Added code displaying the max_clean_index_size and * max_dirty_index_size. * * MAM -- 01/06/09 * Added code displaying the calls_to_msic, - * total_entries_skipped_in_msic, total_entries_scanned_in_msic, + * total_entries_skipped_in_msic, total_entries_scanned_in_msic, * and max_entries_skipped_in_msic fields. * *------------------------------------------------------------------------- @@ -7314,8 +4733,8 @@ H5C_stats(H5C_t * cache_ptr, (long long)(cache_ptr->calls_to_msic)); if (cache_ptr->calls_to_msic > 0) { - average_entries_skipped_per_calls_to_msic = - (((double)(cache_ptr->total_entries_skipped_in_msic)) / + average_entries_skipped_per_calls_to_msic = + (((double)(cache_ptr->total_entries_skipped_in_msic)) / ((double)(cache_ptr->calls_to_msic))); } @@ -7325,8 +4744,8 @@ H5C_stats(H5C_t * cache_ptr, (long)(cache_ptr->max_entries_skipped_in_msic)); if (cache_ptr->calls_to_msic > 0) { - average_entries_scanned_per_calls_to_msic = - (((double)(cache_ptr->total_entries_scanned_in_msic)) / + average_entries_scanned_per_calls_to_msic = + (((double)(cache_ptr->total_entries_scanned_in_msic)) / ((double)(cache_ptr->calls_to_msic))); } @@ -7341,7 +4760,7 @@ H5C_stats(H5C_t * cache_ptr, HDfprintf(stdout, "%s MSIC: Scanned to satisfy min_clean = %lld\n", cache_ptr->prefix, - (long long)(cache_ptr->total_entries_scanned_in_msic - + (long long)(cache_ptr->total_entries_scanned_in_msic - cache_ptr->entries_scanned_to_make_space)); #if H5C_COLLECT_CACHE_ENTRY_STATS @@ -7810,14 +5229,14 @@ done: * cache" concept, by adding the 'take_ownership' flag. * * JRM -- 11/5/08 - * Added code to update the clean_index_size and - * dirty_index_size fields of H5C_t in cases where the - * the entry was clean on protect, was marked dirty on - * unprotect, and did not change its size. Do this via + * Added code to update the clean_index_size and + * dirty_index_size fields of H5C_t in cases where the + * the entry was clean on protect, was marked dirty on + * unprotect, and did not change its size. Do this via * a call to H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(). * * If the size changed, this case is already dealt with by - * by the pre-existing call to + * by the pre-existing call to * H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(). * *------------------------------------------------------------------------- @@ -8047,7 +5466,7 @@ H5C_unprotect(H5F_t * f, entry_ptr->size = new_size; } else if ( ( was_clean ) && ( entry_ptr->is_dirty ) ) { - + H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr) } @@ -8522,7 +5941,7 @@ H5C_adjust_flush_dependency_rc(H5C_cache_entry_t * cache_entry, cache_entry->flush_dep_height = new_child_height + 1; } /* end if */ else { - /* Check for child's flush dep. height decreasing and ref. count of + /* Check for child's flush dep. height decreasing and ref. count of * old child height going to zero, it could mean the parent's * flush dependency height dropped. */ @@ -10787,8 +8206,8 @@ done: * the "destroy_entry" variable. * * JRM -- 11/5/08 - * Added call to H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN() to - * maintain the new clean_index_size and clean_index_size + * Added call to H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN() to + * maintain the new clean_index_size and clean_index_size * fields of H5C_t. * *------------------------------------------------------------------------- @@ -11101,7 +8520,7 @@ H5C_flush_single_entry(H5F_t * f, if ( destroy ) { #ifndef NDEBUG - /* we are about to call the clear callback with the + /* we are about to call the clear callback with the * destroy flag set -- this will result in *entry_ptr * being freed. Set the magic field to bad magic * so we can detect a freed cache entry if we see @@ -11130,7 +8549,7 @@ H5C_flush_single_entry(H5F_t * f, if ( destroy ) { #ifndef NDEBUG - /* we are about to call the flush callback with the + /* we are about to call the flush callback with the * destroy flag set -- this will result in *entry_ptr * being freed. Set the magic field to bad magic * so we can detect a freed cache entry if we see @@ -11246,11 +8665,11 @@ H5C_flush_single_entry(H5F_t * f, HDassert( entry_ptr->size < H5C_MAX_ENTRY_SIZE ); - /* update the hash table for the size change - * We pass TRUE as the was_clean parameter, as we + /* update the hash table for the size change + * We pass TRUE as the was_clean parameter, as we * have already updated the clean and dirty index * size fields for the fact that the entry has - * been flushed. (See above call to + * been flushed. (See above call to * H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN()). */ H5C__UPDATE_INDEX_FOR_SIZE_CHANGE((cache_ptr), \ @@ -11543,21 +8962,21 @@ done: * ever detect the condidtion. * * JRM -- 11/13/08 - * Modified function to always observe the min_clean_size + * Modified function to always observe the min_clean_size * whether we are maintaining the clean and dirt LRU lists * or not. To do this, we had to add the new clean_index_size * and dirty_index_size fields to H5C_t, and supporting code * as needed throughout the cache. * * The purpose of this modification is to avoid "metadata - * blizzards" in the write only case. In such instances, + * blizzards" in the write only case. In such instances, * the cache was allowed to fill with dirty metadata. When * we finally needed to evict an entry to make space, we had * to flush out a whole cache full of metadata -- which has - * interesting performance effects. We hope to avoid (or - * perhaps more accurately hide) this effect by maintaining + * interesting performance effects. We hope to avoid (or + * perhaps more accurately hide) this effect by maintaining * the min_clean_size, which should force us to start flushing - * entries long before we actually have to evict something + * entries long before we actually have to evict something * to make space. * * MAM -- 01/06/09 @@ -11596,7 +9015,7 @@ H5C_make_space_in_cache(H5F_t * f, HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); HDassert( first_flush_ptr != NULL ); HDassert( ( *first_flush_ptr == TRUE ) || ( *first_flush_ptr == FALSE ) ); - HDassert( cache_ptr->index_size == + HDassert( cache_ptr->index_size == (cache_ptr->clean_index_size + cache_ptr->dirty_index_size) ); if ( write_permitted ) { @@ -11667,7 +9086,7 @@ H5C_make_space_in_cache(H5F_t * f, H5C__NO_FLAGS_SET, first_flush_ptr, FALSE); - } else if ( (cache_ptr->index_size + space_needed) + } else if ( (cache_ptr->index_size + space_needed) > cache_ptr->max_cache_size ) { #if H5C_COLLECT_CACHE_STATS @@ -11685,12 +9104,12 @@ H5C_make_space_in_cache(H5F_t * f, TRUE); } else { - /* We have enough space so don't flush clean entry. - * Set result to SUCCEED to avoid triggering the error + /* We have enough space so don't flush clean entry. + * Set result to SUCCEED to avoid triggering the error * code below. */ #if H5C_COLLECT_CACHE_STATS - clean_entries_skipped++; + clean_entries_skipped++; #endif /* H5C_COLLECT_CACHE_STATS */ didnt_flush_entry = TRUE; result = SUCCEED; @@ -11769,9 +9188,9 @@ H5C_make_space_in_cache(H5F_t * f, empty_space = cache_ptr->max_cache_size - cache_ptr->index_size; } - - HDassert( cache_ptr->index_size == - (cache_ptr->clean_index_size + + + HDassert( cache_ptr->index_size == + (cache_ptr->clean_index_size + cache_ptr->dirty_index_size) ); } diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index b7a348b..db68e88 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -29,7 +29,7 @@ */ #ifndef H5C_PACKAGE -#error "Do not include this file outside the H5HL package!" +#error "Do not include this file outside the H5C package!" #endif #ifndef _H5Cpkg_H @@ -55,8 +55,6 @@ #define H5C__MAX_PASSES_ON_FLUSH 4 -#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */ - /**************************************************************************** * @@ -207,18 +205,18 @@ * the hash table. Note that the index_size field (above) * is also the sum of the sizes of all entries in the cache. * Thus we should have the invarient that clean_index_size + - * dirty_index_size == index_size. + * dirty_index_size == index_size. * * WARNING: * - * 1) The clean_index_size field is not maintained by the - * index macros, as the hash table doesn't care whether + * 1) The clean_index_size field is not maintained by the + * index macros, as the hash table doesn't care whether * the entry is clean or dirty. Instead the field is * maintained in the H5C__UPDATE_RP macros. * * 2) The value of the clean_index_size must not be mistaken - * for the current clean size of the cache. Rather, the - * clean size of the cache is the current value of + * for the current clean size of the cache. Rather, the + * clean size of the cache is the current value of * clean_index_size plus the amount of empty space (if any) * in the cache. * @@ -226,12 +224,12 @@ * the hash table. Note that the index_size field (above) * is also the sum of the sizes of all entries in the cache. * Thus we should have the invarient that clean_index_size + - * dirty_index_size == index_size. + * dirty_index_size == index_size. * * WARNING: * - * 1) The dirty_index_size field is not maintained by the - * index macros, as the hash table doesn't care whether + * 1) The dirty_index_size field is not maintained by the + * index macros, as the hash table doesn't care whether * the entry is clean or dirty. Instead the field is * maintained in the H5C__UPDATE_RP macros. * @@ -856,6 +854,8 @@ * ****************************************************************************/ +#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */ + #define H5C__H5C_T_MAGIC 0x005CAC0E #define H5C__MAX_NUM_TYPE_IDS 27 #define H5C__PREFIX_LEN 32 @@ -1017,5 +1017,2595 @@ struct H5C_t char prefix[H5C__PREFIX_LEN]; }; + +/****************************************************************************/ +/***************************** Macro Definitions ****************************/ +/****************************************************************************/ + + +/**************************************************************************** + * + * We maintain doubly linked lists of instances of H5C_cache_entry_t for a + * variety of reasons -- protected list, LRU list, and the clean and dirty + * LRU lists at present. The following macros support linking and unlinking + * of instances of H5C_cache_entry_t by both their regular and auxilary next + * and previous pointers. + * + * The size and length fields are also maintained. + * + * Note that the relevant pair of prev and next pointers are presumed to be + * NULL on entry in the insertion macros. + * + * Finally, observe that the sanity checking macros evaluate to the empty + * string when H5C_DO_SANITY_CHECKS is FALSE. They also contain calls + * to the HGOTO_ERROR macro, which may not be appropriate in all cases. + * If so, we will need versions of the insertion and deletion macros which + * do not reference the sanity checking macros. + * JRM - 5/5/04 + * + * Changes: + * + * - Removed the line: + * + * ( ( (Size) == (entry_ptr)->size ) && ( (len) != 1 ) ) || + * + * from the H5C__DLL_PRE_REMOVE_SC macro. With the addition of the + * epoch markers used in the age out based cache size reduction algorithm, + * this invarient need not hold, as the epoch markers are of size 0. + * + * One could argue that I should have given the epoch markers a positive + * size, but this would break the index_size = LRU_list_size + pl_size + * + pel_size invarient. + * + * Alternatively, I could pass the current decr_mode in to the macro, + * and just skip the check whenever epoch markers may be in use. + * + * However, any size errors should be caught when the cache is flushed + * and destroyed. Until we are tracking such an error, this should be + * good enough. + * JRM - 12/9/04 + * + * + * - In the H5C__DLL_PRE_INSERT_SC macro, replaced the lines: + * + * ( ( (len) == 1 ) && + * ( ( (head_ptr) != (tail_ptr) ) || ( (Size) <= 0 ) || + * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) + * ) + * ) || + * + * with: + * + * ( ( (len) == 1 ) && + * ( ( (head_ptr) != (tail_ptr) ) || + * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) + * ) + * ) || + * + * Epoch markers have size 0, so we can now have a non-empty list with + * zero size. Hence the "( (Size) <= 0 )" clause cause false failures + * in the sanity check. Since "Size" is typically a size_t, it can't + * take on negative values, and thus the revised clause "( (Size) < 0 )" + * caused compiler warnings. + * JRM - 12/22/04 + * + * - In the H5C__DLL_SC macro, replaced the lines: + * + * ( ( (len) == 1 ) && + * ( ( (head_ptr) != (tail_ptr) ) || ( (cache_ptr)->size <= 0 ) || + * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) + * ) + * ) || + * + * with + * + * ( ( (len) == 1 ) && + * ( ( (head_ptr) != (tail_ptr) ) || + * ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) + * ) + * ) || + * + * Epoch markers have size 0, so we can now have a non-empty list with + * zero size. Hence the "( (Size) <= 0 )" clause cause false failures + * in the sanity check. Since "Size" is typically a size_t, it can't + * take on negative values, and thus the revised clause "( (Size) < 0 )" + * caused compiler warnings. + * JRM - 1/10/05 + * + * - Added the H5C__DLL_UPDATE_FOR_SIZE_CHANGE macro and the associated + * sanity checking macros. These macro are used to update the size of + * a DLL when one of its entries changes size. + * + * JRM - 9/8/05 + * + ****************************************************************************/ + +#if H5C_DO_SANITY_CHECKS + +#define H5C__DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ +if ( ( (head_ptr) == NULL ) || \ + ( (tail_ptr) == NULL ) || \ + ( (entry_ptr) == NULL ) || \ + ( (len) <= 0 ) || \ + ( (Size) < (entry_ptr)->size ) || \ + ( ( (entry_ptr)->prev == NULL ) && ( (head_ptr) != (entry_ptr) ) ) || \ + ( ( (entry_ptr)->next == NULL ) && ( (tail_ptr) != (entry_ptr) ) ) || \ + ( ( (len) == 1 ) && \ + ( ! ( ( (head_ptr) == (entry_ptr) ) && \ + ( (tail_ptr) == (entry_ptr) ) && \ + ( (entry_ptr)->next == NULL ) && \ + ( (entry_ptr)->prev == NULL ) && \ + ( (Size) == (entry_ptr)->size ) \ + ) \ + ) \ + ) \ + ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL pre remove SC failed") \ +} + +#define H5C__DLL_SC(head_ptr, tail_ptr, len, Size, fv) \ +if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ + ( (head_ptr) != (tail_ptr) ) \ + ) || \ + ( (len) < 0 ) || \ + ( (Size) < 0 ) || \ + ( ( (len) == 1 ) && \ + ( ( (head_ptr) != (tail_ptr) ) || \ + ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) \ + ) \ + ) || \ + ( ( (len) >= 1 ) && \ + ( ( (head_ptr) == NULL ) || ( (head_ptr)->prev != NULL ) || \ + ( (tail_ptr) == NULL ) || ( (tail_ptr)->next != NULL ) \ + ) \ + ) \ + ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL sanity check failed") \ +} + +#define H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ +if ( ( (entry_ptr) == NULL ) || \ + ( (entry_ptr)->next != NULL ) || \ + ( (entry_ptr)->prev != NULL ) || \ + ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ + ( (head_ptr) != (tail_ptr) ) \ + ) || \ + ( (len) < 0 ) || \ + ( ( (len) == 1 ) && \ + ( ( (head_ptr) != (tail_ptr) ) || \ + ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) \ + ) \ + ) || \ + ( ( (len) >= 1 ) && \ + ( ( (head_ptr) == NULL ) || ( (head_ptr)->prev != NULL ) || \ + ( (tail_ptr) == NULL ) || ( (tail_ptr)->next != NULL ) \ + ) \ + ) \ + ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL pre insert SC failed") \ +} + +#define H5C__DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) \ +if ( ( (dll_len) <= 0 ) || \ + ( (dll_size) <= 0 ) || \ + ( (old_size) <= 0 ) || \ + ( (old_size) > (dll_size) ) || \ + ( (new_size) <= 0 ) || \ + ( ( (dll_len) == 1 ) && ( (old_size) != (dll_size) ) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "DLL pre size update SC failed") \ +} + +#define H5C__DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) \ +if ( ( (new_size) > (dll_size) ) || \ + ( ( (dll_len) == 1 ) && ( (new_size) != (dll_size) ) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "DLL post size update SC failed") \ +} + +#else /* H5C_DO_SANITY_CHECKS */ + +#define H5C__DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) +#define H5C__DLL_SC(head_ptr, tail_ptr, len, Size, fv) +#define H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) +#define H5C__DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) +#define H5C__DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) + +#endif /* H5C_DO_SANITY_CHECKS */ + + +#define H5C__DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \ + H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ + fail_val) \ + if ( (head_ptr) == NULL ) \ + { \ + (head_ptr) = (entry_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + else \ + { \ + (tail_ptr)->next = (entry_ptr); \ + (entry_ptr)->prev = (tail_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + (len)++; \ + (Size) += (entry_ptr)->size; + +#define H5C__DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \ + H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ + fail_val) \ + if ( (head_ptr) == NULL ) \ + { \ + (head_ptr) = (entry_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + else \ + { \ + (head_ptr)->prev = (entry_ptr); \ + (entry_ptr)->next = (head_ptr); \ + (head_ptr) = (entry_ptr); \ + } \ + (len)++; \ + (Size) += entry_ptr->size; + +#define H5C__DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val) \ + H5C__DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ + fail_val) \ + { \ + if ( (head_ptr) == (entry_ptr) ) \ + { \ + (head_ptr) = (entry_ptr)->next; \ + if ( (head_ptr) != NULL ) \ + { \ + (head_ptr)->prev = NULL; \ + } \ + } \ + else \ + { \ + (entry_ptr)->prev->next = (entry_ptr)->next; \ + } \ + if ( (tail_ptr) == (entry_ptr) ) \ + { \ + (tail_ptr) = (entry_ptr)->prev; \ + if ( (tail_ptr) != NULL ) \ + { \ + (tail_ptr)->next = NULL; \ + } \ + } \ + else \ + { \ + (entry_ptr)->next->prev = (entry_ptr)->prev; \ + } \ + entry_ptr->next = NULL; \ + entry_ptr->prev = NULL; \ + (len)--; \ + (Size) -= entry_ptr->size; \ + } + +#define H5C__DLL_UPDATE_FOR_SIZE_CHANGE(dll_len, dll_size, old_size, new_size) \ + H5C__DLL_PRE_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) \ + (dll_size) -= (old_size); \ + (dll_size) += (new_size); \ + H5C__DLL_POST_SIZE_UPDATE_SC(dll_len, dll_size, old_size, new_size) + +#if H5C_DO_SANITY_CHECKS + +#define H5C__AUX_DLL_PRE_REMOVE_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) \ +if ( ( (hd_ptr) == NULL ) || \ + ( (tail_ptr) == NULL ) || \ + ( (entry_ptr) == NULL ) || \ + ( (len) <= 0 ) || \ + ( (Size) < (entry_ptr)->size ) || \ + ( ( (Size) == (entry_ptr)->size ) && ( ! ( (len) == 1 ) ) ) || \ + ( ( (entry_ptr)->aux_prev == NULL ) && ( (hd_ptr) != (entry_ptr) ) ) || \ + ( ( (entry_ptr)->aux_next == NULL ) && ( (tail_ptr) != (entry_ptr) ) ) || \ + ( ( (len) == 1 ) && \ + ( ! ( ( (hd_ptr) == (entry_ptr) ) && ( (tail_ptr) == (entry_ptr) ) && \ + ( (entry_ptr)->aux_next == NULL ) && \ + ( (entry_ptr)->aux_prev == NULL ) && \ + ( (Size) == (entry_ptr)->size ) \ + ) \ + ) \ + ) \ + ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "aux DLL pre remove SC failed") \ +} + +#define H5C__AUX_DLL_SC(head_ptr, tail_ptr, len, Size, fv) \ +if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ + ( (head_ptr) != (tail_ptr) ) \ + ) || \ + ( (len) < 0 ) || \ + ( (Size) < 0 ) || \ + ( ( (len) == 1 ) && \ + ( ( (head_ptr) != (tail_ptr) ) || ( (Size) <= 0 ) || \ + ( (head_ptr) == NULL ) || ( (head_ptr)->size != (Size) ) \ + ) \ + ) || \ + ( ( (len) >= 1 ) && \ + ( ( (head_ptr) == NULL ) || ( (head_ptr)->aux_prev != NULL ) || \ + ( (tail_ptr) == NULL ) || ( (tail_ptr)->aux_next != NULL ) \ + ) \ + ) \ + ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "AUX DLL sanity check failed") \ +} + +#define H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) \ +if ( ( (entry_ptr) == NULL ) || \ + ( (entry_ptr)->aux_next != NULL ) || \ + ( (entry_ptr)->aux_prev != NULL ) || \ + ( ( ( (hd_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ + ( (hd_ptr) != (tail_ptr) ) \ + ) || \ + ( (len) < 0 ) || \ + ( ( (len) == 1 ) && \ + ( ( (hd_ptr) != (tail_ptr) ) || ( (Size) <= 0 ) || \ + ( (hd_ptr) == NULL ) || ( (hd_ptr)->size != (Size) ) \ + ) \ + ) || \ + ( ( (len) >= 1 ) && \ + ( ( (hd_ptr) == NULL ) || ( (hd_ptr)->aux_prev != NULL ) || \ + ( (tail_ptr) == NULL ) || ( (tail_ptr)->aux_next != NULL ) \ + ) \ + ) \ + ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "AUX DLL pre insert SC failed") \ +} + +#else /* H5C_DO_SANITY_CHECKS */ + +#define H5C__AUX_DLL_PRE_REMOVE_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) +#define H5C__AUX_DLL_SC(head_ptr, tail_ptr, len, Size, fv) +#define H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) + +#endif /* H5C_DO_SANITY_CHECKS */ + + +#define H5C__AUX_DLL_APPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fail_val)\ + H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ + fail_val) \ + if ( (head_ptr) == NULL ) \ + { \ + (head_ptr) = (entry_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + else \ + { \ + (tail_ptr)->aux_next = (entry_ptr); \ + (entry_ptr)->aux_prev = (tail_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + (len)++; \ + (Size) += entry_ptr->size; + +#define H5C__AUX_DLL_PREPEND(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ + H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ + fv) \ + if ( (head_ptr) == NULL ) \ + { \ + (head_ptr) = (entry_ptr); \ + (tail_ptr) = (entry_ptr); \ + } \ + else \ + { \ + (head_ptr)->aux_prev = (entry_ptr); \ + (entry_ptr)->aux_next = (head_ptr); \ + (head_ptr) = (entry_ptr); \ + } \ + (len)++; \ + (Size) += entry_ptr->size; + +#define H5C__AUX_DLL_REMOVE(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ + H5C__AUX_DLL_PRE_REMOVE_SC(entry_ptr, head_ptr, tail_ptr, len, Size, \ + fv) \ + { \ + if ( (head_ptr) == (entry_ptr) ) \ + { \ + (head_ptr) = (entry_ptr)->aux_next; \ + if ( (head_ptr) != NULL ) \ + { \ + (head_ptr)->aux_prev = NULL; \ + } \ + } \ + else \ + { \ + (entry_ptr)->aux_prev->aux_next = (entry_ptr)->aux_next; \ + } \ + if ( (tail_ptr) == (entry_ptr) ) \ + { \ + (tail_ptr) = (entry_ptr)->aux_prev; \ + if ( (tail_ptr) != NULL ) \ + { \ + (tail_ptr)->aux_next = NULL; \ + } \ + } \ + else \ + { \ + (entry_ptr)->aux_next->aux_prev = (entry_ptr)->aux_prev; \ + } \ + entry_ptr->aux_next = NULL; \ + entry_ptr->aux_prev = NULL; \ + (len)--; \ + (Size) -= entry_ptr->size; \ + } + + +/*********************************************************************** + * + * Stats collection macros + * + * The following macros must handle stats collection when this collection + * is enabled, and evaluate to the empty string when it is not. + * + * The sole exception to this rule is + * H5C__UPDATE_CACHE_HIT_RATE_STATS(), which is always active as + * the cache hit rate stats are always collected and available. + * + * Changes: + * + * JRM -- 3/21/06 + * Added / updated macros for pinned entry related stats. + * + * JRM -- 8/9/06 + * More pinned entry stats related updates. + * + * JRM -- 3/31/07 + * Updated H5C__UPDATE_STATS_FOR_PROTECT() to keep stats on + * read and write protects. + * + * MAM -- 1/15/09 + * Created H5C__UPDATE_MAX_INDEX_SIZE_STATS to contain + * common code within macros that update the maximum + * index, clean_index, and dirty_index statistics fields. + * + ***********************************************************************/ + +#define H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit) \ + (cache_ptr->cache_accesses)++; \ + if ( hit ) { \ + (cache_ptr->cache_hits)++; \ + } \ + +#if H5C_COLLECT_CACHE_STATS + +#define H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ + (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ + if ( (cache_ptr)->clean_index_size > \ + (cache_ptr)->max_clean_index_size ) \ + (cache_ptr)->max_clean_index_size = \ + (cache_ptr)->clean_index_size; \ + if ( (cache_ptr)->dirty_index_size > \ + (cache_ptr)->max_dirty_index_size ) \ + (cache_ptr)->max_dirty_index_size = \ + (cache_ptr)->dirty_index_size; + +#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) \ + (((cache_ptr)->dirty_pins)[(entry_ptr)->type->id])++; + +#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) \ + if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ + (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ + if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ + if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; + +#define H5C__UPDATE_STATS_FOR_RENAME(cache_ptr, entry_ptr) \ + if ( cache_ptr->flush_in_progress ) { \ + ((cache_ptr)->cache_flush_renames[(entry_ptr)->type->id])++; \ + } \ + if ( entry_ptr->flush_in_progress ) { \ + ((cache_ptr)->entry_flush_renames[(entry_ptr)->type->id])++; \ + } \ + (((cache_ptr)->renames)[(entry_ptr)->type->id])++; + +#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size)\ + if ( cache_ptr->flush_in_progress ) { \ + ((cache_ptr)->cache_flush_size_changes[(entry_ptr)->type->id])++; \ + } \ + if ( entry_ptr->flush_in_progress ) { \ + ((cache_ptr)->entry_flush_size_changes[(entry_ptr)->type->id])++; \ + } \ + if ( (entry_ptr)->size < (new_size) ) { \ + ((cache_ptr)->size_increases[(entry_ptr)->type->id])++; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ + if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ + (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ + } else if ( (entry_ptr)->size > (new_size) ) { \ + ((cache_ptr)->size_decreases[(entry_ptr)->type->id])++; \ + } + +#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ + (cache_ptr)->total_ht_insertions++; + +#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ + (cache_ptr)->total_ht_deletions++; + +#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) \ + if ( success ) { \ + (cache_ptr)->successful_ht_searches++; \ + (cache_ptr)->total_successful_ht_search_depth += depth; \ + } else { \ + (cache_ptr)->failed_ht_searches++; \ + (cache_ptr)->total_failed_ht_search_depth += depth; \ + } + +#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) \ + ((cache_ptr)->unpins)[(entry_ptr)->type->id]++; + +#if H5C_COLLECT_CACHE_ENTRY_STATS + +#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) \ + (entry_ptr)->accesses = 0; \ + (entry_ptr)->clears = 0; \ + (entry_ptr)->flushes = 0; \ + (entry_ptr)->pins = 0; + +#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ + (((cache_ptr)->clears)[(entry_ptr)->type->id])++; \ + if ( (entry_ptr)->is_pinned ) { \ + (((cache_ptr)->pinned_clears)[(entry_ptr)->type->id])++; \ + } \ + ((entry_ptr)->clears)++; + +#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ + (((cache_ptr)->flushes)[(entry_ptr)->type->id])++; \ + if ( (entry_ptr)->is_pinned ) { \ + (((cache_ptr)->pinned_flushes)[(entry_ptr)->type->id])++; \ + } \ + ((entry_ptr)->flushes)++; + +#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr) \ + (((cache_ptr)->evictions)[(entry_ptr)->type->id])++; \ + if ( (entry_ptr)->accesses > \ + ((cache_ptr)->max_accesses)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_accesses)[(entry_ptr)->type->id] \ + = (entry_ptr)->accesses; \ + } \ + if ( (entry_ptr)->accesses < \ + ((cache_ptr)->min_accesses)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->min_accesses)[(entry_ptr)->type->id] \ + = (entry_ptr)->accesses; \ + } \ + if ( (entry_ptr)->clears > \ + ((cache_ptr)->max_clears)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_clears)[(entry_ptr)->type->id] \ + = (entry_ptr)->clears; \ + } \ + if ( (entry_ptr)->flushes > \ + ((cache_ptr)->max_flushes)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_flushes)[(entry_ptr)->type->id] \ + = (entry_ptr)->flushes; \ + } \ + if ( (entry_ptr)->size > \ + ((cache_ptr)->max_size)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_size)[(entry_ptr)->type->id] \ + = (entry_ptr)->size; \ + } \ + if ( (entry_ptr)->pins > \ + ((cache_ptr)->max_pins)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_pins)[(entry_ptr)->type->id] \ + = (entry_ptr)->pins; \ + } + +#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ + (((cache_ptr)->insertions)[(entry_ptr)->type->id])++; \ + if ( (entry_ptr)->is_pinned ) { \ + (((cache_ptr)->pinned_insertions)[(entry_ptr)->type->id])++; \ + ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ + (entry_ptr)->pins++; \ + if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ + } \ + if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ + (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ + if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ + if ( (entry_ptr)->size > \ + ((cache_ptr)->max_size)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_size)[(entry_ptr)->type->id] \ + = (entry_ptr)->size; \ + } + +#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ + if ( hit ) \ + ((cache_ptr)->hits)[(entry_ptr)->type->id]++; \ + else \ + ((cache_ptr)->misses)[(entry_ptr)->type->id]++; \ + if ( ! ((entry_ptr)->is_read_only) ) { \ + ((cache_ptr)->write_protects)[(entry_ptr)->type->id]++; \ + } else { \ + ((cache_ptr)->read_protects)[(entry_ptr)->type->id]++; \ + if ( ((entry_ptr)->ro_ref_count) > \ + ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] = \ + ((entry_ptr)->ro_ref_count); \ + } \ + } \ + if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \ + (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ + if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ + (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; \ + if ( (entry_ptr)->size > \ + ((cache_ptr)->max_size)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_size)[(entry_ptr)->type->id] \ + = (entry_ptr)->size; \ + } \ + ((entry_ptr)->accesses)++; + +#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ + ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ + (entry_ptr)->pins++; \ + if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; + +#else /* H5C_COLLECT_CACHE_ENTRY_STATS */ + +#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) + +#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) \ + if ( (entry_ptr)->is_pinned ) { \ + (((cache_ptr)->pinned_clears)[(entry_ptr)->type->id])++; \ + } \ + (((cache_ptr)->clears)[(entry_ptr)->type->id])++; + +#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) \ + (((cache_ptr)->flushes)[(entry_ptr)->type->id])++; \ + if ( (entry_ptr)->is_pinned ) { \ + (((cache_ptr)->pinned_flushes)[(entry_ptr)->type->id])++; \ + } + +#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr) \ + (((cache_ptr)->evictions)[(entry_ptr)->type->id])++; + +#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) \ + (((cache_ptr)->insertions)[(entry_ptr)->type->id])++; \ + if ( (entry_ptr)->is_pinned ) { \ + (((cache_ptr)->pinned_insertions)[(entry_ptr)->type->id])++; \ + ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ + if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; \ + } \ + if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ + (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ + if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ + (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; + +#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) \ + if ( hit ) \ + ((cache_ptr)->hits)[(entry_ptr)->type->id]++; \ + else \ + ((cache_ptr)->misses)[(entry_ptr)->type->id]++; \ + if ( ! ((entry_ptr)->is_read_only) ) { \ + ((cache_ptr)->write_protects)[(entry_ptr)->type->id]++; \ + } else { \ + ((cache_ptr)->read_protects)[(entry_ptr)->type->id]++; \ + if ( ((entry_ptr)->ro_ref_count) > \ + ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] ) { \ + ((cache_ptr)->max_read_protects)[(entry_ptr)->type->id] = \ + ((entry_ptr)->ro_ref_count); \ + } \ + } \ + if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ + (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \ + (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ + if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ + (cache_ptr)->max_pl_size = (cache_ptr)->pl_size; + +#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) \ + ((cache_ptr)->pins)[(entry_ptr)->type->id]++; \ + if ( (cache_ptr)->pel_len > (cache_ptr)->max_pel_len ) \ + (cache_ptr)->max_pel_len = (cache_ptr)->pel_len; \ + if ( (cache_ptr)->pel_size > (cache_ptr)->max_pel_size ) \ + (cache_ptr)->max_pel_size = (cache_ptr)->pel_size; + +#endif /* H5C_COLLECT_CACHE_ENTRY_STATS */ + +#else /* H5C_COLLECT_CACHE_STATS */ + +#define H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) +#define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) +#define H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr) +#define H5C__UPDATE_STATS_FOR_RENAME(cache_ptr, entry_ptr) +#define H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) +#define H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) +#define H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) +#define H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, success, depth) +#define H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) +#define H5C__UPDATE_STATS_FOR_CLEAR(cache_ptr, entry_ptr) +#define H5C__UPDATE_STATS_FOR_FLUSH(cache_ptr, entry_ptr) +#define H5C__UPDATE_STATS_FOR_EVICTION(cache_ptr, entry_ptr) +#define H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit) +#define H5C__UPDATE_STATS_FOR_PIN(cache_ptr, entry_ptr) +#define H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, entry_ptr) + +#endif /* H5C_COLLECT_CACHE_STATS */ + + +/*********************************************************************** + * + * Hash table access and manipulation macros: + * + * The following macros handle searches, insertions, and deletion in + * the hash table. + * + * When modifying these macros, remember to modify the similar macros + * in tst/cache.c + * + * Changes: + * + * - Updated existing index macros and sanity check macros to maintain + * the clean_index_size and dirty_index_size fields of H5C_t. Also + * added macros to allow us to track entry cleans and dirties. + * + * JRM -- 11/5/08 + * + ***********************************************************************/ + +/* H5C__HASH_TABLE_LEN is defined in H5Cpkg.h. It mut be a power of two. */ + +#define H5C__HASH_MASK ((size_t)(H5C__HASH_TABLE_LEN - 1) << 3) + +#define H5C__HASH_FCN(x) (int)(((x) & H5C__HASH_MASK) >> 3) + +#if H5C_DO_SANITY_CHECKS + +#define H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (entry_ptr) == NULL ) || \ + ( ! H5F_addr_defined((entry_ptr)->addr) ) || \ + ( (entry_ptr)->ht_next != NULL ) || \ + ( (entry_ptr)->ht_prev != NULL ) || \ + ( (entry_ptr)->size <= 0 ) || \ + ( (k = H5C__HASH_FCN((entry_ptr)->addr)) < 0 ) || \ + ( k >= H5C__HASH_TABLE_LEN ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + \ + (cache_ptr)->dirty_index_size) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ + "Pre HT insert SC failed") \ +} + +#define H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len < 1 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( ! H5F_addr_defined((entry_ptr)->addr) ) || \ + ( (entry_ptr)->size <= 0 ) || \ + ( H5C__HASH_FCN((entry_ptr)->addr) < 0 ) || \ + ( H5C__HASH_FCN((entry_ptr)->addr) >= H5C__HASH_TABLE_LEN ) || \ + ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] \ + == NULL ) || \ + ( ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] \ + != (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev == NULL ) ) || \ + ( ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] == \ + (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev != NULL ) ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + \ + (cache_ptr)->dirty_index_size) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Pre HT remove SC failed") \ +} + +/* (Keep in sync w/H5C_TEST__PRE_HT_SEARCH_SC macro in test/cache_common.h -QAK) */ +#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) || \ + ( ! H5F_addr_defined(Addr) ) || \ + ( H5C__HASH_FCN(Addr) < 0 ) || \ + ( H5C__HASH_FCN(Addr) >= H5C__HASH_TABLE_LEN ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, "Pre HT search SC failed") \ +} + +/* (Keep in sync w/H5C_TEST__POST_SUC_HT_SEARCH_SC macro in test/cache_common.h -QAK) */ +#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len < 1 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) || \ + ( H5F_addr_ne((entry_ptr)->addr, (Addr)) ) || \ + ( (entry_ptr)->size <= 0 ) || \ + ( ((cache_ptr)->index)[k] == NULL ) || \ + ( ( ((cache_ptr)->index)[k] != (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev == NULL ) ) || \ + ( ( ((cache_ptr)->index)[k] == (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev != NULL ) ) || \ + ( ( (entry_ptr)->ht_prev != NULL ) && \ + ( (entry_ptr)->ht_prev->ht_next != (entry_ptr) ) ) || \ + ( ( (entry_ptr)->ht_next != NULL ) && \ + ( (entry_ptr)->ht_next->ht_prev != (entry_ptr) ) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ + "Post successful HT search SC failed") \ +} + +/* (Keep in sync w/H5C_TEST__POST_HT_SHIFT_TO_FRONT macro in test/cache_common.h -QAK) */ +#define H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) \ +if ( ( (cache_ptr) == NULL ) || \ + ( ((cache_ptr)->index)[k] != (entry_ptr) ) || \ + ( (entry_ptr)->ht_prev != NULL ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ + "Post HT shift to front SC failed") \ +} + +#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ + entry_ptr, was_clean) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->index_len <= 0 ) || \ + ( (cache_ptr)->index_size <= 0 ) || \ + ( (new_size) <= 0 ) || \ + ( (old_size) > (cache_ptr)->index_size ) || \ + ( (new_size) <= 0 ) || \ + ( ( (cache_ptr)->index_len == 1 ) && \ + ( (cache_ptr)->index_size != (old_size) ) ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + \ + (cache_ptr)->dirty_index_size) ) || \ + ( (entry_ptr == NULL) ) || \ + ( ( !( was_clean ) || \ + ( (cache_ptr)->clean_index_size < (old_size) ) ) && \ + ( ( (was_clean) ) || \ + ( (cache_ptr)->dirty_index_size < (old_size) ) ) ) \ + ( (entry_ptr) == NULL ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Pre HT entry size change SC failed") \ +} + +#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ + entry_ptr) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->index_len <= 0 ) || \ + ( (cache_ptr)->index_size <= 0 ) || \ + ( (new_size) > (cache_ptr)->index_size ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + \ + (cache_ptr)->dirty_index_size) ) || \ + ( ( !((entry_ptr)->is_dirty ) || \ + ( (cache_ptr)->dirty_index_size < (new_size) ) ) && \ + ( ( ((entry_ptr)->is_dirty) ) || \ + ( (cache_ptr)->clean_index_size < (new_size) ) ) ) \ + ( ( (cache_ptr)->index_len == 1 ) && \ + ( (cache_ptr)->index_size != (new_size) ) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Post HT entry size change SC failed") \ +} + +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ +if ( \ + ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len <= 0 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (entry_ptr)->is_dirty != FALSE ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->dirty_index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Pre HT update for entry clean SC failed") \ +} + +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ +if ( \ + ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len <= 0 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (entry_ptr)->is_dirty != TRUE ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->clean_index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Pre HT update for entry dirty SC failed") \ +} + +#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ +if ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Post HT update for entry clean SC failed") \ +} + +#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ +if ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Post HT update for entry dirty SC failed") \ +} + +#else /* H5C_DO_SANITY_CHECKS */ + +#define H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) +#define H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr) +#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) +#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) +#define H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) +#define H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ + entry_ptr, was_clean) +#define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ + entry_ptr) +#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) +#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) + +#endif /* H5C_DO_SANITY_CHECKS */ + + +#define H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, fail_val) \ +{ \ + int k; \ + H5C__PRE_HT_INSERT_SC(cache_ptr, entry_ptr, fail_val) \ + k = H5C__HASH_FCN((entry_ptr)->addr); \ + if ( ((cache_ptr)->index)[k] == NULL ) \ + { \ + ((cache_ptr)->index)[k] = (entry_ptr); \ + } \ + else \ + { \ + (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr); \ + ((cache_ptr)->index)[k] = (entry_ptr); \ + } \ + (cache_ptr)->index_len++; \ + (cache_ptr)->index_size += (entry_ptr)->size; \ + if ( (entry_ptr)->is_dirty ) { \ + (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ + } else { \ + (cache_ptr)->clean_index_size += (entry_ptr)->size; \ + } \ + H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ +} + +#define H5C__DELETE_FROM_INDEX(cache_ptr, entry_ptr) \ +{ \ + int k; \ + H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr) \ + k = H5C__HASH_FCN((entry_ptr)->addr); \ + if ( (entry_ptr)->ht_next ) \ + { \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ + } \ + if ( (entry_ptr)->ht_prev ) \ + { \ + (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ + } \ + if ( ((cache_ptr)->index)[k] == (entry_ptr) ) \ + { \ + ((cache_ptr)->index)[k] = (entry_ptr)->ht_next; \ + } \ + (entry_ptr)->ht_next = NULL; \ + (entry_ptr)->ht_prev = NULL; \ + (cache_ptr)->index_len--; \ + (cache_ptr)->index_size -= (entry_ptr)->size; \ + if ( (entry_ptr)->is_dirty ) { \ + (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ + } else { \ + (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ + } \ + H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ +} + +#define H5C__SEARCH_INDEX(cache_ptr, Addr, entry_ptr, fail_val) \ +{ \ + int k; \ + int depth = 0; \ + H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \ + k = H5C__HASH_FCN(Addr); \ + entry_ptr = ((cache_ptr)->index)[k]; \ + while ( ( entry_ptr ) && ( H5F_addr_ne(Addr, (entry_ptr)->addr) ) ) \ + { \ + (entry_ptr) = (entry_ptr)->ht_next; \ + (depth)++; \ + } \ + if ( entry_ptr ) \ + { \ + H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) \ + if ( entry_ptr != ((cache_ptr)->index)[k] ) \ + { \ + if ( (entry_ptr)->ht_next ) \ + { \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ + } \ + HDassert( (entry_ptr)->ht_prev != NULL ); \ + (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ + ((cache_ptr)->index)[k]->ht_prev = (entry_ptr); \ + (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ + (entry_ptr)->ht_prev = NULL; \ + ((cache_ptr)->index)[k] = (entry_ptr); \ + H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) \ + } \ + } \ + H5C__UPDATE_STATS_FOR_HT_SEARCH(cache_ptr, (entry_ptr != NULL), depth) \ +} + +#define H5C__SEARCH_INDEX_NO_STATS(cache_ptr, Addr, entry_ptr, fail_val) \ +{ \ + int k; \ + int depth = 0; \ + H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \ + k = H5C__HASH_FCN(Addr); \ + entry_ptr = ((cache_ptr)->index)[k]; \ + while ( ( entry_ptr ) && ( H5F_addr_ne(Addr, (entry_ptr)->addr) ) ) \ + { \ + (entry_ptr) = (entry_ptr)->ht_next; \ + (depth)++; \ + } \ + if ( entry_ptr ) \ + { \ + H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) \ + if ( entry_ptr != ((cache_ptr)->index)[k] ) \ + { \ + if ( (entry_ptr)->ht_next ) \ + { \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ + } \ + HDassert( (entry_ptr)->ht_prev != NULL ); \ + (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ + ((cache_ptr)->index)[k]->ht_prev = (entry_ptr); \ + (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ + (entry_ptr)->ht_prev = NULL; \ + ((cache_ptr)->index)[k] = (entry_ptr); \ + H5C__POST_HT_SHIFT_TO_FRONT(cache_ptr, entry_ptr, k, fail_val) \ + } \ + } \ +} + +#define H5C__UPDATE_INDEX_FOR_ENTRY_CLEAN(cache_ptr, entry_ptr) \ +{ \ + H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \ + (cache_ptr)->dirty_index_size -= (entry_ptr)->size; \ + (cache_ptr)->clean_index_size += (entry_ptr)->size; \ + H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr); \ +} + +#define H5C__UPDATE_INDEX_FOR_ENTRY_DIRTY(cache_ptr, entry_ptr) \ +{ \ + H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \ + (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ + (cache_ptr)->dirty_index_size += (entry_ptr)->size; \ + H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr); \ +} + +#define H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size, \ + entry_ptr, was_clean) \ +{ \ + H5C__PRE_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ + entry_ptr, was_clean) \ + (cache_ptr)->index_size -= (old_size); \ + (cache_ptr)->index_size += (new_size); \ + if ( was_clean ) { \ + (cache_ptr)->clean_index_size -= (old_size); \ + } else { \ + (cache_ptr)->dirty_index_size -= (old_size); \ + } \ + if ( (entry_ptr)->is_dirty ) { \ + (cache_ptr)->dirty_index_size += (new_size); \ + } else { \ + (cache_ptr)->clean_index_size += (new_size); \ + } \ + H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, entry_ptr) \ +} + + +/************************************************************************** + * + * Skip list insertion and deletion macros: + * + * These used to be functions, but I converted them to macros to avoid some + * function call overhead. + * + **************************************************************************/ + +/*------------------------------------------------------------------------- + * + * Macro: H5C__INSERT_ENTRY_IN_SLIST + * + * Purpose: Insert the specified instance of H5C_cache_entry_t into + * the skip list in the specified instance of H5C_t. Update + * the associated length and size fields. + * + * Return: N/A + * + * Programmer: John Mainzer, 5/10/04 + * + * Modifications: + * + * JRM -- 7/21/04 + * Updated function to set the in_tree flag when inserting + * an entry into the tree. Also modified the function to + * update the tree size and len fields instead of the similar + * index fields. + * + * All of this is part of the modifications to support the + * hash table. + * + * JRM -- 7/27/04 + * Converted the function H5C_insert_entry_in_tree() into + * the macro H5C__INSERT_ENTRY_IN_TREE in the hopes of + * wringing a little more speed out of the cache. + * + * Note that we don't bother to check if the entry is already + * in the tree -- if it is, H5SL_insert() will fail. + * + * QAK -- 11/27/04 + * Switched over to using skip list routines. + * + * JRM -- 6/27/06 + * Added fail_val parameter. + * + * JRM -- 8/25/06 + * Added the H5C_DO_SANITY_CHECKS version of the macro. + * + * This version maintains the slist_len_increase and + * slist_size_increase fields that are used in sanity + * checks in the flush routines. + * + * All this is needed as the fractal heap needs to be + * able to dirty, resize and/or rename entries during the + * flush. + * + *------------------------------------------------------------------------- + */ + +#if H5C_DO_SANITY_CHECKS + +#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( (entry_ptr)->size > 0 ); \ + HDassert( H5F_addr_defined((entry_ptr)->addr) ); \ + HDassert( !((entry_ptr)->in_slist) ); \ + \ + if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &(entry_ptr)->addr) \ + < 0 ) \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), \ + "Can't insert entry in skip list") \ + \ + (entry_ptr)->in_slist = TRUE; \ + (cache_ptr)->slist_len++; \ + (cache_ptr)->slist_size += (entry_ptr)->size; \ + (cache_ptr)->slist_len_increase++; \ + (cache_ptr)->slist_size_increase += (entry_ptr)->size; \ + \ + HDassert( (cache_ptr)->slist_len > 0 ); \ + HDassert( (cache_ptr)->slist_size > 0 ); \ + \ +} /* H5C__INSERT_ENTRY_IN_SLIST */ + +#else /* H5C_DO_SANITY_CHECKS */ + +#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( (entry_ptr)->size > 0 ); \ + HDassert( H5F_addr_defined((entry_ptr)->addr) ); \ + HDassert( !((entry_ptr)->in_slist) ); \ + \ + if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &(entry_ptr)->addr) \ + < 0 ) \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), \ + "Can't insert entry in skip list") \ + \ + (entry_ptr)->in_slist = TRUE; \ + (cache_ptr)->slist_len++; \ + (cache_ptr)->slist_size += (entry_ptr)->size; \ + \ + HDassert( (cache_ptr)->slist_len > 0 ); \ + HDassert( (cache_ptr)->slist_size > 0 ); \ + \ +} /* H5C__INSERT_ENTRY_IN_SLIST */ + +#endif /* H5C_DO_SANITY_CHECKS */ + + +/*------------------------------------------------------------------------- + * + * Function: H5C__REMOVE_ENTRY_FROM_SLIST + * + * Purpose: Remove the specified instance of H5C_cache_entry_t from the + * index skip list in the specified instance of H5C_t. Update + * the associated length and size fields. + * + * Return: N/A + * + * Programmer: John Mainzer, 5/10/04 + * + * Modifications: + * + * JRM -- 7/21/04 + * Updated function for the addition of the hash table. + * + * JRM - 7/27/04 + * Converted from the function H5C_remove_entry_from_tree() + * to the macro H5C__REMOVE_ENTRY_FROM_TREE in the hopes of + * wringing a little more performance out of the cache. + * + * QAK -- 11/27/04 + * Switched over to using skip list routines. + * + * JRM -- 3/28/07 + * Updated sanity checks for the new is_read_only and + * ro_ref_count fields in H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + HDassert( (entry_ptr)->in_slist ); \ + HDassert( (cache_ptr)->slist_ptr ); \ + \ + if ( H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \ + != (entry_ptr) ) \ + \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ + "Can't delete entry from skip list.") \ + \ + HDassert( (cache_ptr)->slist_len > 0 ); \ + (cache_ptr)->slist_len--; \ + HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \ + (cache_ptr)->slist_size -= (entry_ptr)->size; \ + (entry_ptr)->in_slist = FALSE; \ +} /* H5C__REMOVE_ENTRY_FROM_SLIST */ + + +/*------------------------------------------------------------------------- + * + * Function: H5C__UPDATE_SLIST_FOR_SIZE_CHANGE + * + * Purpose: Update cache_ptr->slist_size for a change in the size of + * and entry in the slist. + * + * Return: N/A + * + * Programmer: John Mainzer, 9/07/05 + * + * Modifications: + * + * JRM -- 8/27/06 + * Added the H5C_DO_SANITY_CHECKS version of the macro. + * + * This version maintains the slist_size_increase field + * that are used in sanity checks in the flush routines. + * + * All this is needed as the fractal heap needs to be + * able to dirty, resize and/or rename entries during the + * flush. + * + *------------------------------------------------------------------------- + */ + +#if H5C_DO_SANITY_CHECKS + +#define H5C__UPDATE_SLIST_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (old_size) > 0 ); \ + HDassert( (new_size) > 0 ); \ + HDassert( (old_size) <= (cache_ptr)->slist_size ); \ + HDassert( (cache_ptr)->slist_len > 0 ); \ + HDassert( ((cache_ptr)->slist_len > 1) || \ + ( (cache_ptr)->slist_size == (old_size) ) ); \ + \ + (cache_ptr)->slist_size -= (old_size); \ + (cache_ptr)->slist_size += (new_size); \ + \ + (cache_ptr)->slist_size_increase -= (int64_t)(old_size); \ + (cache_ptr)->slist_size_increase += (int64_t)(new_size); \ + \ + HDassert( (new_size) <= (cache_ptr)->slist_size ); \ + HDassert( ( (cache_ptr)->slist_len > 1 ) || \ + ( (cache_ptr)->slist_size == (new_size) ) ); \ +} /* H5C__REMOVE_ENTRY_FROM_SLIST */ + +#else /* H5C_DO_SANITY_CHECKS */ + +#define H5C__UPDATE_SLIST_FOR_SIZE_CHANGE(cache_ptr, old_size, new_size) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (old_size) > 0 ); \ + HDassert( (new_size) > 0 ); \ + HDassert( (old_size) <= (cache_ptr)->slist_size ); \ + HDassert( (cache_ptr)->slist_len > 0 ); \ + HDassert( ((cache_ptr)->slist_len > 1) || \ + ( (cache_ptr)->slist_size == (old_size) ) ); \ + \ + (cache_ptr)->slist_size -= (old_size); \ + (cache_ptr)->slist_size += (new_size); \ + \ + HDassert( (new_size) <= (cache_ptr)->slist_size ); \ + HDassert( ( (cache_ptr)->slist_len > 1 ) || \ + ( (cache_ptr)->slist_size == (new_size) ) ); \ +} /* H5C__REMOVE_ENTRY_FROM_SLIST */ + +#endif /* H5C_DO_SANITY_CHECKS */ + + +/************************************************************************** + * + * Replacement policy update macros: + * + * These used to be functions, but I converted them to macros to avoid some + * function call overhead. + * + **************************************************************************/ + +/*------------------------------------------------------------------------- + * + * Macro: H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS + * + * Purpose: For efficiency, we sometimes change the order of flushes -- + * but doing so can confuse the replacement policy. This + * macro exists to allow us to specify an entry as the + * most recently touched so we can repair any such + * confusion. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the macro + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 10/13/05 + * + * Modifications: + * + * JRM -- 3/20/06 + * Modified macro to ignore pinned entries. Pinned entries + * do not appear in the data structures maintained by the + * replacement policy code, and thus this macro has nothing + * to do if called for such an entry. + * + * JRM -- 3/28/07 + * Added sanity checks using the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( ! ((entry_ptr)->is_pinned) ) { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list, and re-insert it at the head.\ + */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Use the dirty flag to infer whether the entry is on the clean or \ + * dirty LRU list, and remove it. Then insert it at the head of \ + * the same LRU list. \ + * \ + * At least initially, all entries should be clean. That may \ + * change, so we may as well deal with both cases now. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + } else { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + /* End modified LRU specific code. */ \ + } \ +} /* H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( ! ((entry_ptr)->is_pinned) ) { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list, and re-insert it at the head \ + */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + } \ +} /* H5C__FAKE_RP_FOR_MOST_RECENT_ACCESS */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_EVICTION + * + * Purpose: Update the replacement policy data structures for an + * eviction of the specified cache entry. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the function + * should switch on the current policy and act accordingly. + * + * Return: Non-negative on success/Negative on failure. + * + * Programmer: John Mainzer, 5/10/04 + * + * Modifications: + * + * JRM - 7/27/04 + * Converted the function H5C_update_rp_for_eviction() to the + * macro H5C__UPDATE_RP_FOR_EVICTION in an effort to squeeze + * a bit more performance out of the cache. + * + * At least for the first cut, I am leaving the comments and + * white space in the macro. If they cause dificulties with + * the pre-processor, I'll have to remove them. + * + * JRM - 7/28/04 + * Split macro into two version, one supporting the clean and + * dirty LRU lists, and the other not. Yet another attempt + * at optimization. + * + * JRM - 3/20/06 + * Pinned entries can't be evicted, so this entry should never + * be called on a pinned entry. Added assert to verify this. + * + * JRM -- 3/28/07 + * Added sanity checks for the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( !((entry_ptr)->is_pinned) ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list. */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* If the entry is clean when it is evicted, it should be on the \ + * clean LRU list, if it was dirty, it should be on the dirty LRU list. \ + * Remove it from the appropriate list according to the value of the \ + * dirty flag. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + } else { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ +} /* H5C__UPDATE_RP_FOR_EVICTION */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_EVICTION(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( !((entry_ptr)->is_pinned) ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list. */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ +} /* H5C__UPDATE_RP_FOR_EVICTION */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_FLUSH + * + * Purpose: Update the replacement policy data structures for a flush + * of the specified cache entry. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the function + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 5/6/04 + * + * Modifications: + * + * JRM - 7/27/04 + * Converted the function H5C_update_rp_for_flush() to the + * macro H5C__UPDATE_RP_FOR_FLUSH in an effort to squeeze + * a bit more performance out of the cache. + * + * At least for the first cut, I am leaving the comments and + * white space in the macro. If they cause dificulties with + * pre-processor, I'll have to remove them. + * + * JRM - 7/28/04 + * Split macro into two versions, one supporting the clean and + * dirty LRU lists, and the other not. Yet another attempt + * at optimization. + * + * JRM - 3/20/06 + * While pinned entries can be flushed, they don't reside in + * the replacement policy data structures when unprotected. + * Thus I modified this macro to do nothing if the entry is + * pinned. + * + * JRM - 3/28/07 + * Added sanity checks based on the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_FLUSH(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( ! ((entry_ptr)->is_pinned) ) { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list, and re-insert it at the \ + * head. \ + */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* since the entry is being flushed or cleared, one would think \ + * that it must be dirty -- but that need not be the case. Use the \ + * dirty flag to infer whether the entry is on the clean or dirty \ + * LRU list, and remove it. Then insert it at the head of the \ + * clean LRU list. \ + * \ + * The function presumes that a dirty entry will be either cleared \ + * or flushed shortly, so it is OK if we put a dirty entry on the \ + * clean LRU list. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + } else { \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + } \ +} /* H5C__UPDATE_RP_FOR_FLUSH */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_FLUSH(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( ! ((entry_ptr)->is_pinned) ) { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list, and re-insert it at the \ + * head. \ + */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + } \ +} /* H5C__UPDATE_RP_FOR_FLUSH */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_INSERTION + * + * Purpose: Update the replacement policy data structures for an + * insertion of the specified cache entry. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the function + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 5/17/04 + * + * Modifications: + * + * JRM - 7/27/04 + * Converted the function H5C_update_rp_for_insertion() to the + * macro H5C__UPDATE_RP_FOR_INSERTION in an effort to squeeze + * a bit more performance out of the cache. + * + * At least for the first cut, I am leaving the comments and + * white space in the macro. If they cause dificulties with + * pre-processor, I'll have to remove them. + * + * JRM - 7/28/04 + * Split macro into two version, one supporting the clean and + * dirty LRU lists, and the other not. Yet another attempt + * at optimization. + * + * JRM - 3/10/06 + * This macro should never be called on a pinned entry. + * Inserted an assert to verify this. + * + * JRM - 8/9/06 + * Not any more. We must now allow insertion of pinned + * entries. Updated macro to support this. + * + * JRM - 3/28/07 + * Added sanity checks using the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* insert the entry at the head of the LRU list. */ \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* insert the entry at the head of the clean or dirty LRU list as \ + * appropriate. \ + */ \ + \ + if ( entry_ptr->is_dirty ) { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + } else { \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + /* End modified LRU specific code. */ \ + } \ +} + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* insert the entry at the head of the LRU list. */ \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + } \ +} + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_PROTECT + * + * Purpose: Update the replacement policy data structures for a + * protect of the specified cache entry. + * + * To do this, unlink the specified entry from any data + * structures used by the replacement policy, and add the + * entry to the protected list. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the function + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 5/17/04 + * + * Modifications: + * + * JRM - 7/27/04 + * Converted the function H5C_update_rp_for_protect() to the + * macro H5C__UPDATE_RP_FOR_PROTECT in an effort to squeeze + * a bit more performance out of the cache. + * + * At least for the first cut, I am leaving the comments and + * white space in the macro. If they cause dificulties with + * pre-processor, I'll have to remove them. + * + * JRM - 7/28/04 + * Split macro into two version, one supporting the clean and + * dirty LRU lists, and the other not. Yet another attempt + * at optimization. + * + * JRM - 3/17/06 + * Modified macro to attempt to remove pinned entriese from + * the pinned entry list instead of from the data structures + * maintained by the replacement policy. + * + * JRM - 3/28/07 + * Added sanity checks based on the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_PROTECT(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + HDassert( (cache_ptr)->pel_len >= 0 ); \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list. */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Similarly, remove the entry from the clean or dirty LRU list \ + * as appropriate. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + \ + } else { \ + \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + /* End modified LRU specific code. */ \ + } \ + \ + /* Regardless of the replacement policy, or whether the entry is \ + * pinned, now add the entry to the protected list. \ + */ \ + \ + H5C__DLL_APPEND((entry_ptr), (cache_ptr)->pl_head_ptr, \ + (cache_ptr)->pl_tail_ptr, \ + (cache_ptr)->pl_len, \ + (cache_ptr)->pl_size, (fail_val)) \ +} /* H5C__UPDATE_RP_FOR_PROTECT */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_PROTECT(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + HDassert( (cache_ptr)->pel_len >= 0 ); \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list. */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + } \ + \ + /* Regardless of the replacement policy, or whether the entry is \ + * pinned, now add the entry to the protected list. \ + */ \ + \ + H5C__DLL_APPEND((entry_ptr), (cache_ptr)->pl_head_ptr, \ + (cache_ptr)->pl_tail_ptr, \ + (cache_ptr)->pl_len, \ + (cache_ptr)->pl_size, (fail_val)) \ +} /* H5C__UPDATE_RP_FOR_PROTECT */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_RENAME + * + * Purpose: Update the replacement policy data structures for a + * rename of the specified cache entry. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the function + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 5/17/04 + * + * Modifications: + * + * JRM - 7/27/04 + * Converted the function H5C_update_rp_for_rename() to the + * macro H5C__UPDATE_RP_FOR_RENAME in an effort to squeeze + * a bit more performance out of the cache. + * + * At least for the first cut, I am leaving the comments and + * white space in the macro. If they cause dificulties with + * pre-processor, I'll have to remove them. + * + * JRM - 7/28/04 + * Split macro into two version, one supporting the clean and + * dirty LRU lists, and the other not. Yet another attempt + * at optimization. + * + * JRM - 6/23/05 + * Added the was_dirty parameter. It is possible that + * the entry was clean when it was renamed -- if so it + * it is in the clean LRU regardless of the current + * value of the is_dirty field. + * + * At present, all renamed entries are forced to be + * dirty. This macro is a bit more general that that, + * to allow it to function correctly should that policy + * be relaxed in the future. + * + * JRM - 3/17/06 + * Modified macro to do nothing if the entry is pinned. + * In this case, the entry is on the pinned entry list, not + * in the replacement policy data structures, so there is + * nothing to be done. + * + * JRM - 3/28/07 + * Added sanity checks using the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_RENAME(cache_ptr, entry_ptr, was_dirty, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( ! ((entry_ptr)->is_pinned) ) { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list, and re-insert it at the head. \ + */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* remove the entry from either the clean or dirty LUR list as \ + * indicated by the was_dirty parameter \ + */ \ + if ( was_dirty ) { \ + \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + \ + } else { \ + \ + H5C__AUX_DLL_REMOVE((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + /* insert the entry at the head of either the clean or dirty LRU \ + * list as appropriate. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + \ + } else { \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + /* End modified LRU specific code. */ \ + } \ +} /* H5C__UPDATE_RP_FOR_RENAME */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_RENAME(cache_ptr, entry_ptr, was_dirty, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + if ( ! ((entry_ptr)->is_pinned) ) { \ + \ + /* modified LRU specific code */ \ + \ + /* remove the entry from the LRU list, and re-insert it at the head. \ + */ \ + \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + } \ +} /* H5C__UPDATE_RP_FOR_RENAME */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_SIZE_CHANGE + * + * Purpose: Update the replacement policy data structures for a + * size change of the specified cache entry. + * + * To do this, determine if the entry is pinned. If it is, + * update the size of the pinned entry list. + * + * If it isn't pinned, the entry must handled by the + * replacement policy. Update the appropriate replacement + * policy data structures. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the function + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 8/23/06 + * + * Modifications: + * + * JRM -- 3/28/07 + * Added sanity checks based on the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + HDassert( new_size > 0 ); \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, \ + (entry_ptr)->size, \ + (new_size)); \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* Update the size of the LRU list */ \ + \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, \ + (entry_ptr)->size, \ + (new_size)); \ + \ + /* Similarly, update the size of the clean or dirty LRU list as \ + * appropriate. At present, the entry must be clean, but that \ + * could change. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, \ + (entry_ptr)->size, \ + (new_size)); \ + \ + } else { \ + \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, \ + (entry_ptr)->size, \ + (new_size)); \ + } \ + \ + /* End modified LRU specific code. */ \ + } \ + \ +} /* H5C__UPDATE_RP_FOR_SIZE_CHANGE */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_SIZE_CHANGE(cache_ptr, entry_ptr, new_size) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->size > 0 ); \ + HDassert( new_size > 0 ); \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, \ + (entry_ptr)->size, \ + (new_size)); \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* Update the size of the LRU list */ \ + \ + H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, \ + (entry_ptr)->size, \ + (new_size)); \ + \ + /* End modified LRU specific code. */ \ + } \ + \ +} /* H5C__UPDATE_RP_FOR_SIZE_CHANGE */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_UNPIN + * + * Purpose: Update the replacement policy data structures for an + * unpin of the specified cache entry. + * + * To do this, unlink the specified entry from the protected + * entry list, and re-insert it in the data structures used + * by the current replacement policy. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the macro + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 3/22/06 + * + * Modifications: + * + * JRM -- 3/28/07 + * Added sanity checks based on the new is_read_only and + * ro_ref_count fields of struct H5C_cache_entry_t. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->is_pinned); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + /* Regardless of the replacement policy, remove the entry from the \ + * pinned entry list. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + HDassert( (cache_ptr)->pel_len >= 0 ); \ + \ + /* modified LRU specific code */ \ + \ + /* insert the entry at the head of the LRU list. */ \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Similarly, insert the entry at the head of either the clean or \ + * dirty LRU list as appropriate. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + \ + } else { \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + /* End modified LRU specific code. */ \ + \ +} /* H5C__UPDATE_RP_FOR_UNPIN */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( !((entry_ptr)->is_protected) ); \ + HDassert( !((entry_ptr)->is_read_only) ); \ + HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ + HDassert( (entry_ptr)->is_pinned); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + /* Regardless of the replacement policy, remove the entry from the \ + * pinned entry list. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + HDassert( (cache_ptr)->pel_len >= 0 ); \ + \ + /* modified LRU specific code */ \ + \ + /* insert the entry at the head of the LRU list. */ \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + \ +} /* H5C__UPDATE_RP_FOR_UNPIN */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + +/*------------------------------------------------------------------------- + * + * Macro: H5C__UPDATE_RP_FOR_UNPROTECT + * + * Purpose: Update the replacement policy data structures for an + * unprotect of the specified cache entry. + * + * To do this, unlink the specified entry from the protected + * list, and re-insert it in the data structures used by the + * current replacement policy. + * + * At present, we only support the modified LRU policy, so + * this function deals with that case unconditionally. If + * we ever support other replacement policies, the function + * should switch on the current policy and act accordingly. + * + * Return: N/A + * + * Programmer: John Mainzer, 5/19/04 + * + * Modifications: + * + * JRM - 7/27/04 + * Converted the function H5C_update_rp_for_unprotect() to + * the macro H5C__UPDATE_RP_FOR_UNPROTECT in an effort to + * squeeze a bit more performance out of the cache. + * + * At least for the first cut, I am leaving the comments and + * white space in the macro. If they cause dificulties with + * pre-processor, I'll have to remove them. + * + * JRM - 7/28/04 + * Split macro into two version, one supporting the clean and + * dirty LRU lists, and the other not. Yet another attempt + * at optimization. + * + * JRM - 3/17/06 + * Modified macro to put pinned entries on the pinned entry + * list instead of inserting them in the data structures + * maintained by the replacement policy. + * + *------------------------------------------------------------------------- + */ + +#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS + +#define H5C__UPDATE_RP_FOR_UNPROTECT(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( (entry_ptr)->is_protected); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + /* Regardless of the replacement policy, remove the entry from the \ + * protected list. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pl_head_ptr, \ + (cache_ptr)->pl_tail_ptr, (cache_ptr)->pl_len, \ + (cache_ptr)->pl_size, (fail_val)) \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* insert the entry at the head of the LRU list. */ \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* Similarly, insert the entry at the head of either the clean or \ + * dirty LRU list as appropriate. \ + */ \ + \ + if ( (entry_ptr)->is_dirty ) { \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->dLRU_head_ptr, \ + (cache_ptr)->dLRU_tail_ptr, \ + (cache_ptr)->dLRU_list_len, \ + (cache_ptr)->dLRU_list_size, (fail_val)) \ + \ + } else { \ + \ + H5C__AUX_DLL_PREPEND((entry_ptr), (cache_ptr)->cLRU_head_ptr, \ + (cache_ptr)->cLRU_tail_ptr, \ + (cache_ptr)->cLRU_list_len, \ + (cache_ptr)->cLRU_list_size, (fail_val)) \ + } \ + \ + /* End modified LRU specific code. */ \ + } \ + \ +} /* H5C__UPDATE_RP_FOR_UNPROTECT */ + +#else /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + +#define H5C__UPDATE_RP_FOR_UNPROTECT(cache_ptr, entry_ptr, fail_val) \ +{ \ + HDassert( (cache_ptr) ); \ + HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ + HDassert( (entry_ptr) ); \ + HDassert( (entry_ptr)->is_protected); \ + HDassert( (entry_ptr)->size > 0 ); \ + \ + /* Regardless of the replacement policy, remove the entry from the \ + * protected list. \ + */ \ + H5C__DLL_REMOVE((entry_ptr), (cache_ptr)->pl_head_ptr, \ + (cache_ptr)->pl_tail_ptr, (cache_ptr)->pl_len, \ + (cache_ptr)->pl_size, (fail_val)) \ + \ + if ( (entry_ptr)->is_pinned ) { \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->pel_head_ptr, \ + (cache_ptr)->pel_tail_ptr, \ + (cache_ptr)->pel_len, \ + (cache_ptr)->pel_size, (fail_val)) \ + \ + } else { \ + \ + /* modified LRU specific code */ \ + \ + /* insert the entry at the head of the LRU list. */ \ + \ + H5C__DLL_PREPEND((entry_ptr), (cache_ptr)->LRU_head_ptr, \ + (cache_ptr)->LRU_tail_ptr, \ + (cache_ptr)->LRU_list_len, \ + (cache_ptr)->LRU_list_size, (fail_val)) \ + \ + /* End modified LRU specific code. */ \ + } \ +} /* H5C__UPDATE_RP_FOR_UNPROTECT */ + +#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ + + #endif /* _H5Cpkg_H */ diff --git a/src/H5Cpublic.h b/src/H5Cpublic.h index 7ef959a..0a3742b 100644 --- a/src/H5Cpublic.h +++ b/src/H5Cpublic.h @@ -15,7 +15,7 @@ /*------------------------------------------------------------------------- * - * Created: H5Cproto.h + * Created: H5Cpublic.h * June 4, 2005 * John Mainzer * @@ -667,7 +667,7 @@ done: * to the default. The chunk cache properties in the returned list * are considered to be “set”, and any use of this list will override * the corresponding properties in the file’s file access property - * list. + * list. * * All link access properties in the returned list will be set to the * default values. @@ -1068,20 +1068,20 @@ H5Dset_extent(hid_t dset_id, const hsize_t size[]) { H5D_t *dset; /* Dataset for this operation */ herr_t ret_value = SUCCEED; /* Return value */ - + FUNC_ENTER_API(H5Dset_extent, FAIL) H5TRACE2("e", "i*h", dset_id, size); - + /* Check args */ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") if(!size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified") - + /* Private function */ if(H5D_set_extent(dset, size, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extend dataset") - + done: FUNC_LEAVE_API(ret_value) } /* end H5Dset_extent() */ diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index 5eec112..c11c0e1 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -26,7 +26,6 @@ /* Module Setup */ /****************/ -#define H5B_PACKAGE /*suppress error about including H5Bpkg */ #define H5D_PACKAGE /*suppress error about including H5Dpkg */ @@ -34,7 +33,7 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5Bpkg.h" /* B-link trees */ +#include "H5Bprivate.h" /* B-link trees */ #include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ @@ -42,11 +41,8 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MFprivate.h" /* File space management */ -#include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* Object headers */ -#include "H5Pprivate.h" /* Property lists */ #include "H5Sprivate.h" /* Dataspaces */ -#include "H5SLprivate.h" /* Skip lists */ #include "H5Vprivate.h" /* Vector and array functions */ /****************/ @@ -90,6 +86,12 @@ typedef struct H5D_btree_it_ud_t { void *udata; /* User data for chunk callback routine */ } H5D_btree_it_ud_t; +/* B-tree callback info for debugging */ +typedef struct H5D_btree_dbg_t { + H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */ + unsigned ndims; /* Number of dimensions */ +} H5D_btree_dbg_t; + /********************/ /* Local Prototypes */ @@ -106,10 +108,8 @@ static int H5D_btree_idx_iterate_cb(H5F_t *f, hid_t dxpl_id, const void *left_ke static H5RC_t *H5D_btree_get_shared(const H5F_t *f, const void *_udata); static herr_t H5D_btree_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t, void *_lt_key, void *_udata, void *_rt_key, haddr_t *addr_p /*out*/); -static int H5D_btree_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, - void *_rt_key); -static int H5D_btree_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, - void *_rt_key); +static int H5D_btree_cmp2(void *_lt_key, void *_udata, void *_rt_key); +static int H5D_btree_cmp3(void *_lt_key, void *_udata, void *_rt_key); static htri_t H5D_btree_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_lt_key, void *_udata); static H5B_ins_t H5D_btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, @@ -118,12 +118,12 @@ static H5B_ins_t H5D_btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, static H5B_ins_t H5D_btree_remove( H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key, hbool_t *lt_key_changed, void *_udata, void *_rt_key, hbool_t *rt_key_changed); -static herr_t H5D_btree_decode_key(const H5F_t *f, const H5B_t *bt, - const uint8_t *raw, void *_key); -static herr_t H5D_btree_encode_key(const H5F_t *f, const H5B_t *bt, - uint8_t *raw, void *_key); -static herr_t H5D_btree_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id, - int indent, int fwidth, const void *key, const void *udata); +static herr_t H5D_btree_decode_key(const H5B_shared_t *shared, const uint8_t *raw, + void *_key); +static herr_t H5D_btree_encode_key(const H5B_shared_t *shared, uint8_t *raw, + void *_key); +static herr_t H5D_btree_debug_key(FILE *stream, int indent, int fwidth, + const void *key, const void *udata); /* Chunked layout indexing callbacks */ static herr_t H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info, @@ -192,9 +192,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 */ @@ -233,9 +234,6 @@ H5D_btree_get_shared(const H5F_t UNUSED *f, const void *_udata) HDassert(udata->storage->idx_type == H5D_CHUNK_IDX_BTREE); HDassert(udata->storage->u.btree.shared); - /* Increment reference count on B-tree info */ - H5RC_INC(udata->storage->u.btree.shared); - /* Return the pointer to the ref-count object */ FUNC_LEAVE_NOAPI(udata->storage->u.btree.shared) } /* end H5D_btree_get_shared() */ @@ -334,10 +332,8 @@ done: * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static int -H5D_btree_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, - void *_rt_key) +H5D_btree_cmp2(void *_lt_key, void *_udata, void *_rt_key) { H5D_btree_key_t *lt_key = (H5D_btree_key_t *) _lt_key; H5D_btree_key_t *rt_key = (H5D_btree_key_t *) _rt_key; @@ -385,10 +381,8 @@ H5D_btree_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udat * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static int -H5D_btree_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, - void *_rt_key) +H5D_btree_cmp3(void *_lt_key, void *_udata, void *_rt_key) { H5D_btree_key_t *lt_key = (H5D_btree_key_t *) _lt_key; H5D_btree_key_t *rt_key = (H5D_btree_key_t *) _rt_key; @@ -542,7 +536,7 @@ H5D_btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key, HDassert(rt_key); HDassert(new_node_p); - cmp = H5D_btree_cmp3(f, dxpl_id, lt_key, udata, rt_key); + cmp = H5D_btree_cmp3(lt_key, udata, rt_key); HDassert(cmp <= 0); if(cmp < 0) { @@ -676,19 +670,15 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_btree_decode_key(const H5F_t UNUSED *f, const H5B_t *bt, const uint8_t *raw, void *_key) +H5D_btree_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key) { H5D_btree_key_t *key = (H5D_btree_key_t *) _key; - H5B_shared_t *shared; /* Pointer to shared B-tree info */ size_t ndims; unsigned u; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_decode_key) /* check args */ - HDassert(f); - HDassert(bt); - shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); HDassert(shared); HDassert(raw); HDassert(key); @@ -718,19 +708,15 @@ H5D_btree_decode_key(const H5F_t UNUSED *f, const H5B_t *bt, const uint8_t *raw, *------------------------------------------------------------------------- */ static herr_t -H5D_btree_encode_key(const H5F_t UNUSED *f, const H5B_t *bt, uint8_t *raw, void *_key) +H5D_btree_encode_key(const H5B_shared_t *shared, uint8_t *raw, void *_key) { H5D_btree_key_t *key = (H5D_btree_key_t *) _key; - H5B_shared_t *shared; /* Pointer to shared B-tree info */ size_t ndims; unsigned u; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_encode_key) /* check args */ - HDassert(f); - HDassert(bt); - shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); HDassert(shared); HDassert(raw); HDassert(key); @@ -761,11 +747,11 @@ H5D_btree_encode_key(const H5F_t UNUSED *f, const H5B_t *bt, uint8_t *raw, void */ /* ARGSUSED */ static herr_t -H5D_btree_debug_key(FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, int indent, - int fwidth, const void *_key, const void *_udata) +H5D_btree_debug_key(FILE *stream, int indent, int fwidth, const void *_key, + const void *_udata) { const H5D_btree_key_t *key = (const H5D_btree_key_t *)_key; - const unsigned *ndims = (const unsigned *)_udata; + const H5D_btree_dbg_t *udata = (const H5D_btree_dbg_t *)_udata; unsigned u; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_btree_debug_key) @@ -775,7 +761,7 @@ H5D_btree_debug_key(FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, int ind HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, "Chunk size:", (unsigned)key->nbytes); HDfprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth, "Filter mask:", key->filter_mask); HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Logical offset:"); - for(u = 0; u < *ndims; u++) + for(u = 0; u < udata->ndims; u++) HDfprintf(stream, "%s%Hd", u?", ":"", key->offset[u]); HDfputs("}\n", stream); @@ -1463,7 +1449,7 @@ herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth, unsigned ndims) { - H5D_chunk_common_ud_t udata; /* User data for B-tree callback */ + H5D_btree_dbg_t udata; /* User data for B-tree callback */ H5O_storage_chunk_t storage; /* Storage information for B-tree callback */ hbool_t shared_init = FALSE; /* Whether B-tree shared info is initialized */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1480,9 +1466,10 @@ H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent shared_init = TRUE; /* Set up user data for callback */ - udata.layout = NULL; - udata.storage = &storage; - udata.offset = NULL; + udata.common.layout = NULL; + udata.common.storage = &storage; + udata.common.offset = NULL; + udata.ndims = ndims; /* Dump the records for the B-tree */ (void)H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_BTREE, &udata); diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 296d79a..8e0f387 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -1801,8 +1801,8 @@ done: * * Modification:Raymond Lu * 4 Feb 2009 - * One case that was considered cacheable was when the chunk - * was bigger than the cache size but not allocated on disk. + * One case that was considered cacheable was when the chunk + * was bigger than the cache size but not allocated on disk. * I moved it to uncacheable branch to bypass the cache to * improve performance. *------------------------------------------------------------------------- @@ -2858,7 +2858,9 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache") /* Create a new entry */ - ent = H5FL_MALLOC(H5D_rdcc_ent_t); + if(NULL == (ent = H5FL_MALLOC(H5D_rdcc_ent_t))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, NULL, "can't allocate raw data chunk entry") + ent->locked = 0; ent->dirty = FALSE; ent->chunk_addr = chunk_addr; @@ -3163,10 +3165,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite) +H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite, + hsize_t old_dim[]) { H5D_chk_idx_info_t idx_info; /* Chunked index info */ const H5D_chunk_ops_t *ops = dset->shared->layout.storage.u.chunk.ops; /* Chunk operations */ + hsize_t min_unalloc[H5O_LAYOUT_NDIMS]; /* First chunk in each dimension that is unallocated */ + hsize_t max_unalloc[H5O_LAYOUT_NDIMS]; /* Last chunk in each dimension that is unallocated */ hsize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */ size_t orig_chunk_size; /* Original size of chunk in bytes */ unsigned filter_mask = 0; /* Filter mask for chunks that have them */ @@ -3187,6 +3192,8 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite) hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */ int space_ndims; /* Dataset's space rank */ hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Dataset's dataspace dimensions */ + const uint32_t *chunk_dim = layout->u.chunk.dim; /* Convenience pointer to chunk dimensions */ + int op_dim; /* Current operationg dimension */ H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */ hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */ hid_t data_dxpl_id; /* DXPL ID to use for raw data I/O operations */ @@ -3210,6 +3217,15 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info") space_dim[space_ndims] = layout->u.chunk.dim[space_ndims]; + /* Check if any space dimensions are 0, if so we do not have to do anything + */ + for(op_dim=0; op_dim<space_ndims; op_dim++) + if(space_dim[op_dim] == 0) { + /* Reset any cached chunk info for this dataset */ + H5D_chunk_cinfo_cache_reset(&dset->shared->cache.chunk.last); + HGOTO_DONE(SUCCEED) + } /* end if */ + #ifdef H5_HAVE_PARALLEL /* Retrieve MPI parameters */ if(IS_H5FD_MPI(dset->oloc.file)) { @@ -3294,135 +3310,161 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite) idx_info.layout = &dset->shared->layout.u.chunk; idx_info.storage = &dset->shared->layout.storage.u.chunk; - /* Reset the chunk offset indices */ - HDmemset(chunk_offset, 0, (layout->u.chunk.ndims * sizeof(chunk_offset[0]))); + /* Calculate the minimum and maximum chunk offsets in each dimension */ + for(op_dim=0; op_dim<space_ndims; op_dim++) { + min_unalloc[op_dim] = ((old_dim[op_dim] + chunk_dim[op_dim] - 1) + / chunk_dim[op_dim]) * chunk_dim[op_dim]; + if(space_dim[op_dim] == 0) + max_unalloc[op_dim] = 0; + else + max_unalloc[op_dim] = ((space_dim[op_dim] - 1) / chunk_dim[op_dim]) + * chunk_dim[op_dim]; + } /* end for */ /* Loop over all chunks */ - carry = FALSE; - while(!carry) { + /* The algorithm is: + * For each dimension: + * -Allocate all chunks in the new dataspace that are beyond the original + * dataspace in the operating dimension, except those that have already + * been allocated. + * + * This is accomplished mainly using the min_unalloc and max_unalloc arrays. + * min_unalloc represents the lowest offset in each dimension of chunks that + * have not been allocated (whether or not they need to be). max_unalloc + * represents the highest offset in each dimension of chunks in the new + * dataset that have not been allocated by this routine (they may have been + * allocated previously). + * + * Every time the algorithm finishes allocating chunks allocated beyond a + * certain dimension, max_unalloc is updated in order to avoid allocating + * those chunks again. + */ + for(op_dim=0; op_dim<space_ndims; op_dim++) { H5D_chunk_ud_t udata; /* User data for querying chunk info */ int i; /* Local index variable */ - /* Get the chunk's info */ - if(H5D_chunk_get_info(dset, dxpl_id, chunk_offset, &udata) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address") - - /* Check if the chunk exists yet on disk */ - if(!H5F_addr_defined(udata.addr)) { - const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Raw data chunk cache */ - H5D_rdcc_ent_t *ent; /* Cache entry */ - hbool_t chunk_exists; /* Flag to indicate whether a chunk exists already */ - unsigned u; /* Local index variable */ - - /* Didn't find the chunk on disk */ - chunk_exists = FALSE; - - /* Look for chunk in cache */ - for(ent = rdcc->head; ent && !chunk_exists; ent = ent->next) { - /* Assume a match */ - chunk_exists = TRUE; - for(u = 0; u < layout->u.chunk.ndims; u++) - if(ent->offset[u] != chunk_offset[u]) { - chunk_exists = FALSE; /* Reset if no match */ - break; - } /* end if */ - } /* end for */ - - /* Chunk wasn't in cache either, create it now */ - if(!chunk_exists) { - size_t chunk_size; /* Size of chunk in bytes, possibly filtered */ - - /* Check for VL datatype & non-default fill value */ - if(fb_info_init && fb_info.has_vlen_fill_type) { - /* Sanity check */ - HDassert(should_fill); + /* Check if allocation along this dimension is really necessary */ + if(min_unalloc[op_dim] > max_unalloc[op_dim]) + carry = TRUE; + else { + /* Reset the chunk offset indices */ + HDmemset(chunk_offset, 0, (layout->u.chunk.ndims * sizeof(chunk_offset[0]))); + chunk_offset[op_dim] = min_unalloc[op_dim]; - /* Fill the buffer with VL datatype fill values */ - if(H5D_fill_refill_vl(&fb_info, fb_info.elmts_per_buf, data_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't refill fill value buffer") + carry = FALSE; + } /* end if */ - /* Check if there are filters which need to be applied to the chunk */ - if(pline->nused > 0) { - size_t buf_size = orig_chunk_size; - size_t nbytes = fb_info.fill_buf_size; + while(!carry) { + size_t chunk_size; /* Size of chunk in bytes, possibly filtered */ - /* Push the chunk through the filters */ - if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &nbytes, &buf_size, &fb_info.fill_buf) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed") +#ifndef NDEBUG + /* None of the chunks should be allocated */ + if(H5D_chunk_get_info(dset, dxpl_id, chunk_offset, &udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address") + HDassert(!H5F_addr_defined(udata.addr)); +#endif /* NDEBUG */ + + /* Check for VL datatype & non-default fill value */ + if(fb_info_init && fb_info.has_vlen_fill_type) { + /* Sanity check */ + HDassert(should_fill); + + /* Fill the buffer with VL datatype fill values */ + if(H5D_fill_refill_vl(&fb_info, fb_info.elmts_per_buf, data_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't refill fill value buffer") + + /* Check if there are filters which need to be applied to the chunk */ + if(pline->nused > 0) { + size_t buf_size = orig_chunk_size; + size_t nbytes = fb_info.fill_buf_size; + + /* Push the chunk through the filters */ + if(H5Z_pipeline(pline, 0, &filter_mask, dxpl_cache->err_detect, dxpl_cache->filter_cb, &nbytes, &buf_size, &fb_info.fill_buf) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed") #if H5_SIZEOF_SIZE_T > 4 - /* Check for the chunk expanding too much to encode in a 32-bit value */ - if(nbytes > ((size_t)0xffffffff)) - HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length") + /* Check for the chunk expanding too much to encode in a 32-bit value */ + if(nbytes > ((size_t)0xffffffff)) + HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length") #endif /* H5_SIZEOF_SIZE_T > 4 */ - /* Keep the number of bytes the chunk turned in to */ - chunk_size = nbytes; - } /* end if */ - else - H5_ASSIGN_OVERFLOW(chunk_size, layout->u.chunk.size, uint32_t, size_t); + /* Keep the number of bytes the chunk turned in to */ + chunk_size = nbytes; } /* end if */ else - chunk_size = orig_chunk_size; - - /* Initialize the chunk information */ - udata.common.layout = &layout->u.chunk; - udata.common.storage = &layout->storage.u.chunk; - udata.common.offset = chunk_offset; - H5_ASSIGN_OVERFLOW(udata.nbytes, chunk_size, size_t, uint32_t); - udata.filter_mask = filter_mask; - udata.addr = HADDR_UNDEF; - - /* Allocate the chunk with all processes */ - if((ops->insert)(&idx_info, &udata) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert record into chunk index") - HDassert(H5F_addr_defined(udata.addr)); - - /* Check if fill values should be written to chunks */ - if(should_fill) { - /* Sanity check */ - HDassert(fb_info_init); - HDassert(udata.nbytes == chunk_size); + H5_ASSIGN_OVERFLOW(chunk_size, layout->u.chunk.size, uint32_t, size_t); + } /* end if */ + else + chunk_size = orig_chunk_size; + + /* Initialize the chunk information */ + udata.common.layout = &layout->u.chunk; + udata.common.storage = &layout->storage.u.chunk; + udata.common.offset = chunk_offset; + H5_ASSIGN_OVERFLOW(udata.nbytes, chunk_size, size_t, uint32_t); + udata.filter_mask = filter_mask; + udata.addr = HADDR_UNDEF; + + /* Allocate the chunk with all processes */ + if((ops->insert)(&idx_info, &udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert record into chunk index") + HDassert(H5F_addr_defined(udata.addr)); + + /* Check if fill values should be written to chunks */ + if(should_fill) { + /* Sanity check */ + HDassert(fb_info_init); + HDassert(udata.nbytes == chunk_size); #ifdef H5_HAVE_PARALLEL - /* Check if this file is accessed with an MPI-capable file driver */ - if(using_mpi) { - /* Write the chunks out from only one process */ - /* !! Use the internal "independent" DXPL!! -QAK */ - if(H5_PAR_META_WRITE == mpi_rank) - if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, chunk_size, data_dxpl_id, fb_info.fill_buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file") - - /* Indicate that blocks are being written */ - blocks_written = TRUE; - } /* end if */ - else { -#endif /* H5_HAVE_PARALLEL */ + /* Check if this file is accessed with an MPI-capable file driver */ + if(using_mpi) { + /* Write the chunks out from only one process */ + /* !! Use the internal "independent" DXPL!! -QAK */ + if(H5_PAR_META_WRITE == mpi_rank) if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, chunk_size, data_dxpl_id, fb_info.fill_buf) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file") + + /* Indicate that blocks are being written */ + blocks_written = TRUE; + } /* end if */ + else { +#endif /* H5_HAVE_PARALLEL */ + if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, chunk_size, data_dxpl_id, fb_info.fill_buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file") #ifdef H5_HAVE_PARALLEL - } /* end else */ + } /* end else */ #endif /* H5_HAVE_PARALLEL */ - } /* end if */ - - /* Release the fill buffer if we need to re-allocate it each time */ - if(fb_info_init && fb_info.has_vlen_fill_type && pline->nused > 0) - H5D_fill_release(&fb_info); } /* end if */ - } /* end if */ - /* Increment indices */ - carry = TRUE; - for(i = (int)(space_ndims - 1); i >= 0; --i) { - chunk_offset[i] += layout->u.chunk.dim[i]; - if(chunk_offset[i] >= space_dim[i]) - chunk_offset[i] = 0; - else { - carry = FALSE; - break; - } /* end else */ - } /* end for */ - } /* end while */ + /* Release the fill buffer if we need to re-allocate it each time */ + if(fb_info_init && fb_info.has_vlen_fill_type && pline->nused > 0) + H5D_fill_release(&fb_info); + + /* Increment indices */ + carry = TRUE; + for(i = (int)(space_ndims - 1); i >= 0; --i) { + chunk_offset[i] += chunk_dim[i]; + if(chunk_offset[i] > max_unalloc[i]) + if(i == op_dim) + chunk_offset[i] = min_unalloc[i]; + else + chunk_offset[i] = 0; + else { + carry = FALSE; + break; + } /* end else */ + } /* end for */ + } /* end while(!carry) */ + + /* Adjust max_unalloc_dim_idx so we don't allocate the same chunk twice. + * Also check if this dimension started from 0 (and hence allocated all + * of the chunks. */ + if(min_unalloc[op_dim] == 0) + break; + else + max_unalloc[op_dim] = min_unalloc[op_dim] - chunk_dim[op_dim]; + } /* end for(op_dim=0...) */ #ifdef H5_HAVE_PARALLEL /* Only need to block at the barrier if we actually initialized a chunk */ @@ -3508,7 +3550,7 @@ H5D_chunk_prune_fill(const H5D_chunk_rec_t *chunk_rec, H5D_chunk_it_ud1_t *udata /* Calculate the index of this chunk */ if(H5V_chunk_index(rank, chunk_rec->offset, layout->u.chunk.dim, layout->u.chunk.down_chunks, &io_info->store->chunk.index) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5_ITER_ERROR, "can't get chunk index") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index") /* Lock the chunk into the cache, to get a pointer to the chunk buffer */ /* (Casting away const OK -QAK) */ @@ -3638,7 +3680,7 @@ H5D_chunk_prune_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, H5_ITER_ERROR, "unable to write fill value") done: - /* It is currently impossible to fail after the stack node has been + /* It is currently impossible to fail after the stack node has been * malloc'ed. No need to free it here on failure. */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_chunk_prune_cb() */ @@ -3873,7 +3915,7 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims) if(needs_fill) { /* Allocate space for the stack node */ if(NULL == (tmp_stack = H5FL_MALLOC(H5D_chunk_prune_stack_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for stack node") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for stack node") /* Set up chunk record for fill routine */ tmp_stack->rec.nbytes = dset->shared->layout.u.chunk.size; @@ -3893,7 +3935,7 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims) while(tmp_stack) { /* Write the fill value */ if(H5D_chunk_prune_fill(&(tmp_stack->rec), &udata) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, H5_ITER_ERROR, "unable to write fill value") + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write fill value") /* Advance the stack pointer */ tmp_stack = tmp_stack->next; @@ -3914,7 +3956,7 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims) /* Remove the chunk from disk */ if((layout->storage.u.chunk.ops->remove)(&idx_info, &idx_udata) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, H5_ITER_ERROR, "unable to remove chunk entry from index") + HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to remove chunk entry from index") /* Advance the stack pointer */ tmp_stack = tmp_stack->next; @@ -4262,7 +4304,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) else if((H5T_get_class(udata->dt_src, FALSE) == H5T_REFERENCE) && (udata->file_src != udata->idx_info_dst->f)) fix_ref = TRUE; else - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy dataset elements") + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy dataset elements") } /* end if */ /* Check for filtered chunks */ @@ -4346,7 +4388,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) /* Copy the reference elements */ if(H5O_copy_expand_ref(udata->file_src, buf, udata->idx_info_dst->dxpl_id, udata->idx_info_dst->f, bkg, ref_count, H5T_get_ref_type(udata->dt_src), udata->cpy_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy reference attribute") } /* end if */ /* After fix ref, copy the new reference elements to the buffer to write out */ @@ -4368,7 +4410,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) #if H5_SIZEOF_SIZE_T > 4 /* Check for the chunk expanding too much to encode in a 32-bit value */ if(nbytes > ((size_t)0xffffffff)) - HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk too large for 32-bit length") + HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, H5_ITER_ERROR, "chunk too large for 32-bit length") #endif /* H5_SIZEOF_SIZE_T > 4 */ H5_ASSIGN_OVERFLOW(udata_dst.nbytes, nbytes, size_t, uint32_t); udata->buf = buf; @@ -4377,7 +4419,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) /* Insert chunk into the destination index */ if((udata->idx_info_dst->storage->ops->insert)(udata->idx_info_dst, &udata_dst) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert chunk into index") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5_ITER_ERROR, "unable to insert chunk into index") /* Write chunk data to destination file */ HDassert(H5F_addr_defined(udata_dst.addr)); @@ -4955,9 +4997,9 @@ done: * Function: H5D_nonexistent_readvv * * Purpose: When the chunk doesn't exist on disk and the chunk is bigger - * than the cache size, performs fill value I/O operation on - * memory buffer, advancing through two I/O vectors, until one - * runs out. + * than the cache size, performs fill value I/O operation on + * memory buffer, advancing through two I/O vectors, until one + * runs out. * * Note: This algorithm is pretty inefficient about initializing and * terminating the fill buffer info structure and it would be @@ -5013,7 +5055,7 @@ H5D_nonexistent_readvv(const H5D_io_info_t *io_info, HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill buffer info") fb_info_init = TRUE; - /* Check for VL datatype & fill the buffer with VL datatype fill values */ + /* Check for VL datatype & fill the buffer with VL datatype fill values */ if(fb_info.has_vlen_fill_type && H5D_fill_refill_vl(&fb_info, fb_info.elmts_per_buf, io_info->dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't refill fill value buffer") diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index e2fe420..7c1b87c 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -217,8 +217,8 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id) store.contig.dset_size = dset->shared->layout.storage.u.contig.size; /* Get the number of elements in the dataset's dataspace */ - snpoints = H5S_GET_EXTENT_NPOINTS(dset->shared->space); - HDassert(snpoints >= 0); + if((snpoints = H5S_GET_EXTENT_NPOINTS(dset->shared->space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "dataset has negative number of elements") H5_ASSIGN_OVERFLOW(npoints, snpoints, hssize_t, size_t); /* Initialize the fill value buffer */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 637cb70..923b888 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -319,6 +319,8 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id) { htri_t changed; /* Flag to indicate that the dataspace was successfully extended */ H5S_t *space; /* Dataset's dataspace */ + int rank; /* Dataspace # of dimensions */ + hsize_t curr_dims[H5O_LAYOUT_NDIMS];/* Current dimension sizes */ H5O_fill_t *fill; /* Dataset's fill value */ herr_t ret_value = SUCCEED; /* Return value */ @@ -338,8 +340,12 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id) * able to muck things up. */ - /* Increase the size of the data space */ + /* Retrieve the current dimensions */ space = dataset->shared->space; + if((rank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions") + + /* Increase the size of the data space */ if((changed = H5S_extend(space, size)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to increase size of data space") @@ -356,7 +362,8 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id) /* Allocate space for the new parts of the dataset, if appropriate */ fill = &dataset->shared->dcpl_cache.fill; if(fill->alloc_time == H5D_ALLOC_TIME_EARLY) - if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_EXTEND, FALSE) < 0) + if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_EXTEND, FALSE, + curr_dims) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value") /* Mark the dataspace as dirty, for later writing to the file */ diff --git a/src/H5Dint.c b/src/H5Dint.c index da73890..228fe83 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -29,6 +29,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5FOprivate.h" /* File objects */ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ @@ -56,7 +57,8 @@ typedef struct { /********************/ /* General stuff */ -static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite, hid_t dxpl_id); +static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite, + hsize_t old_dim[], hid_t dxpl_id); static herr_t H5D_get_dxpl_cache_real(hid_t dxpl_id, H5D_dxpl_cache_t *cache); static H5D_shared_t *H5D_new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type); @@ -1305,7 +1307,7 @@ H5D_open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id) if((H5F_INTENT(dataset->oloc.file) & H5F_ACC_RDWR) && !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage) && IS_H5FD_MPI(dataset->oloc.file)) { - if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_OPEN, FALSE) < 0) + if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_OPEN, FALSE, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file storage") } /* end if */ @@ -1313,17 +1315,19 @@ done: if(ret_value < 0) { if(H5F_addr_defined(dataset->oloc.addr) && H5O_close(&(dataset->oloc)) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header") - if(dataset->shared->space && H5S_close(dataset->shared->space) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") - if(dataset->shared->type) { - if(dataset->shared->type_id > 0) { - if(H5I_dec_ref(dataset->shared->type_id, FALSE) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + if(dataset->shared) { + if(dataset->shared->space && H5S_close(dataset->shared->space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") + if(dataset->shared->type) { + if(dataset->shared->type_id > 0) { + if(H5I_dec_ref(dataset->shared->type_id, FALSE) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + } /* end if */ + else { + if(H5T_close(dataset->shared->type) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + } /* end else */ } /* end if */ - else { - if(H5T_close(dataset->shared->type) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") - } /* end else */ } /* end if */ } /* end if */ @@ -1560,7 +1564,7 @@ H5D_typeof(const H5D_t *dset) */ herr_t H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_alloc, - hbool_t full_overwrite) + hbool_t full_overwrite, hsize_t old_dim[]) { H5F_t *f = dset->oloc.file; /* The dataset's file pointer */ H5O_layout_t *layout; /* The dataset's layout information */ @@ -1655,7 +1659,7 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al * this is icky. -QAK */ if(!(dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR && time_alloc == H5D_ALLOC_WRITE)) - if(H5D_init_storage(dset, full_overwrite, dxpl_id) < 0) + if(H5D_init_storage(dset, full_overwrite, old_dim, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value") } /* end if */ else { @@ -1669,7 +1673,7 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al * the fill value _is_ set, do that now */ if(dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC || (dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET && fill_status == H5D_FILL_VALUE_USER_DEFINED)) { - if(H5D_init_storage(dset, full_overwrite, dxpl_id) < 0) + if(H5D_init_storage(dset, full_overwrite, old_dim, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value") } /* end if */ } /* end else */ @@ -1706,7 +1710,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_init_storage(H5D_t *dset, hbool_t full_overwrite, hid_t dxpl_id) +H5D_init_storage(H5D_t *dset, hbool_t full_overwrite, hsize_t old_dim[], + hid_t dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1737,9 +1742,17 @@ H5D_init_storage(H5D_t *dset, hbool_t full_overwrite, hid_t dxpl_id) * Allocate file space * for all chunks now and initialize each chunk with the fill value. */ - if(H5D_chunk_allocate(dset, dxpl_id, full_overwrite) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset") - break; + { + hsize_t zero_dim[H5O_LAYOUT_NDIMS] = {0}; + + /* Use zeros for old dimensions if not specified */ + if(old_dim == NULL) + old_dim = zero_dim; + + if(H5D_chunk_allocate(dset, dxpl_id, full_overwrite, old_dim) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset") + break; + } /* end block */ default: HDassert("not implemented yet" && 0); @@ -2113,7 +2126,7 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "dataset has compact storage") if(H5D_CONTIGUOUS == dset->shared->layout.type && 0 == dset->shared->dcpl_cache.efl.nused) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "dataset has contiguous storage") - + /* Check if the filters in the DCPL will need to encode, and if so, can they? */ if(H5D_check_filters(dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't apply filters") @@ -2157,14 +2170,13 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) /* Allocate space for the new parts of the dataset, if appropriate */ if(expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY) - if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_EXTEND, FALSE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset storage") - + if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_EXTEND, FALSE, curr_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to extend dataset storage") /*------------------------------------------------------------------------- * Remove chunk information in the case of chunked datasets * This removal takes place only in case we are shrinking the dateset - * and if the chunks are written + * and if the chunks are written *------------------------------------------------------------------------- */ if(shrink && H5D_CHUNKED == dset->shared->layout.type && @@ -2281,7 +2293,7 @@ H5D_flush_real(H5D_t *dataset, hid_t dxpl_id) } /* end if */ /* Flush cached raw data for each kind of dataset layout */ - if(dataset->shared->layout.ops->flush && + if(dataset->shared->layout.ops->flush && (dataset->shared->layout.ops->flush)(dataset, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush raw data") diff --git a/src/H5Dio.c b/src/H5Dio.c index 5723847..d3120b1 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -549,7 +549,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, full_overwrite = (hbool_t)((hsize_t)file_nelmts == nelmts ? TRUE : FALSE); /* Allocate storage */ - if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_WRITE, full_overwrite) < 0) + if(H5D_alloc_storage(dataset, dxpl_id, H5D_ALLOC_WRITE, full_overwrite, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") } /* end if */ diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index c76bfc8..0a5fc6e 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -390,7 +390,7 @@ H5D_layout_oh_create(H5F_t *file, hid_t dxpl_id, H5O_t *oh, H5D_t *dset, * allocation until later. */ if(fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY) - if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_CREATE, FALSE) < 0) + if(H5D_alloc_storage(dset, dxpl_id, H5D_ALLOC_CREATE, FALSE, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") /* Update external storage message, if it's used */ diff --git a/src/H5Doh.c b/src/H5Doh.c index 30f1829..de4fb17 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -369,6 +369,11 @@ static herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) { H5O_layout_t layout; /* Data storage layout message */ + H5O_pline_t pline; /* I/O pipeline message */ + H5O_efl_t efl; /* External File List message */ + hbool_t layout_read = FALSE; /* Whether the layout message was read */ + hbool_t pline_read = FALSE; /* Whether the I/O pipeline message was read */ + hbool_t efl_read = FALSE; /* Whether the external file list message was read */ htri_t exists; /* Flag if header message of interest exists */ herr_t ret_value = SUCCEED; /* Return value */ @@ -382,6 +387,7 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) /* Get the layout message from the object header */ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_LAYOUT_ID, &layout)) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find layout message") + layout_read = TRUE; /* Check for newer version of the layout message, which indicates that some * information is stored in the 'storage' message. @@ -394,14 +400,13 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) /* Check for chunked dataset storage */ if(layout.type == H5D_CHUNKED && H5D_chunk_is_space_alloc(&layout.storage)) { - H5O_pline_t pline; /* I/O pipeline message */ - /* Check for I/O pipeline message */ if((exists = H5O_msg_exists_oh(oh, H5O_PLINE_ID)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header") else if(exists) { if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_PLINE_ID, &pline)) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find I/O pipeline message") + pline_read = TRUE; } /* end else if */ else HDmemset(&pline, 0, sizeof(pline)); @@ -415,14 +420,13 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "unable to check for EFL message") if(exists && H5D_efl_is_space_alloc(&layout.storage)) { - H5O_efl_t efl; /* External File List message */ - /* Start with clean EFL info */ HDmemset(&efl, 0, sizeof(efl)); /* Get External File List message from the object header */ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_EFL_ID, &efl)) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find EFL message") + efl_read = TRUE; /* Get size of local heap for EFL message's file list */ if(H5D_efl_bh_info(f, dxpl_id, &efl, &(bh_info->heap_size)) < 0) @@ -430,6 +434,14 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) } /* end if */ done: + /* Free messages, if they've been read in */ + if(layout_read && H5O_msg_reset(H5O_LAYOUT_ID, &layout) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset data storage layout message") + if(pline_read && H5O_msg_reset(H5O_PLINE_ID, &pline) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset I/O pipeline message") + if(efl_read && H5O_msg_reset(H5O_EFL_ID, &efl) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset external file list message") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_dset_bh_info() */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 3e03ffd..68b5835 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -32,6 +32,7 @@ #include "H5Dprivate.h" /* Other private headers needed by this file */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Gprivate.h" /* Groups */ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatypes */ @@ -557,7 +558,7 @@ H5_DLL H5D_t *H5D_create_named(const H5G_loc_t *loc, const char *name, H5_DLL herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id); H5_DLL herr_t H5D_alloc_storage(H5D_t *dset, hid_t dxpl_id, H5D_time_alloc_t time_alloc, - hbool_t full_overwrite); + hbool_t full_overwrite, hsize_t old_dim[]); H5_DLL hsize_t H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id); H5_DLL haddr_t H5D_get_offset(const H5D_t *dset); H5_DLL herr_t H5D_iterate(void *buf, hid_t type_id, const H5S_t *space, @@ -643,7 +644,8 @@ H5_DLL herr_t H5D_chunk_unlock(const H5D_io_info_t *io_info, H5_DLL herr_t H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t *dxpl_cache, H5D_rdcc_ent_t *ent, hbool_t reset); H5_DLL herr_t H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes); -H5_DLL herr_t H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite); +H5_DLL herr_t H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, + hbool_t full_overwrite, hsize_t old_dim[]); H5_DLL herr_t H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims); #ifdef H5_HAVE_PARALLEL diff --git a/src/H5Dproxy.c b/src/H5Dproxy.c index 592bdaf..da5ef0a 100644 --- a/src/H5Dproxy.c +++ b/src/H5Dproxy.c @@ -46,6 +46,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Dpkg.h" /* Dataset functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5MFprivate.h" /* File memory management */ @@ -560,7 +560,7 @@ if(sblock->dblk_npages) /* Compute data block page address */ dblk_page_addr = sblock->dblk_addrs[dblk_idx] + - H5EA_DBLOCK_PREFIX_SIZE(sblock) + + H5EA_DBLOCK_PREFIX_SIZE(sblock) + (page_idx * sblock->dblk_page_size); #ifdef QAK HDfprintf(stderr, "%s: sblock->addr = %a\n", FUNC, sblock->addr); diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c index 6967413..45bb498 100644 --- a/src/H5EAhdr.c +++ b/src/H5EAhdr.c @@ -411,7 +411,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); dblk_nelmts = H5EA_SBLK_DBLK_NELMTS(sblk_idx, cparam->data_blk_min_elmts); if(dblk_page_nelmts < dblk_nelmts) H5E_THROW(H5E_BADVALUE, "max. # of elements per data block page bits must be > # of elements in first data block from super block") - + if(cparam->max_dblk_page_nelmts_bits > cparam->max_nelmts_bits) H5E_THROW(H5E_BADVALUE, "max. # of elements per data block page bits must be <= max. # of elements bits") } @@ -71,7 +71,7 @@ static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, char ** /*out*/ actual_name); -static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id); +static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush); static herr_t H5F_close(H5F_t *f); /* Declare a free list to manage the H5F_t struct */ @@ -374,8 +374,8 @@ done: * Modification: * Raymond Lu * 24 September 2008 - * Changed the return value to ssize_t to accommadate - * potential large number of objects. + * Changed the return value to ssize_t to accommadate + * potential large number of objects. * *------------------------------------------------------------------------- */ @@ -415,8 +415,8 @@ done: * Modification: * Raymond Lu * 24 September 2008 - * Changed the return value to size_t to accommadate - * potential large number of objects. + * Changed the return value to size_t to accommadate + * potential large number of objects. * *------------------------------------------------------------------------- */ @@ -447,8 +447,8 @@ H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref) * Modification: * Raymond Lu * 24 September 2008 - * Changed the return value to ssize_t and MAX_OBJTS to size_t to - * accommadate potential large number of objects. + * Changed the return value to ssize_t and MAX_OBJTS to size_t to + * accommadate potential large number of objects. * *------------------------------------------------------------------------- */ @@ -466,7 +466,7 @@ H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list) if(0 == (types & H5F_OBJ_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type") HDassert(oid_list); - + /* H5F_get_objects doesn't fail */ ret_value = (ssize_t)H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE); @@ -489,7 +489,7 @@ done: * Raymond Lu * 24 September 2008 * Changed the return value and MAX_OBJTS to size_t to accommadate - * potential large number of objects. + * potential large number of objects. * *------------------------------------------------------------------------- */ @@ -546,7 +546,7 @@ H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_ } /* end else */ /* Search through file IDs to count the number, and put their - * IDs on the object list. H5I_search returns NULL if no object + * IDs on the object list. H5I_search returns NULL if no object * is found, so don't return failure in this function. */ if(types & H5F_OBJ_FILE) { olist.obj_type = H5I_FILE; @@ -633,7 +633,7 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) (*olist->obj_id_count)++; /* Check if we've filled up the array. Return TRUE only if - * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * we have filled up the array. Otherwise return FALSE(RET_VALUE is * preset to FALSE) because H5I_search needs the return value of FALSE * to continue searching. */ if(olist->max_index>0 && olist->list_index>=olist->max_index) @@ -686,7 +686,7 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) (*olist->obj_id_count)++; /* Check if we've filled up the array. Return TRUE only if - * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * we have filled up the array. Otherwise return FALSE(RET_VALUE is * preset to FALSE) because H5I_search needs the return value of FALSE * to continue searching. */ if(olist->max_index>0 && olist->list_index>=olist->max_index) @@ -967,7 +967,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5F_dest(H5F_t *f, hid_t dxpl_id) +H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) { herr_t ret_value = SUCCEED; /* Return value */ @@ -978,17 +978,16 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) HDassert(f->shared); if(1 == f->shared->nrefs) { - /* Flush at this point since the file will be closed */ - /* (Only try to flush here if the file structure was successfully - * initialized (i.e., the file struct is being shutdown in an - * orderly manner with the 'closing' flag set) + /* Flush at this point since the file will be closed. + * Only try to flush the file if it was opened with write access, and if + * the caller requested a flush. */ - if(f->closing) { -#if H5AC_DUMP_STATS_ON_CLOSE - /* Dump debugging info */ - H5AC_stats(f); -#endif /* H5AC_DUMP_STATS_ON_CLOSE */ + if((f->shared->flags & H5F_ACC_RDWR) && flush) + if(H5F_flush(f, dxpl_id) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + /* Release objects that depend on the superblock being initialized */ + if(f->shared->sblock) { /* Shutdown file free space manager(s) */ /* (We should release the free space information now (before truncating * the file and before the metadata cache is shut down) since the @@ -1008,7 +1007,7 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") f->shared->sblock = NULL; } /* end if */ - + /* Remove shared file struct from list of open files */ if(H5F_sfile_remove(f->shared) < 0) /* Push error, but keep going*/ @@ -1330,7 +1329,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, done: if(!ret_value && file) - if(H5F_dest(file, dxpl_id) < 0) + if(H5F_dest(file, dxpl_id, FALSE) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") FUNC_LEAVE_NOAPI(ret_value) @@ -1879,24 +1878,16 @@ H5F_try_close(H5F_t *f) if(H5F_close_mounts(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files") - /* Flush at this point since the file will be closed. Don't invalidate - * the cache, since this file might still be open using another handle. - * However, make sure we flush in case that handle is read-only; its - * copy of the cache needs to be clean. - * Only try to flush the file if it was opened with write access. - */ - if(f->intent & H5F_ACC_RDWR) { - /* Flush all caches */ - if(H5F_flush(f, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - } /* end if */ + /* Delay flush until the shared file struct is closed, in H5F_dest. If the + * application called H5Fclose, it would have been flushed in that function + * (unless it will have been flushed in H5F_dest anyways). */ /* * Destroy the H5F_t struct and decrement the reference count for the * shared H5F_file_t struct. If the reference count for the H5F_file_t * struct reaches zero then destroy it also. */ - if(H5F_dest(f, H5AC_dxpl_id) < 0) + if(H5F_dest(f, H5AC_dxpl_id, TRUE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") done: @@ -1928,6 +1919,8 @@ done: herr_t H5Fclose(hid_t file_id) { + H5F_t *f = NULL; + int nref; herr_t ret_value = SUCCEED; FUNC_ENTER_API(H5Fclose, FAIL) @@ -1937,6 +1930,20 @@ H5Fclose(hid_t file_id) if(H5I_FILE != H5I_get_type(file_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + /* Flush file if this is the last reference to this id and we have write + * intent, unless it will be flushed by the "shared" file being closed. + * This is only necessary to replicate previous behaviour, and could be + * disabled by an option/property to improve performance. */ + if(NULL == (f = (H5F_t *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + if((f->shared->nrefs > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { + if((nref = H5I_get_ref(file_id, FALSE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") + if(nref == 1) + if(H5F_flush(f, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + } /* end if */ + /* * Decrement reference count on atom. When it reaches zero the file will * be closed. @@ -2004,7 +2011,7 @@ H5Freopen(hid_t file_id) done: if(ret_value < 0 && new_file) - if(H5F_dest(new_file, H5AC_dxpl_id) < 0) + if(H5F_dest(new_file, H5AC_dxpl_id, FALSE) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") FUNC_LEAVE_API(ret_value) @@ -2861,7 +2868,7 @@ H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) /* Set version # fields */ finfo->super.version = f->shared->sblock->super_vers; finfo->sohm.version = f->shared->sohm_vers; - finfo->free.version = HDF5_FREESPACE_VERSION; + finfo->free.version = HDF5_FREESPACE_VERSION; done: FUNC_LEAVE_API(ret_value) @@ -29,7 +29,7 @@ /* Module Declaration */ /**********************/ -#define H5FA_MODULE +#define H5FA_MODULE /***********************/ /* Other Packages Used */ @@ -702,7 +702,7 @@ herr_t, SUCCEED, FAIL, H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata)) /* Local variables */ - uint8_t *elmt = NULL; + uint8_t *elmt = NULL; hsize_t u; /* diff --git a/src/H5FAcache.c b/src/H5FAcache.c index 3488531..9fa9941 100644 --- a/src/H5FAcache.c +++ b/src/H5FAcache.c @@ -218,8 +218,8 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *u /* General array creation/configuration information */ hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */ - hdr->cparam.max_dblk_page_nelmts_bits = *p++; /* Log2(Max. # of elements in data block page) - - i.e. # of bits needed to store max. # of + hdr->cparam.max_dblk_page_nelmts_bits = *p++; /* Log2(Max. # of elements in data block page) - + i.e. # of bits needed to store max. # of elements in data block page. */ /* Array statistics */ @@ -790,7 +790,7 @@ H5FA__cache_dblock_size(const H5F_t UNUSED *f, const H5FA_dblock_t *dblock, else *size_ptr = H5FA_DBLOCK_PREFIX_SIZE(dblock); -END_FUNC(STATIC) /* end H5FA__cache_dblock_size() */ +END_FUNC(STATIC) /* end H5FA__cache_dblock_size() */ /*------------------------------------------------------------------------- diff --git a/src/H5FAdblkpage.c b/src/H5FAdblkpage.c index dde299f..a1bd90e 100644 --- a/src/H5FAdblkpage.c +++ b/src/H5FAdblkpage.c @@ -168,7 +168,7 @@ HDfprintf(stderr, "%s: Called, addr = %a\n", FUNC, addr); /* Set info about data block page on disk */ dblk_page->addr = addr; dblk_page->size = H5FA_DBLK_PAGE_SIZE(dblk_page, nelmts); -#ifdef H5FA_DEBUG +#ifdef H5FA_DEBUG HDfprintf(stderr, "%s: dblk_page->size = %Zu\n", FUNC, dblk_page->size); #endif /* H5FA_DEBUG */ diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c index 372caf8..644b4c9 100644 --- a/src/H5FAhdr.c +++ b/src/H5FAhdr.c @@ -197,9 +197,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Check for valid parameters */ if(cparam->raw_elmt_size == 0) H5E_THROW(H5E_BADVALUE, "element size must be greater than zero") - if(cparam->max_dblk_page_nelmts_bits == 0) + if(cparam->max_dblk_page_nelmts_bits == 0) H5E_THROW(H5E_BADVALUE, "max. # of elements bits must be greater than zero") - if(cparam->nelmts == 0) + if(cparam->nelmts == 0) H5E_THROW(H5E_BADVALUE, "# of elements must be greater than zero") } #endif /* NDEBUG */ @@ -478,7 +478,7 @@ H5FA__hdr_dest(H5FA_hdr_t *hdr)) H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context") } /* end if */ hdr->cb_ctx = NULL; - + /* Free the shared info itself */ hdr = H5FL_FREE(H5FA_hdr_t, hdr); diff --git a/src/H5FApkg.h b/src/H5FApkg.h index 8e2a515..eb224a6 100644 --- a/src/H5FApkg.h +++ b/src/H5FApkg.h @@ -14,7 +14,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: + * Programmer: * * Purpose: This file contains declarations which are visible only within * the H5FA package. Source files outside the H5FA package should diff --git a/src/H5FAprivate.h b/src/H5FAprivate.h index 08e6e50..f8a4619 100644 --- a/src/H5FAprivate.h +++ b/src/H5FAprivate.h @@ -79,8 +79,8 @@ typedef struct H5FA_class_t { typedef struct H5FA_create_t { const H5FA_class_t *cls; /* Class of Fixed Array to create */ uint8_t raw_elmt_size; /* Element size in file (in bytes) */ - uint8_t max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in a data block page) - - i.e. # of bits needed to store max. # of elements + uint8_t max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in a data block page) - + i.e. # of bits needed to store max. # of elements in a data block page */ hsize_t nelmts; /* # of elements in array */ } H5FA_create_t; diff --git a/src/H5FAtest.c b/src/H5FAtest.c index 187b5be..1828fa4 100644 --- a/src/H5FAtest.c +++ b/src/H5FAtest.c @@ -13,8 +13,8 @@ * access to either file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* - * Programmer: +/* + * Programmer: * * Purpose: Fixed array testing functions. * diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 7324afb..f91c6b5 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -52,6 +52,31 @@ typedef struct H5FD_core_t { size_t increment; /*multiples for mem allocation */ hbool_t backing_store; /*write to file name on flush */ int fd; /*backing store file descriptor */ + /* Information for determining uniqueness of a file with a backing store */ +#ifndef _WIN32 + /* + * On most systems the combination of device and i-node number uniquely + * identify a file. + */ + dev_t device; /*file device number */ +#ifdef H5_VMS + ino_t inode[3]; /*file i-node number */ +#else + ino_t inode; /*file i-node number */ +#endif /*H5_VMS*/ +#else + /* + * On _WIN32 the low-order word of a unique identifier associated with the + * file and the volume serial number uniquely identify a file. This number + * (which, both? -rpm) may change when the system is restarted or when the + * file is opened. After a process opens a file, the identifier is + * constant until the file is closed. An application can use this + * identifier and the volume serial number to determine whether two + * handles refer to the same file. + */ + DWORD fileindexlo; + DWORD fileindexhi; +#endif hbool_t dirty; /*changes not saved? */ /* Information from file open flags, for SWMR access */ @@ -394,6 +419,10 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, H5FD_core_t *file=NULL; H5FD_core_fapl_t *fa=NULL; H5P_genplist_t *plist; /* Property list pointer */ +#ifdef _WIN32 + HFILE filehandle; + struct _BY_HANDLE_FILE_INFORMATION fileinfo; +#endif h5_stat_t sb; int fd=-1; H5FD_t *ret_value; @@ -418,11 +447,14 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, if(H5F_ACC_CREAT & flags) o_flags |= O_CREAT; if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL; - /* Open backing store. The only case that backing store is off is when - * the backing_store flag is off and H5F_ACC_CREAT is on. */ + /* Open backing store, and get stat() from file. The only case that backing + * store is off is when the backing_store flag is off and H5F_ACC_CREAT is + * on. */ if(fa->backing_store || !(H5F_ACC_CREAT & flags)) { if(fa && (fd = HDopen(name, o_flags, 0666)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") + if(HDfstat(fd, &sb) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") } /* end if */ /* Create the new file struct */ @@ -442,13 +474,31 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, /* If save data in backing store. */ file->backing_store = fa->backing_store; + if(fd >= 0) { + /* Retrieve information for determining uniqueness of file */ +#ifdef _WIN32 + filehandle = _get_osfhandle(fd); + (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo); + file->fileindexhi = fileinfo.nFileIndexHigh; + file->fileindexlo = fileinfo.nFileIndexLow; +#else /* _WIN32 */ + file->device = sb.st_dev; +#ifdef H5_VMS + file->inode[0] = sb.st_ino[0]; + file->inode[1] = sb.st_ino[1]; + file->inode[2] = sb.st_ino[2]; +#else + file->inode = sb.st_ino; +#endif /* H5_VMS */ + +#endif /* _WIN32 */ + } /* end if */ + /* If an existing file is opened, load the whole file into memory. */ if(!(H5F_ACC_CREAT & flags)) { size_t size; - /* stat() file to retrieve its size */ - if(HDfstat(file->fd, &sb) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") + /* Retrieve file size */ size = (size_t)sb.st_size; /* Check if we should allocate the memory buffer and read in existing data */ @@ -536,6 +586,11 @@ done: * Thursday, July 29, 1999 * * Modifications: + * Neil Fortner + * Tuesday, March 9, 2010 + * Modified function to compare low level file information if + * a backing store is opened for both files, similar to the + * sec2 file driver. * *------------------------------------------------------------------------- */ @@ -544,28 +599,62 @@ H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { const H5FD_core_t *f1 = (const H5FD_core_t*)_f1; const H5FD_core_t *f2 = (const H5FD_core_t*)_f2; - int ret_value; + int ret_value = 0; FUNC_ENTER_NOAPI(H5FD_core_cmp, FAIL) - if (NULL==f1->name && NULL==f2->name) { - if (f1<f2) + if(f1->fd >= 0 && f2->fd >= 0) { + /* Compare low level file information for backing store */ +#ifdef _WIN32 + if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) + if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) + + if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) + if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) + +#else +#ifdef H5_DEV_T_IS_SCALAR + if (f1->device < f2->device) HGOTO_DONE(-1) + if (f1->device > f2->device) HGOTO_DONE(1) +#else /* H5_DEV_T_IS_SCALAR */ + /* If dev_t isn't a scalar value on this system, just use memcmp to + * determine if the values are the same or not. The actual return value + * shouldn't really matter... + */ + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))<0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))>0) HGOTO_DONE(1) +#endif /* H5_DEV_T_IS_SCALAR */ + +#ifndef H5_VMS + if (f1->inode < f2->inode) HGOTO_DONE(-1) + if (f1->inode > f2->inode) HGOTO_DONE(1) +#else + if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))<0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))>0) HGOTO_DONE(1) +#endif /* H5_VMS */ + +#endif /*_WIN32*/ + } /* end if */ + else { + if (NULL==f1->name && NULL==f2->name) { + if (f1<f2) + HGOTO_DONE(-1) + if (f1>f2) + HGOTO_DONE(1) + HGOTO_DONE(0) + } /* end if */ + + if (NULL==f1->name) HGOTO_DONE(-1) - if (f1>f2) + if (NULL==f2->name) HGOTO_DONE(1) - HGOTO_DONE(0) - } - if (NULL==f1->name) - HGOTO_DONE(-1) - if (NULL==f2->name) - HGOTO_DONE(1) - - ret_value = HDstrcmp(f1->name, f2->name); + ret_value = HDstrcmp(f1->name, f2->name); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_core_cmp() */ /*------------------------------------------------------------------------- diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 3c25426..67bb107 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -632,9 +632,9 @@ H5FD_family_sb_encode(H5FD_t *_file, char *name/*out*/, unsigned char *buf/*out* name[8] = '\0'; /* Store member file size. Use the member file size from the property here. - * This is to guarantee backward compatibility. If a file is created with + * This is to guarantee backward compatibility. If a file is created with * v1.6 library and the driver info isn't saved in the superblock. We open - * it with v1.8, the FILE->MEMB_SIZE will be the actual size of the first + * it with v1.8, the FILE->MEMB_SIZE will be the actual size of the first * member file (see H5FD_family_open). So it isn't safe to use FILE->MEMB_SIZE. * If the file is created with v1.8, the correctness of FILE->PMEM_SIZE is * checked in H5FD_family_sb_decode. SLU - 2009/3/21 @@ -894,45 +894,43 @@ done: * Programmer: Robb Matzke * Wednesday, August 4, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t H5FD_family_close(H5FD_t *_file) { - H5FD_family_t *file = (H5FD_family_t*)_file; - unsigned nerrors=0; /* Number of errors while closing member files */ - unsigned u; /* Local index variable */ - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_family_t *file = (H5FD_family_t*)_file; + unsigned nerrors = 0; /* Number of errors while closing member files */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5FD_family_close, FAIL) /* Close as many members as possible. Use private function here to avoid clearing * the error stack. We need the error message to indicate wrong member file size. */ - for (u=0; u<file->nmembs; u++) { - if (file->memb[u]) { - if (H5FD_close(file->memb[u])<0) + for(u = 0; u < file->nmembs; u++) { + if(file->memb[u]) { + if(H5FD_close(file->memb[u]) < 0) nerrors++; else file->memb[u] = NULL; - } - } - if (nerrors) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close member files") + } /* end if */ + } /* end for */ + if(nerrors) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close member files") /* Clean up other stuff */ - if(H5I_dec_ref(file->memb_fapl_id, FALSE)<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID") - if (file->memb) - H5MM_xfree(file->memb); - if (file->name) - H5MM_xfree(file->name); + if(H5I_dec_ref(file->memb_fapl_id, FALSE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID") + H5MM_xfree(file->memb); + H5MM_xfree(file->name); H5MM_xfree(file); done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_family_close() */ /*------------------------------------------------------------------------- @@ -835,8 +835,8 @@ H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) haddr_t saved_addr; hsize_t saved_size; unsigned cache_flags; - unsigned sinfo_status = 0; - unsigned hdr_status = 0; + unsigned sinfo_status = 0; + unsigned hdr_status = 0; FUNC_ENTER_NOAPI(H5FS_free, FAIL) @@ -881,7 +881,7 @@ H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) /* Check whether free-space manager header is in cache or not */ if(H5AC_get_entry_status(f, fspace->addr, &hdr_status) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free-space section info") - + if(hdr_status & H5AC_ES__IN_CACHE) { /* Unpin the free-space manager header */ if(H5AC_unpin_entry(fspace) < 0) @@ -902,7 +902,7 @@ H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, dxpl_id, saved_addr, (hsize_t)H5FS_HEADER_SIZE(f)) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space header") } - + done: FUNC_LEAVE_NOAPI(ret_value) } /* H5FS_free() */ diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h index 145c374..ca7104c 100644 --- a/src/H5FSprivate.h +++ b/src/H5FSprivate.h @@ -187,7 +187,7 @@ H5_DLL herr_t H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id); /* Free space section routines */ H5_DLL herr_t H5FS_sect_add(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *node, unsigned flags, void *op_data); -H5_DLL htri_t H5FS_sect_try_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, +H5_DLL htri_t H5FS_sect_try_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data); H5_DLL htri_t H5FS_sect_try_extend(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, haddr_t addr, hsize_t size, hsize_t extra_requested); diff --git a/src/H5FSsection.c b/src/H5FSsection.c index 26aac37..a9b8e3b 100644 --- a/src/H5FSsection.c +++ b/src/H5FSsection.c @@ -1574,7 +1574,7 @@ done: /*------------------------------------------------------------------------- * Function: H5FS_sect_try_merge * - * Purpose: Try to merge/shrink a block + * Purpose: Try to merge/shrink a block * * Return: TRUE: merged/shrunk * FALSE: not merged/not shrunk diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 9a63b6a..7075683 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -36,6 +36,7 @@ /* Other private headers needed by this file */ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5FLprivate.h" /* Free Lists */ #include "H5FOprivate.h" /* File objects */ #include "H5FSprivate.h" /* File free space */ diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index eb739dc..f42c7f6 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -240,7 +240,7 @@ done: /*------------------------------------------------------------------------- * Function: H5F_super_ext_close - * + * * Purpose: Close superblock extension * * Return: Success: non-negative on success @@ -250,7 +250,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr) { herr_t ret_value = SUCCEED; /* Return value */ @@ -321,7 +321,7 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id) /* Look up the superblock */ if(NULL == (sblock = (H5F_super_t *)H5AC_protect(f, dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, NULL, &dirtied, rw))) HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load superblock") - + /* Mark the superblock dirty if it was modified during loading or VFD indicated to do so */ if((H5AC_WRITE == rw) && (dirtied || H5F_HAS_FEATURE(f, H5FD_FEAT_DIRTY_SBLK_LOAD))) sblock_flags |= H5AC__DIRTIED_FLAG; @@ -401,8 +401,8 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) /* Bump superblock version to create superblock extension for SOHM info */ else if(f->shared->sohm_nindexes > 0) super_vers = HDF5_SUPERBLOCK_VERSION_2; - /* Bump superblock version to create superblock extension for - * non-default file space strategy or non-default free-space threshold + /* Bump superblock version to create superblock extension for + * non-default file space strategy or non-default free-space threshold */ else if(f->shared->fs_strategy != H5F_FILE_SPACE_STRATEGY_DEF || f->shared->fs_threshold != H5F_FREE_SPACE_THRESHOLD_DEF) @@ -804,7 +804,6 @@ done: * * Programmer: Vailin Choi; Feb 2009 * - * *------------------------------------------------------------------------- */ herr_t diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index e6e980b..a103351 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -152,7 +152,7 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, const void UNUSED /* Allocate space for the superblock */ if(NULL == (sblock = H5FL_CALLOC(H5F_super_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - + /* Read fixed-size portion of the superblock */ p = sbuf; H5_CHECK_OVERFLOW(fixed_size, size_t, haddr_t); @@ -659,24 +659,24 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, HDmemcpy(p, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN); p += H5F_SIGNATURE_LEN; *p++ = (uint8_t)sblock->super_vers; - + /* Check for older version of superblock format */ if(sblock->super_vers < HDF5_SUPERBLOCK_VERSION_2) { *p++ = (uint8_t)HDF5_FREESPACE_VERSION; /* (hard-wired) */ *p++ = (uint8_t)HDF5_OBJECTDIR_VERSION; /* (hard-wired) */ *p++ = 0; /* reserved*/ - + *p++ = (uint8_t)HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */ HDassert(H5F_SIZEOF_ADDR(f) <= 255); *p++ = (uint8_t)H5F_SIZEOF_ADDR(f); HDassert(H5F_SIZEOF_SIZE(f) <= 255); *p++ = (uint8_t)H5F_SIZEOF_SIZE(f); *p++ = 0; /* reserved */ - + UINT16ENCODE(p, sblock->sym_leaf_k); UINT16ENCODE(p, sblock->btree_k[H5B_SNODE_ID]); UINT32ENCODE(p, (uint32_t)sblock->status_flags); - + /* * Versions of the superblock >0 have the indexed storage B-tree * internal 'K' value stored @@ -686,37 +686,37 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, *p++ = 0; /*reserved */ *p++ = 0; /*reserved */ } /* end if */ - + H5F_addr_encode(f, &p, sblock->base_addr); H5F_addr_encode(f, &p, sblock->ext_addr); rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER); H5F_addr_encode(f, &p, (rel_eoa + sblock->base_addr)); H5F_addr_encode(f, &p, sblock->driver_addr); - + /* Encode the root group object entry, including the cached stab info */ if(H5G_ent_encode(f, &p, sblock->root_ent) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTENCODE, FAIL, "can't encode root group symbol table entry") - + /* Encode the driver information block. */ H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t); - + /* Checking whether driver block address is defined here is to handle backward * compatibility. If the file was created with v1.6 library or earlier and no * driver info block was written in the superblock, we don't write it either even * though there's some driver info. Otherwise, the driver block extended will * overwrite the (meta)data right after the superblock. This situation happens to - * the family driver particularly. SLU - 2009/3/24 + * the family driver particularly. SLU - 2009/3/24 */ if(driver_size > 0 && H5F_addr_defined(sblock->driver_addr)) { char driver_name[9]; /* Name of driver, for driver info block */ uint8_t *dbuf = p; /* Pointer to beginning of driver info */ - + /* Encode the driver information block */ *p++ = HDF5_DRIVERINFO_VERSION_0; /* Version */ *p++ = 0; /* reserved */ *p++ = 0; /* reserved */ *p++ = 0; /* reserved */ - + /* Driver info size, excluding header */ UINT32ENCODE(p, driver_size); @@ -726,7 +726,7 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, /* Store driver name (set in 'H5FD_sb_encode' call above) */ HDmemcpy(p, driver_name, (size_t)8); - + /* Advance buffer pointer past name & variable-sized portion of driver info */ /* (for later use in computing the superblock size) */ p += 8 + driver_size; @@ -735,40 +735,40 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, else { uint32_t chksum; /* Checksum temporary variable */ H5O_loc_t *root_oloc; /* Pointer to root group's object location */ - + /* Size of file addresses & offsets, and status flags */ HDassert(H5F_SIZEOF_ADDR(f) <= 255); *p++ = (uint8_t)H5F_SIZEOF_ADDR(f); HDassert(H5F_SIZEOF_SIZE(f) <= 255); *p++ = (uint8_t)H5F_SIZEOF_SIZE(f); *p++ = sblock->status_flags; - + /* Base, superblock extension & end of file addresses */ H5F_addr_encode(f, &p, sblock->base_addr); H5F_addr_encode(f, &p, sblock->ext_addr); rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER); H5F_addr_encode(f, &p, (rel_eoa + sblock->base_addr)); - + /* Retrieve information for root group */ if(NULL == (root_oloc = H5G_oloc(f->shared->root_grp))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to retrieve root group information") - + /* Encode address of root group's object header */ H5F_addr_encode(f, &p, root_oloc->addr); - + /* Compute superblock checksum */ chksum = H5_checksum_metadata(buf, (size_t)(H5F_SUPERBLOCK_SIZE(sblock->super_vers, f) - H5F_SIZEOF_CHKSUM), 0); - + /* Superblock checksum */ UINT32ENCODE(p, chksum); - + /* Sanity check */ HDassert((size_t)(p - buf) == H5F_SUPERBLOCK_SIZE(sblock->super_vers, f)); } /* end else */ - + /* Retrieve the total size of the superblock info */ H5_ASSIGN_OVERFLOW(superblock_size, (p - buf), int, size_t); - + /* Double check we didn't overrun the block (unlikely) */ HDassert(superblock_size <= sizeof(buf)); @@ -776,7 +776,7 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, /* (always at relative address 0) */ if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)0, superblock_size, buf) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock") - + /* Check for newer version of superblock format & superblock extension */ if(sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2 && H5F_addr_defined(sblock->ext_addr)) { /* Check for ignoring the driver info for this file */ @@ -787,10 +787,10 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, H5O_drvinfo_t drvinfo; /* Driver info */ H5O_loc_t ext_loc; /* "Object location" for superblock extension */ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Driver info block encoding buffer */ - + /* Sanity check */ HDassert(driver_size <= H5F_MAX_DRVINFOBLOCK_SIZE); - + /* Encode driver-specific data */ if(H5FD_sb_encode(f->shared->lf, drvinfo.name, dbuf) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information") @@ -798,7 +798,7 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, /* Open the superblock extension's object header */ if(H5F_super_ext_open(f, sblock->ext_addr, &ext_loc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension") - + /* Write driver info information to the superblock extension */ drvinfo.len = driver_size; drvinfo.buf = dbuf; diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 9a8e764..0bb29d5 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -698,7 +698,7 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, /* Determine the address of the index to use */ if(idx_type == H5_INDEX_NAME) { - /* Since names are hashed, getting them in strictly increasing or + /* Since names are hashed, getting them in strictly increasing or * decreasing order requires building a table and sorting it. * If the order is native, use the B-tree for names. */ @@ -716,7 +716,7 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, } /* end else */ /* If the order is native and there's no B-tree for indexing the links, - * use the B-tree for names instead of building a table to speed up the + * use the B-tree for names instead of building a table to speed up the * process. */ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { @@ -1004,7 +1004,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, /* Determine the address of the index to use */ if(idx_type == H5_INDEX_NAME) { - /* Since names are hashed, getting them in strictly increasing or + /* Since names are hashed, getting them in strictly increasing or * decreasing order requires building a table and sorting it. If * the order is native, use the B-tree for names. */ @@ -1022,7 +1022,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, } /* end else */ /* If the order is native and there's no B-tree for indexing the links, - * use the B-tree for names instead of building a table to speed up the + * use the B-tree for names instead of building a table to speed up the * process. */ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { @@ -1209,7 +1209,7 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, /* Determine the address of the index to use */ if(idx_type == H5_INDEX_NAME) { - /* Since names are hashed, getting them in strictly increasing or + /* Since names are hashed, getting them in strictly increasing or * decreasing order requires building a table and sorting it. If * the order is native, use the B-tree for names. */ @@ -1227,7 +1227,7 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, } /* end else */ /* If the order is native and there's no B-tree for indexing the links, - * use the B-tree for names instead of building a table to speed up the + * use the B-tree for names instead of building a table to speed up the * process. */ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { @@ -1647,7 +1647,7 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, /* Determine the address of the index to use */ if(idx_type == H5_INDEX_NAME) { - /* Since names are hashed, getting them in strictly increasing or + /* Since names are hashed, getting them in strictly increasing or * decreasing order requires building a table and sorting it. If * the order is native, use the B-tree for names. */ @@ -1665,14 +1665,14 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, } /* end else */ /* If the order is native and there's no B-tree for indexing the links, - * use the B-tree for names instead of building a table to speed up the + * use the B-tree for names instead of building a table to speed up the * process. */ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { bt2_addr = linfo->name_bt2_addr; HDassert(H5F_addr_defined(bt2_addr)); } /* end if */ - + /* If there is an index defined for the field, use it */ if(H5F_addr_defined(bt2_addr)) { H5G_bt2_ud_rmbi_t udata; /* User data for v2 B-tree record removal */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index a18339b..0eb4764 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -250,7 +250,7 @@ H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint) done: if(tmp_gcpl > 0 && tmp_gcpl != H5P_GROUP_CREATE_DEFAULT) - if(H5I_dec_ref(tmp_gcpl, TRUE) < 0) + if(H5I_dec_ref(tmp_gcpl, FALSE) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release property list") if(ret_value < 0) diff --git a/src/H5Glink.c b/src/H5Glink.c index f5ad7d9..05df268 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -403,6 +403,10 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, H5O_link_t tmp_src_lnk; /* Temporary copy of src link, when needed */ const H5O_link_t *src_lnk = _src_lnk; /* Source link */ hbool_t dst_lnk_init = FALSE; /* Whether the destination link is initialized */ + hbool_t expanded_link_open = FALSE; /* Whether the target location has been opened */ + H5G_loc_t tmp_src_loc; /* Group location holding target object */ + H5G_name_t tmp_src_path; /* Path for target object */ + H5O_loc_t tmp_src_oloc; /* Object location for target object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_link_copy_file, FAIL) @@ -413,61 +417,79 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, HDassert(dst_lnk); HDassert(cpy_info); - /* Expand soft link */ - if(H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link) { - H5O_info_t oinfo; /* Information about object pointed to by soft link */ - H5G_loc_t grp_loc; /* Group location holding soft link */ - H5G_name_t grp_path; /* Path for group holding soft link */ - - /* Make a temporary copy, so that it will not change the info in the cache */ - if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, &tmp_src_lnk)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy message") - - /* Set up group location for soft link to start in */ - H5G_name_reset(&grp_path); - grp_loc.path = &grp_path; - grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */ - - /* Check if the object pointed by the soft link exists in the source file */ - if(H5G_loc_info(&grp_loc, tmp_src_lnk.u.soft.name, FALSE, &oinfo, H5P_DEFAULT, dxpl_id) >= 0) { - /* Convert soft link to hard link */ - tmp_src_lnk.u.soft.name = (char *)H5MM_xfree(tmp_src_lnk.u.soft.name); + /* Expand soft or external link, if requested */ + if((H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link) + || (H5L_TYPE_EXTERNAL == src_lnk->type + && cpy_info->expand_ext_link)) { + H5G_loc_t lnk_grp_loc; /* Group location holding link */ + H5G_name_t lnk_grp_path; /* Path for link */ + htri_t tar_exists; /* Whether the target object exists */ + + /* Set up group location for link */ + H5G_name_reset(&lnk_grp_path); + lnk_grp_loc.path = &lnk_grp_path; + lnk_grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */ + + /* Check if the target object exists */ + if((tar_exists = H5G_loc_exists(&lnk_grp_loc, src_lnk->name, H5P_DEFAULT, + dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to check if target object exists") + + if(tar_exists) { + /* Make a temporary copy of the link, so that it will not change the + * info in the cache when we change it to a hard link */ + if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, &tmp_src_lnk)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy message") + + /* Set up group location for target object. Let H5G_traverse expand + * the link. */ + tmp_src_loc.path = &tmp_src_path; + tmp_src_loc.oloc = &tmp_src_oloc; + if(H5G_loc_reset(&tmp_src_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to reset location") + + /* Find the target object */ + if(H5G_loc_find(&lnk_grp_loc, src_lnk->name, &tmp_src_loc, + H5P_DEFAULT, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to find target object") + expanded_link_open = TRUE; + + /* Convert symbolic link to hard link */ + if(tmp_src_lnk.type == H5L_TYPE_SOFT) + tmp_src_lnk.u.soft.name = + (char *)H5MM_xfree(tmp_src_lnk.u.soft.name); + else if(tmp_src_lnk.u.ud.size > 0) + tmp_src_lnk.u.ud.udata = H5MM_xfree(tmp_src_lnk.u.ud.udata); tmp_src_lnk.type = H5L_TYPE_HARD; - tmp_src_lnk.u.hard.addr = oinfo.addr; + tmp_src_lnk.u.hard.addr = tmp_src_oloc.addr; src_lnk = &tmp_src_lnk; } /* end if */ - else { - /* Discard any errors from a dangling soft link */ - H5E_clear_stack(NULL); - - /* Release any information copied for temporary src link */ - H5O_msg_reset(H5O_LINK_ID, &tmp_src_lnk); - } /* end else */ } /* end if */ /* Copy src link information to dst link information */ if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, dst_lnk)) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy message") dst_lnk_init = TRUE; /* Check if object in source group is a hard link & copy it */ if(H5L_TYPE_HARD == src_lnk->type) { H5O_loc_t new_dst_oloc; /* Copied object location in destination */ - H5O_loc_t tmp_src_oloc; /* Temporary object location for source object */ /* Set up copied object location to fill in */ H5O_loc_reset(&new_dst_oloc); new_dst_oloc.file = dst_file; - /* Build temporary object location for source */ - H5O_loc_reset(&tmp_src_oloc); - tmp_src_oloc.file = src_oloc->file; - HDassert(H5F_addr_defined(src_lnk->u.hard.addr)); - tmp_src_oloc.addr = src_lnk->u.hard.addr; + if(!expanded_link_open) { + /* Build temporary object location for source */ + H5O_loc_reset(&tmp_src_oloc); + tmp_src_oloc.file = src_oloc->file; + tmp_src_oloc.addr = src_lnk->u.hard.addr; + } /* end if */ + HDassert(H5F_addr_defined(tmp_src_oloc.addr)); /* Copy the shared object from source to destination */ if(H5O_copy_header_map(&tmp_src_oloc, &new_dst_oloc, dxpl_id, cpy_info, TRUE) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy object") + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") /* Copy new destination object's information for eventual insertion */ dst_lnk->u.hard.addr = new_dst_oloc.addr; @@ -482,6 +504,10 @@ done: if(ret_value < 0) if(dst_lnk_init) H5O_msg_reset(H5O_LINK_ID, dst_lnk); + /* Check if we need to free the temp source oloc */ + if(expanded_link_open) + if(H5G_loc_free(&tmp_src_loc) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link_copy_file() */ diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 47214a4..6145839 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -40,6 +40,8 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ + /****************/ /* Local Macros */ @@ -56,6 +58,12 @@ typedef struct { H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fnd_t; +/* User data for checking if an object exists */ +typedef struct { + /* upward */ + hbool_t exists; /* Whether the object exists */ +} H5G_loc_exists_t; + /* User data for looking up an object in a group by index */ typedef struct { /* downward */ @@ -493,8 +501,9 @@ H5G_loc_find_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, H5G_loc_fbi_t *udata = (H5G_loc_fbi_t *)_udata; /* User data passed in */ H5O_link_t fnd_lnk; /* Link within group */ hbool_t lnk_copied = FALSE; /* Whether the link was copied */ - size_t links_left = 1; /* # of links left to traverse (somewhat bogus... :-/ ) */ + size_t links_left = H5L_NUM_LINKS; /* # of links left to traverse */ hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */ + hbool_t obj_exists = FALSE; /* Whether the object exists (unused) */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_loc_find_by_idx_cb) @@ -517,7 +526,7 @@ H5G_loc_find_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, /* Perform any special traversals that the link needs */ /* (soft links, user-defined links, file mounting, etc.) */ /* (may modify the object location) */ - if(H5G_traverse_special(obj_loc, &fnd_lnk, H5G_TARGET_NORMAL, &links_left, TRUE, udata->loc, udata->lapl_id, udata->dxpl_id) < 0) + if(H5G_traverse_special(obj_loc, &fnd_lnk, H5G_TARGET_NORMAL, &links_left, TRUE, udata->loc, &obj_exists, udata->lapl_id, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") done: @@ -631,6 +640,84 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_loc_exists_cb + * + * Purpose: Callback for checking if an object exists + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, February 2, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_exists_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, + const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_exists_t *udata = (H5G_loc_exists_t *)_udata; /* User data passed in */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_loc_exists_cb) + + /* Check if the name in this group resolved to a valid object */ + if(obj_loc == NULL) + if(lnk) + udata->exists = FALSE; + else + udata->exists = FAIL; + else + udata->exists = TRUE; + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G_loc_exists_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_exists + * + * Purpose: Check if an object actually exists at a location + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Tuesday, February 2, 2010 + * + *------------------------------------------------------------------------- + */ +htri_t +H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_exists_t udata; /* User data for traversal callback */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_loc_exists, FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + + /* Set up user data for locating object */ + udata.exists = FALSE; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G_loc_exists_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't check if object exists") + + /* Set return value */ + ret_value = (htri_t)udata.exists; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_exists() */ + + +/*------------------------------------------------------------------------- * Function: H5G_loc_info_cb * * Purpose: Callback for retrieving object info for an object in a group diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 18125df..1df2fe4 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -51,7 +51,6 @@ typedef struct H5G_node_key_t { size_t offset; /*offset into heap for name */ } H5G_node_key_t; - /* Private macros */ #define H5G_NODE_SIZEOF_HDR(F) (H5_SIZEOF_MAGIC + 4) @@ -63,10 +62,8 @@ static H5RC_t *H5G_node_get_shared(const H5F_t *f, const void *_udata); static herr_t H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t op, void *_lt_key, void *_udata, void *_rt_key, haddr_t *addr_p/*out*/); -static int H5G_node_cmp2(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, - void *_rt_key); -static int H5G_node_cmp3(H5F_t *f, hid_t dxpl_id, void *_lt_key, void *_udata, - void *_rt_key); +static int H5G_node_cmp2(void *_lt_key, void *_udata, void *_rt_key); +static int H5G_node_cmp3(void *_lt_key, void *_udata, void *_rt_key); static htri_t H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_lt_key, void *_udata); static H5B_ins_t H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key, @@ -77,13 +74,10 @@ static H5B_ins_t H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_l static H5B_ins_t H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *lt_key, hbool_t *lt_key_changed, void *udata, void *rt_key, hbool_t *rt_key_changed); -static herr_t H5G_node_decode_key(const H5F_t *f, const H5B_t *bt, const uint8_t *raw, - void *_key); -static herr_t H5G_node_encode_key(const H5F_t *f, const H5B_t *bt, uint8_t *raw, - void *_key); -static herr_t H5G_node_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id, - int indent, int fwidth, const void *key, - const void *udata); +static herr_t H5G_node_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key); +static herr_t H5G_node_encode_key(const H5B_shared_t *shared, uint8_t *raw, const void *_key); +static herr_t H5G_node_debug_key(FILE *stream, int indent, int fwidth, + const void *key, const void *udata); /* H5G inherits B-tree like properties from H5B */ H5B_class_t H5B_SNODE[1] = {{ @@ -95,6 +89,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 */ @@ -130,18 +125,12 @@ H5FL_SEQ_DEFINE(H5G_entry_t); static H5RC_t * H5G_node_get_shared(const H5F_t *f, const void UNUSED *_udata) { - H5RC_t *rc; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_get_shared) HDassert(f); - /* Increment reference count on shared B-tree node */ - rc = H5F_GRP_BTREE_SHARED(f); - H5RC_INC(rc); - /* Return the pointer to the ref-count object */ - FUNC_LEAVE_NOAPI(rc) + FUNC_LEAVE_NOAPI(H5F_GRP_BTREE_SHARED(f)) } /* end H5G_node_get_shared() */ @@ -159,17 +148,17 @@ H5G_node_get_shared(const H5F_t *f, const void UNUSED *_udata) *------------------------------------------------------------------------- */ static herr_t -H5G_node_decode_key(const H5F_t *f, const H5B_t UNUSED *bt, const uint8_t *raw, void *_key) +H5G_node_decode_key(const H5B_shared_t *shared, const uint8_t *raw, void *_key) { H5G_node_key_t *key = (H5G_node_key_t *) _key; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_decode_key) - HDassert(f); + HDassert(shared); HDassert(raw); HDassert(key); - H5F_DECODE_LENGTH(f, raw, key->offset); + H5F_DECODE_LENGTH_LEN(raw, key->offset, shared->sizeof_len); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_node_decode_key() */ @@ -189,17 +178,17 @@ H5G_node_decode_key(const H5F_t *f, const H5B_t UNUSED *bt, const uint8_t *raw, *------------------------------------------------------------------------- */ static herr_t -H5G_node_encode_key(const H5F_t *f, const H5B_t UNUSED *bt, uint8_t *raw, void *_key) +H5G_node_encode_key(const H5B_shared_t *shared, uint8_t *raw, const void *_key) { - H5G_node_key_t *key = (H5G_node_key_t *) _key; + const H5G_node_key_t *key = (const H5G_node_key_t *) _key; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_encode_key) - HDassert(f); + HDassert(shared); HDassert(raw); HDassert(key); - H5F_ENCODE_LENGTH(f, raw, key->offset); + H5F_ENCODE_LENGTH_LEN(raw, key->offset, shared->sizeof_len); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_node_encode_key() */ @@ -218,8 +207,8 @@ H5G_node_encode_key(const H5F_t *f, const H5B_t UNUSED *bt, uint8_t *raw, void * *------------------------------------------------------------------------- */ static herr_t -H5G_node_debug_key(FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, - int indent, int fwidth, const void *_key, const void *_udata) +H5G_node_debug_key(FILE *stream, int indent, int fwidth, const void *_key, + const void *_udata) { const H5G_node_key_t *key = (const H5G_node_key_t *) _key; const H5G_bt_common_t *udata = (const H5G_bt_common_t *) _udata; @@ -367,8 +356,7 @@ done: *------------------------------------------------------------------------- */ static int -H5G_node_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, - void *_rt_key) +H5G_node_cmp2(void *_lt_key, void *_udata, void *_rt_key) { H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; @@ -427,8 +415,7 @@ H5G_node_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata *------------------------------------------------------------------------- */ static int -H5G_node_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_udata, - void *_rt_key) +H5G_node_cmp3(void *_lt_key, void *_udata, void *_rt_key) { H5G_bt_common_t *udata = (H5G_bt_common_t *) _udata; H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; @@ -860,14 +847,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 +909,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/src/H5Gpkg.h b/src/H5Gpkg.h index 33ec680..b80b1b1 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -34,6 +34,7 @@ /* Other private headers needed by this file */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5B2private.h" /* v2 B-trees */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5HFprivate.h" /* Fractal heaps */ #include "H5HLprivate.h" /* Local Heaps */ #include "H5Oprivate.h" /* Object headers */ @@ -55,7 +56,8 @@ #define H5G_TARGET_SLINK 0x0001 #define H5G_TARGET_MOUNT 0x0002 #define H5G_TARGET_UDLINK 0x0004 -#define H5G_CRT_INTMD_GROUP 0x0008 +#define H5G_TARGET_EXISTS 0x0008 +#define H5G_CRT_INTMD_GROUP 0x0010 /****************************/ /* Package Private Typedefs */ @@ -369,7 +371,7 @@ H5_DLL herr_t H5G_iterate(hid_t loc_id, const char *group_name, H5_DLL herr_t H5G_traverse_term_interface(void); H5_DLL herr_t H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, unsigned target, size_t *nlinks, hbool_t last_comp, - H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id); + H5G_loc_t *obj_loc, hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traverse_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id); diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index dec40f3..3e66777 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -210,6 +210,8 @@ H5_DLL herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5_DLL herr_t H5G_loc_find_by_idx(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc/*out*/, hid_t lapl_id, hid_t dxpl_id); +H5_DLL htri_t H5G_loc_exists(const H5G_loc_t *loc, const char *name, + hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5G_loc_info(H5G_loc_t *loc, const char *name, hbool_t want_ih_info, H5O_info_t *oinfo/*out*/, hid_t lapl_id, hid_t dxpl_id); diff --git a/src/H5Groot.c b/src/H5Groot.c index e4cdc46..0d21bfe 100644 --- a/src/H5Groot.c +++ b/src/H5Groot.c @@ -99,6 +99,7 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) H5G_loc_t root_loc; /* Root location information */ htri_t stab_exists = -1; /* Whether the symbol table exists */ hbool_t sblock_dirty = FALSE; /* Whether superblock was dirtied */ + hbool_t path_init = FALSE; /* Whether path was initialized */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_mkroot, FAIL) @@ -235,6 +236,7 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) /* Create the path names for the root group's entry */ H5G_name_init(root_loc.path, "/"); + path_init = TRUE; f->shared->root_grp->shared->fo_count = 1; /* The only other open object should be the superblock extension, if it @@ -250,13 +252,14 @@ done: * allocated */ if(ret_value < 0) { if(f->shared->root_grp) { + if(path_init) + H5G_name_free(root_loc.path); if(f->shared->root_grp->shared) f->shared->root_grp->shared = H5FL_FREE(H5G_shared_t, f->shared->root_grp->shared); f->shared->root_grp = H5FL_FREE(H5G_t, f->shared->root_grp); } /* end if */ if(f->shared->sblock) f->shared->sblock->root_ent = (H5G_entry_t *)H5MM_xfree(f->shared->sblock->root_ent); - H5G_name_free(root_loc.path); } /* end if */ /* Mark superblock dirty in cache, if necessary */ diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 4c287d5..e9f3010 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -43,8 +43,13 @@ /* User data for path traversal routine */ typedef struct { + /* down */ + hbool_t chk_exists; /* Flag to indicate we are checking if object exists */ + + /* up */ H5G_loc_t *obj_loc; /* Object location */ -} H5G_trav_ud1_t; + hbool_t exists; /* Indicate if object exists */ +} H5G_trav_slink_t; /* Private macros */ @@ -53,15 +58,15 @@ static char *H5G_comp_g = NULL; /*component buffer */ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */ /* PRIVATE PROTOTYPES */ -static herr_t H5G_traverse_link_cb(H5G_loc_t *grp_loc, const char *name, +static herr_t H5G_traverse_slink_cb(H5G_loc_t *grp_loc, 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 H5G_traverse_ud(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id); + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); static herr_t H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id); + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); static herr_t H5G_traverse_mount(H5G_loc_t *loc/*in,out*/); static herr_t H5G_traverse_real(const H5G_loc_t *loc, const char *name, unsigned target, size_t *nlinks, H5G_traverse_t op, void *op_data, @@ -97,9 +102,9 @@ H5G_traverse_term_interface(void) /*------------------------------------------------------------------------- - * Function: H5G_traverse_link_cb + * Function: H5G_traverse_slink_cb * - * Purpose: Callback for link traversal. This routine sets the + * Purpose: Callback for soft link traversal. This routine sets the * correct information for the object location. * * Return: Non-negative on success/Negative on failure @@ -110,20 +115,29 @@ H5G_traverse_term_interface(void) *------------------------------------------------------------------------- */ static herr_t -H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +H5G_traverse_slink_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, + const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) { - H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ + H5G_trav_slink_t *udata = (H5G_trav_slink_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_link_cb) + FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink_cb) /* Check for dangling soft link */ - if(obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") + if(obj_loc == NULL) { + if(udata->chk_exists) + udata->exists = FALSE; + else + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") + } /* end if */ + else { + /* Copy new location information for resolved object */ + H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); - /* Copy new location information for resolved object */ - H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); + /* Indicate that the object exists */ + udata->exists = TRUE; + } /* end else */ done: /* Indicate that this callback didn't take ownership of the group * @@ -131,7 +145,7 @@ done: *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_traverse_link_cb() */ +} /* end H5G_traverse_slink_cb() */ /*------------------------------------------------------------------------- @@ -149,8 +163,8 @@ done: */ static herr_t H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t _lapl_id, - hid_t dxpl_id) + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t _lapl_id, hid_t dxpl_id) { const H5L_class_t *link_class; /* User-defined link class */ hid_t cb_return = -1; /* The ID the user-defined callback returned */ @@ -222,8 +236,25 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info") /* User-defined callback function */ - if((cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID") + cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id); + + /* Check for failing to locate the object */ + if(cb_return < 0) { + /* Check if we just needed to know if the object exists */ + if(target & H5G_TARGET_EXISTS) { + /* Clear any errors from the stack */ + H5E_clear_stack(NULL); + + /* Indicate that the object doesn't exist */ + *obj_exists = FALSE; + + /* Get out now */ + HGOTO_DONE(SUCCEED); + } /* end if */ + /* else, we really needed to open the object */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID") + } /* end if */ /* Get the oloc from the ID the user callback returned */ switch(H5I_get_type(cb_return)) { @@ -306,10 +337,10 @@ done: */ static herr_t H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id) + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id) { - H5G_trav_ud1_t udata; /* User data to pass to link traversal callback */ + H5G_trav_slink_t udata; /* User data to pass to link traversal callback */ H5G_name_t tmp_obj_path; /* Temporary copy of object's path */ hbool_t tmp_obj_path_set = FALSE; /* Flag to indicate that tmp object path is initialized */ H5O_loc_t tmp_grp_oloc; /* Temporary copy of group entry */ @@ -347,12 +378,17 @@ H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, tmp_obj_path_set = TRUE; /* Set up user data for traversal callback */ + udata.chk_exists = (target & H5G_TARGET_EXISTS) ? TRUE : FALSE; + udata.exists = FALSE; udata.obj_loc = obj_loc; /* Traverse the link */ - if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, lapl_id, dxpl_id) < 0) + if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, target, nlinks, H5G_traverse_slink_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") + /* Pass back information about whether the object exists */ + *obj_exists = udata.exists; + done: /* Restore object's group hier. path */ if(tmp_obj_path_set) { @@ -464,7 +500,7 @@ done: herr_t H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, unsigned target, size_t *nlinks, hbool_t last_comp, - H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id) + H5G_loc_t *obj_loc, hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ @@ -485,7 +521,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, (0 == (target & H5G_TARGET_SLINK) || !last_comp)) { if((*nlinks)-- <= 0) HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") - if(H5G_traverse_slink(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0) + if(H5G_traverse_slink(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "symbolic link traversal failed") } /* end if */ @@ -498,7 +534,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, (0 == (target & H5G_TARGET_UDLINK) || !last_comp) ) { if((*nlinks)-- <= 0) HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") - if(H5G_traverse_ud(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0) + if(H5G_traverse_ud(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "user-defined link traversal failed") } /* end if */ @@ -634,6 +670,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, while((name = H5G_component(name, &nchars)) && *name) { const char *s; /* Temporary string pointer */ htri_t lookup_status; /* Status from object lookup */ + hbool_t obj_exists; /* Whether the object exists */ /* * Copy the component name into a null-terminated buffer so @@ -663,6 +700,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Get information for object in current group */ if((lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't look up component") + obj_exists = FALSE; /* If the lookup was OK, build object location and traverse special links, etc. */ if(lookup_status) { @@ -676,9 +714,12 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location") obj_loc_valid = TRUE; + /* Assume object exists */ + obj_exists = TRUE; + /* Perform any special traversals that the link needs */ /* (soft links, user-defined links, file mounting, etc.) */ - if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, lapl_id, dxpl_id) < 0) + if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, &obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") } /* end if */ @@ -690,7 +731,10 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Set callback parameters appropriately, based on link being found */ if(lookup_status) { cb_lnk = &lnk; - cb_loc = &obj_loc; + if(obj_exists) + cb_loc = &obj_loc; + else + cb_loc = NULL; } /* end if */ else { HDassert(!obj_loc_valid); @@ -867,10 +867,10 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr- HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to delete fractal heap") } /* end if */ +done: /* Release the fractal heap wrapper */ - (void)H5FL_FREE(H5HF_t, fh); + fh = H5FL_FREE(H5HF_t, fh); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_close() */ diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c index 027146c..7a511a0 100644 --- a/src/H5HFdblock.c +++ b/src/H5HFdblock.c @@ -312,7 +312,7 @@ H5HF_man_dblock_destroy(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_direct_t *dblock, done: /* Unprotect the indirect block, with appropriate flags */ - if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, cache_flags) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, cache_flags) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block") FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index 8652f90..e55f472 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -1454,7 +1454,7 @@ H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id) done: /* Unprotect the header with appropriate flags */ - if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, cache_flags) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, cache_flags) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c index 5490c22..7577583 100644 --- a/src/H5HFhuge.c +++ b/src/H5HFhuge.c @@ -710,7 +710,7 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, /* Call the user's 'op' callback */ if(op(read_buf, (size_t)obj_size, op_data) < 0) { /* Release buffer */ - H5MM_xfree(read_buf); + read_buf = H5MM_xfree(read_buf); /* Indicate error */ HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "application's callback failed") @@ -720,7 +720,7 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, done: /* Release the buffer for reading */ if(read_buf && read_buf != op_data) - H5MM_xfree(read_buf); + read_buf = H5MM_xfree(read_buf); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_huge_op_real() */ diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index 809a720..26c60a3 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -852,7 +852,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5HF_man_iblock_alloc_indirect2 + * Function: H5HF_man_iblock_alloc_row * * Purpose: Allocate a "single" section for an object, out of a * "row" section. @@ -872,7 +872,7 @@ H5HF_man_iblock_alloc_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t ** { H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */ H5HF_free_section_t *old_sec_node = *sec_node; /* Pointer to old indirect section node */ - unsigned dblock_entry; /* Entry for direct block */ + unsigned dblock_entry; /* Entry for direct block */ hbool_t iblock_held = FALSE; /* Flag to indicate that indirect block is held */ herr_t ret_value = SUCCEED; /* Return value */ diff --git a/src/H5HFiter.c b/src/H5HFiter.c index a3c61d7..f7178a1 100644 --- a/src/H5HFiter.c +++ b/src/H5HFiter.c @@ -315,7 +315,7 @@ herr_t H5HF_man_iter_start_entry(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, H5HF_indirect_t *iblock, unsigned start_entry) { - H5HF_block_loc_t *new_loc; /* Pointer to new block location */ + H5HF_block_loc_t *new_loc = NULL; /* Pointer to new block location */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_start_entry) @@ -350,6 +350,9 @@ H5HF_man_iter_start_entry(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, biter->ready = TRUE; done: + if(ret_value < 0 && new_loc) + new_loc = H5FL_FREE(H5HF_block_loc_t, new_loc); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_iter_start_entry() */ @@ -397,7 +400,7 @@ H5HF_man_iter_reset(H5HF_block_iter_t *biter) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") /* Free the current location context */ - (void)H5FL_FREE(H5HF_block_loc_t, curr_loc); + curr_loc = H5FL_FREE(H5HF_block_loc_t, curr_loc); /* Advance to next location */ curr_loc = next_loc; @@ -489,7 +492,7 @@ H5HF_man_iter_up(H5HF_block_iter_t *biter) up_loc = biter->curr->up; /* Release this location */ - (void)H5FL_FREE(H5HF_block_loc_t, biter->curr); + biter->curr = H5FL_FREE(H5HF_block_loc_t, biter->curr); /* Point location to next location up */ biter->curr = up_loc; @@ -515,7 +518,7 @@ done: herr_t H5HF_man_iter_down(H5HF_block_iter_t *biter, H5HF_indirect_t *iblock) { - H5HF_block_loc_t *down_loc; /* Pointer to new 'down' block location */ + H5HF_block_loc_t *down_loc = NULL; /* Pointer to new 'down' block location */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_down) @@ -547,6 +550,9 @@ H5HF_man_iter_down(H5HF_block_iter_t *biter, H5HF_indirect_t *iblock) biter->curr = down_loc; done: + if(ret_value < 0 && down_loc) + down_loc = H5FL_FREE(H5HF_block_loc_t, down_loc); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_iter_down() */ diff --git a/src/H5HFman.c b/src/H5HFman.c index 47478e6..0ec6f5f 100644 --- a/src/H5HFman.c +++ b/src/H5HFman.c @@ -482,7 +482,7 @@ done: herr_t H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) { - H5HF_free_section_t *sec_node; /* Pointer to free space section for block */ + H5HF_free_section_t *sec_node = NULL; /* Pointer to free space section for block */ H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */ hbool_t did_protect; /* Whether we protected the indirect block or not */ hsize_t obj_off; /* Object's offset in heap */ @@ -571,24 +571,29 @@ H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) iblock = NULL; } /* end if */ - /* Update statistics about heap */ - hdr->man_nobjs--; - /* Increase space available in heap (marks header dirty) */ if(H5HF_hdr_adj_free(hdr, (ssize_t)obj_len) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for heap") + /* Update statistics about heap */ + hdr->man_nobjs--; + /* Return free space to the heap's list of space */ if(H5HF_space_add(hdr, dxpl_id, sec_node, H5FS_ADD_RETURNED_SPACE) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list") + sec_node = NULL; done: if(ret_value < 0) { - /* Unlock indirect block */ - if(iblock && H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") + /* Release section node */ + if(sec_node && H5HF_sect_single_free((H5FS_section_info_t *)sec_node) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release section node") } /* end if */ + /* Unlock indirect block */ + if(iblock && H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_remove() */ diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index 3c5567c..61f018f 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -169,7 +169,7 @@ #define H5HF_FSPACE_SECT_SINGLE 0 /* Section is a range of actual bytes in a direct block */ #define H5HF_FSPACE_SECT_FIRST_ROW 1 /* Section is first range of blocks in an indirect block row */ #define H5HF_FSPACE_SECT_NORMAL_ROW 2 /* Section is a range of blocks in an indirect block row */ -#define H5HF_FSPACE_SECT_INDIRECT 3 /* Section is a span of blocks in an indirect block */ +#define H5HF_FSPACE_SECT_INDIRECT 3 /* Section is a span of blocks in an indirect block */ /* Flags for 'op' operations */ #define H5HF_OP_MODIFY 0x0001 /* Operation will modify object */ @@ -721,6 +721,7 @@ H5_DLL herr_t H5HF_sect_row_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5_DLL H5HF_indirect_t *H5HF_sect_row_get_iblock(H5HF_free_section_t *sect); H5_DLL herr_t H5HF_sect_indirect_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries); +H5_DLL herr_t H5HF_sect_single_free(H5FS_section_info_t *sect); /* Internal operator callbacks */ H5_DLL herr_t H5HF_op_read(const void *obj, size_t obj_len, void *op_data); diff --git a/src/H5HFsection.c b/src/H5HFsection.c index 102dc7c..d763897 100644 --- a/src/H5HFsection.c +++ b/src/H5HFsection.c @@ -97,7 +97,6 @@ static htri_t H5HF_sect_single_can_shrink(const H5FS_section_info_t *sect, void *udata); static herr_t H5HF_sect_single_shrink(H5FS_section_info_t **_sect, void *udata); -static herr_t H5HF_sect_single_free(H5FS_section_info_t *sect); static herr_t H5HF_sect_single_valid(const H5FS_section_class_t *cls, const H5FS_section_info_t *sect); @@ -465,7 +464,7 @@ H5HF_sect_node_free(H5HF_free_section_t *sect, H5HF_indirect_t *iblock) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block") /* Release the section */ - (void)H5FL_FREE(H5HF_free_section_t, sect); + sect = H5FL_FREE(H5HF_free_section_t, sect); done: FUNC_LEAVE_NOAPI(ret_value) @@ -517,7 +516,7 @@ H5HF_sect_single_new(hsize_t sect_off, size_t sect_size, done: if(!ret_value && sect) { /* Release the section */ - (void)H5FL_FREE(H5HF_free_section_t, sect); + sect = H5FL_FREE(H5HF_free_section_t, sect); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -1169,7 +1168,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5HF_sect_single_free(H5FS_section_info_t *_sect) { H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Pointer to section to free */ @@ -1372,7 +1371,7 @@ H5HF_sect_row_from_single(H5HF_hdr_t *hdr, H5HF_free_section_t *sect, /* Release single section's hold on underlying indirect block */ if(H5HF_iblock_decr(dblock->parent) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") done: FUNC_LEAVE_NOAPI(ret_value) @@ -3756,7 +3755,7 @@ static herr_t H5HF_sect_indirect_build_parent(H5HF_hdr_t *hdr, H5HF_free_section_t *sect) { H5HF_indirect_t *par_iblock; /* Indirect block for parent section */ - H5HF_free_section_t *par_sect; /* Parent indirect section */ + H5HF_free_section_t *par_sect = NULL; /* Parent indirect section */ unsigned par_row, par_col; /* Row & column in parent indirect section */ unsigned par_entry; /* Entry within parent indirect section */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3802,6 +3801,10 @@ H5HF_sect_indirect_build_parent(H5HF_hdr_t *hdr, H5HF_free_section_t *sect) par_sect->u.indirect.rc = 1; done: + if(ret_value < 0) + if(par_sect && H5HF_sect_indirect_free(par_sect) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free indirect section node") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_sect_indirect_build_parent() */ @@ -640,10 +640,11 @@ void * H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/, size_t *buf_size) { - H5HG_heap_t *heap = NULL; - size_t size; - uint8_t *p = NULL; - void *ret_value; + H5HG_heap_t *heap = NULL; /* Pointer to global heap object */ + size_t size; /* Size of the heap object */ + uint8_t *p; /* Pointer to object in heap buffer */ + void *orig_object = object; /* Keep a copy of the original object pointer */ + void *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5HG_read, NULL) @@ -659,6 +660,7 @@ H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/, HDassert(heap->obj[hobj->idx].begin); size = heap->obj[hobj->idx].size; p = heap->obj[hobj->idx].begin + H5HG_SIZEOF_OBJHDR(f); + /* Allocate a buffer for the object read in, if the user didn't give one */ if(!object && NULL == (object = H5MM_malloc(size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") @@ -692,6 +694,9 @@ done: if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, H5AC__NO_FLAGS_SET)<0) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release object header") + if(NULL == ret_value && NULL == orig_object && object) + H5MM_free(object); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HG_read() */ diff --git a/src/H5HLcache.c b/src/H5HLcache.c index 6e725ac..47d5d6f 100644 --- a/src/H5HLcache.c +++ b/src/H5HLcache.c @@ -138,13 +138,14 @@ const H5AC_class_t H5AC_LHEAP_DBLK[1] = {{ static herr_t H5HL_fl_deserialize(H5HL_t *heap, hsize_t free_block) { - H5HL_free_t *fl, *tail = NULL; /* Heap free block nodes */ + H5HL_free_t *fl = NULL, *tail = NULL; /* Heap free block nodes */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HL_fl_deserialize) /* check arguments */ HDassert(heap); + HDassert(!heap->freelist); /* Build free list */ while(H5HL_FREE_NULL != free_block) { @@ -161,13 +162,6 @@ H5HL_fl_deserialize(H5HL_t *heap, hsize_t free_block) fl->prev = tail; fl->next = NULL; - /* Insert node into list */ - if(tail) - tail->next = fl; - tail = fl; - if(!heap->freelist) - heap->freelist = fl; - /* Decode offset of next free block */ p = heap->dblk_image + free_block; H5F_DECODE_LENGTH_LEN(p, free_block, heap->sizeof_size); @@ -178,9 +172,21 @@ H5HL_fl_deserialize(H5HL_t *heap, hsize_t free_block) H5F_DECODE_LENGTH_LEN(p, fl->size, heap->sizeof_size); if(fl->offset + fl->size > heap->dblk_size) HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "bad heap free list") + + /* Append node onto list */ + if(tail) + tail->next = fl; + else + heap->freelist = fl; + tail = fl; + fl = NULL; } /* end while */ done: + if(ret_value < 0) + if(fl) + fl = H5FL_FREE(H5HL_free_t, fl); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HL_fl_deserialize() */ @@ -42,6 +42,7 @@ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Ipkg.h" /* IDs */ @@ -924,6 +925,44 @@ done: /*------------------------------------------------------------------------- + * Function: H5I_subst + * + * Purpose: Substitute a new object pointer for the specified ID. + * + * Return: Success: Non-null previsou object pointer associated + * with the specified ID. + * Failure: NULL + * + * Programmer: Quincey Koziol + * Saturday, February 27, 2010 + * + *------------------------------------------------------------------------- + */ +void * +H5I_subst(hid_t id, const void *new_object) +{ + H5I_id_info_t *id_ptr; /* Ptr to the atom */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5I_subst, NULL) + + /* General lookup of the ID */ + if(NULL == (id_ptr = H5I_find_id(id))) + HGOTO_ERROR(H5E_ATOM, H5E_NOTFOUND, NULL, "can't get ID ref count") + + /* Get the old object pointer to return */ + /* (Casting away const OK -QAK) */ + ret_value = (void *)id_ptr->obj_ptr; + + /* Set the new object pointer for the ID */ + id_ptr->obj_ptr = new_object; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end if */ + + +/*------------------------------------------------------------------------- * Function: H5I_object * * Purpose: Find an object pointer for the specified ID. diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index 475871b..ef83908 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -55,6 +55,7 @@ H5_DLL int H5I_nmembers(H5I_type_t type); H5_DLL herr_t H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref); H5_DLL int H5I_destroy_type(H5I_type_t type); H5_DLL hid_t H5I_register(H5I_type_t type, const void *object, hbool_t app_ref); +H5_DLL void *H5I_subst(hid_t id, const void *new_object); H5_DLL void *H5I_object(hid_t id); H5_DLL void *H5I_object_verify(hid_t id, H5I_type_t id_type); H5_DLL H5I_type_t H5I_get_type(hid_t id); diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index db762cf..7ccdb68 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -412,19 +412,15 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, /* get last component of file_name */ GET_LAST_DELIMITER(actual_file_name, ptr) - if(ptr) { - /* Truncate filename portion from actual file name path */ - *ptr = '\0'; + if(!ptr) + HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s', temp_file_name = '%s'", file_name, temp_file_name) - /* Build new file name for the external file */ - if(H5L_build_name(actual_file_name, temp_file_name, &full_name/*out*/) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") - } /* end if */ - else { - /* Transfer ownership of actual file name to 'full_name' variable */ - full_name = actual_file_name; - actual_file_name = NULL; - } /* end else */ + /* Truncate filename portion from actual file name path */ + *ptr = '\0'; + + /* Build new file name for the external file */ + if(H5L_build_name(actual_file_name, temp_file_name, &full_name/*out*/) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") /* Try opening with the resolved name */ if(NULL == (ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) @@ -254,7 +254,7 @@ done: /*------------------------------------------------------------------------- * Function: H5MF_alloc_create * - * Purpose: Create free space manager of TYPE for the file by creating + * Purpose: Create free space manager of TYPE for the file by creating * a free-space structure * * Return: Success: non-negative @@ -652,7 +652,7 @@ HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, a * Note: this drops the space to free on the floor... * */ - if(f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING || + if(f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING || !H5F_HAVE_FREE_SPACE_MANAGER(f)) { #ifdef H5MF_ALLOC_DEBUG_MORE HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size); @@ -991,6 +991,7 @@ HDfprintf(stderr, "%s: Entering\n", FUNC); HDassert(f); HDassert(f->shared); HDassert(f->shared->lf); + HDassert(f->shared->sblock); /* Free the space in aggregators */ /* (for space not at EOF, it may be put into free space managers) */ diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index db13408..9936c3b 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -77,8 +77,8 @@ /*------------------------------------------------------------------------- * Function: H5MF_aggr_vfd_alloc * - * Purpose: Allocate SIZE bytes of file memory via H5MF_aggr_alloc() - * and return the relative address where that contiguous chunk + * Purpose: Allocate SIZE bytes of file memory via H5MF_aggr_alloc() + * and return the relative address where that contiguous chunk * of file memory exists. * The TYPE argument describes the purpose for which the storage * is being requested. @@ -178,7 +178,7 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); /* * If the aggregation feature is enabled for this file and strategy is not H5F_FILE_SPACE_VFD, - * allocate "generic" space and sub-allocate out of that, if possible. + * allocate "generic" space and sub-allocate out of that, if possible. * Otherwise just allocate through H5FD_alloc(). */ if((f->shared->feature_flags & aggr->feature_flag) && f->shared->fs_strategy != H5F_FILE_SPACE_VFD) { @@ -722,6 +722,6 @@ H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id) if(H5MF_aggr_reset(f, dxpl_id, second_aggr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset 'small data' block") done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5MF_free_aggrs() */ diff --git a/src/H5MFsection.c b/src/H5MFsection.c index d10b6b1..888ce62 100644 --- a/src/H5MFsection.c +++ b/src/H5MFsection.c @@ -480,7 +480,7 @@ H5MF_sect_simple_free(H5FS_section_info_t *_sect) */ static herr_t H5MF_sect_simple_valid(const H5FS_section_class_t UNUSED *cls, - const H5FS_section_info_t + const H5FS_section_info_t #ifdef NDEBUG UNUSED #endif /* NDEBUG */ @@ -112,14 +112,12 @@ H5MM_calloc(size_t size) * Return: Success: Ptr to new memory or NULL if the memory * was freed. * - * Failure: abort() + * Failure: NULL * * Programmer: Robb Matzke * matzke@llnl.gov * Jul 10 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -128,27 +126,24 @@ H5MM_realloc(void *mem, size_t size) void *ret_value; /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_realloc); - - if (!mem) { - if (0 == size) - HGOTO_DONE(NULL); - mem = H5MM_malloc(size); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_realloc) - } else if (0 == size) { + if(NULL == mem) { + if(0 == size) + mem = NULL; + else + mem = H5MM_malloc(size); + } /* end if */ + else if(0 == size) mem = H5MM_xfree(mem); - - } else { + else mem = HDrealloc(mem, size); - assert(mem); - } /* Set return value */ - ret_value=mem; + ret_value = mem; -done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MM_realloc() */ /*------------------------------------------------------------------------- @@ -87,16 +87,16 @@ H5FL_DEFINE(H5MP_pool_t); *------------------------------------------------------------------------- */ H5MP_pool_t * -H5MP_create (size_t page_size, unsigned flags) +H5MP_create(size_t page_size, unsigned flags) { - H5MP_pool_t *mp; /* New memory pool header */ + H5MP_pool_t *mp = NULL; /* New memory pool header */ H5MP_pool_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5MP_create, NULL) /* Allocate space for the pool header */ - if (NULL==(mp = H5FL_MALLOC(H5MP_pool_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for memory pool header") + if(NULL == (mp = H5FL_MALLOC(H5MP_pool_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for memory pool header") /* Assign information */ mp->page_size = H5MP_BLOCK_ALIGN(page_size); @@ -108,13 +108,17 @@ H5MP_create (size_t page_size, unsigned flags) mp->max_size = mp->page_size - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t)); /* Create factory for pool pages */ - if((mp->page_fac=H5FL_fac_init(page_size))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, NULL, "can't create page factory") + if(NULL == (mp->page_fac = H5FL_fac_init(page_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't create page factory") /* Set return value */ ret_value = mp; done: + if(NULL == ret_value && mp) + if(H5MP_close(mp) < 0) + HDONE_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "unable to free memory pool header") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5MP_create() */ @@ -271,7 +275,7 @@ HDfprintf(stderr,"%s: request = %Zu, needed = %Zu\n", FUNC, request, needed); /* Allocate new page */ if(NULL == (alloc_page = H5MP_new_page(mp, page_size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for page") /* Set the block to allocate from */ alloc_free = alloc_page->free_blk; @@ -343,7 +347,7 @@ done: *------------------------------------------------------------------------- */ void * -H5MP_free (H5MP_pool_t *mp, void *spc) +H5MP_free(H5MP_pool_t *mp, void *spc) { H5MP_page_blk_t *spc_blk; /* Block for space to free */ H5MP_page_t *spc_page; /* Page containing block to free */ @@ -430,7 +434,7 @@ HDfprintf(stderr,"%s: Freeing from page = %p\n", "H5MP_free", spc_page); *------------------------------------------------------------------------- */ herr_t -H5MP_close (H5MP_pool_t *mp) +H5MP_close(H5MP_pool_t *mp) { herr_t ret_value = SUCCEED; /* Return value */ @@ -447,9 +451,9 @@ H5MP_close (H5MP_pool_t *mp) /* Free the page appropriately */ if(page->fac_alloc) - H5FL_FAC_FREE(mp->page_fac,page); + page = H5FL_FAC_FREE(mp->page_fac, page); else - H5MM_xfree(page); + page = H5MM_xfree(page); page = next_page; } /* end while */ @@ -457,13 +461,13 @@ H5MP_close (H5MP_pool_t *mp) /* Release page factory */ if(mp->page_fac) - if(H5FL_fac_term(mp->page_fac)<0) - HGOTO_ERROR (H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy page factory") + if(H5FL_fac_term(mp->page_fac) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy page factory") +done: /* Free the memory pool itself */ - (void)H5FL_FREE(H5MP_pool_t, mp); + mp = H5FL_FREE(H5MP_pool_t, mp); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5MP_close() */ @@ -538,6 +538,48 @@ done: /*------------------------------------------------------------------------- + * Function: H5Oexists_by_name + * + * Purpose: Determine if a linked-to object exists + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * February 2 2010 + * + *------------------------------------------------------------------------- + */ +htri_t +H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id) +{ + H5G_loc_t loc; /* Location info */ + hid_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_API(H5Oexists_by_name, FAIL) + H5TRACE3("t", "i*si", loc_id, name, lapl_id); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") + + /* Check if the object exists */ + if((ret_value = H5G_loc_exists(&loc, name, lapl_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", name) + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oexists_by_name() */ + + +/*------------------------------------------------------------------------- * Function: H5Oget_info * * Purpose: Retrieve information about an object. @@ -1134,7 +1176,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, #if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T if(size_hint > 4294967295) oh->flags |= H5O_HDR_CHUNK0_8; - else + else #endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */ if(size_hint > 65535) oh->flags |= H5O_HDR_CHUNK0_4; diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c index 0984cd4..1d9caaa 100644 --- a/src/H5Oainfo.c +++ b/src/H5Oainfo.c @@ -396,13 +396,13 @@ H5O_ainfo_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src, * Return: Success: Ptr to _DEST * Failure: NULL * - * Programmer: Peter Cao + * Programmer: Peter Cao * July 18, 2007 * *------------------------------------------------------------------------- */ static void * -H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, +H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id) { H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src; @@ -475,7 +475,7 @@ H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, HDassert(ainfo_src); if(H5F_addr_defined(ainfo_src->fheap_addr)) { - if ( H5A_dense_post_copy_file_all(src_oloc, ainfo_src, dst_oloc, + if ( H5A_dense_post_copy_file_all(src_oloc, ainfo_src, dst_oloc, (H5O_ainfo_t *)mesg_dst, dxpl_id, cpy_info) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute") } diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index dc72799..bcd0749 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -1186,7 +1186,7 @@ H5O_move_cont(H5F_t *f, H5O_t *oh, unsigned cont_u, hid_t dxpl_id) /* Check arguments. */ HDassert(f); HDassert(oh); - + cont_msg = &oh->mesg[cont_u]; H5O_LOAD_NATIVE(f, dxpl_id, 0, oh, cont_msg, FAIL) deleted_chunkno = ((H5O_cont_t *)(cont_msg->native))->chunkno; diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 4d8b17a..35f02a8 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -234,7 +234,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned UNUSED mesg_fl ret_value = attr; done: - if(NULL == ret_value) { + if(NULL == ret_value) if(attr) { if(attr->shared) { /* Free any dynamicly allocated items */ @@ -244,10 +244,9 @@ done: /* Destroy shared attribute struct */ attr->shared = H5FL_FREE(H5A_shared_t, attr->shared); } /* end if */ - } /* end if */ - attr = H5FL_FREE(H5A_t, attr); - } /* end if */ + attr = H5FL_FREE(H5A_t, attr); + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_decode() */ @@ -662,8 +661,8 @@ H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *mesg_type, HDassert(cpy_info); HDassert(!cpy_info->copy_without_attr); - /* Mark datatype as being on disk now. This step used to be done in a lower level - * by H5O_dtype_decode. But it has been moved up. Not an ideal place, but no better + /* Mark datatype as being on disk now. This step used to be done in a lower level + * by H5O_dtype_decode. But it has been moved up. Not an ideal place, but no better * place than here. */ if(H5T_set_loc(((H5A_t *)native_src)->shared->dt, file_src, H5T_LOC_DISK) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location") diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 8bdbed5..da91782 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -661,12 +661,14 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* Insert the address mapping for the new object into the copied list */ /* (Do this here, because "post copy" possibly checks it) */ - addr_map->src_addr = oloc_src->addr; + H5F_GET_FILENO(oloc_src->file, addr_map->src_obj_pos.fileno); + addr_map->src_obj_pos.addr = oloc_src->addr; addr_map->dst_addr = oloc_dst->addr; addr_map->is_locked = TRUE; /* We've locked the object currently */ addr_map->inc_ref_count = 0; /* Start with no additional ref counts to add */ - if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_addr)) < 0) + /* Insert into skip list */ + if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list") /* "post copy" loop over messages, to fix up any messages which require a complete @@ -765,20 +767,27 @@ herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth) { - H5O_addr_map_t *addr_map; /* Address mapping of object copied */ + H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */ + H5_obj_t src_obj_pos; /* Position of source object */ hbool_t inc_link; /* Whether to increment the link count for the object */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5O_copy_header_map, FAIL) /* Sanity check */ HDassert(oloc_src); + HDassert(oloc_src->file); HDassert(oloc_dst); HDassert(oloc_dst->file); HDassert(cpy_info); - /* Look up the address of the object to copy in the skip list */ - addr_map = (H5O_addr_map_t *)H5SL_search(cpy_info->map_list, &(oloc_src->addr)); + /* Create object "position" struct */ + H5F_GET_FILENO(oloc_src->file, src_obj_pos.fileno); + src_obj_pos.addr = oloc_src->addr; + + /* Search for the object in the skip list of copied objects */ + addr_map = (H5O_addr_map_t *)H5SL_search(cpy_info->map_list, + &src_obj_pos); /* Check if address is already in list of objects copied */ if(addr_map == NULL) { @@ -910,7 +919,7 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, cpy_info.preserve_null = TRUE; /* Create a skip list to keep track of which objects are copied */ - if((cpy_info.map_list = H5SL_create(H5SL_TYPE_HADDR)) == NULL) + if((cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ)) == NULL) HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list") /* copy the object from the source file to the destination file */ @@ -946,6 +955,7 @@ H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, H5G_name_t new_path; /* Copied object group hier. path */ H5O_loc_t new_oloc; /* Copied object object location */ H5G_loc_t new_loc; /* Group location of object copied */ + H5F_t *cached_dst_file; /* Cached destination file */ hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */ unsigned cpy_option = 0; /* Copy options */ herr_t ret_value = SUCCEED; /* Return value */ @@ -972,10 +982,19 @@ H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, H5G_loc_reset(&new_loc); new_oloc.file = dst_loc->oloc->file; + /* Make a copy of the destination file, in case the original is changed by + * H5O_copy_header. If and when oloc's point to the shared file struct, + * this will no longer be necessary, so this code can be removed. */ + cached_dst_file = dst_loc->oloc->file; + /* Copy the object from the source file to the destination file */ if(H5O_copy_header(src_loc->oloc, &new_oloc, dxpl_id, cpy_option) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + /* Patch dst_loc. Again, this can be removed once oloc's point to shared + * file structs. */ + dst_loc->oloc->file = cached_dst_file; + /* Insert the new object in the destination file's group */ if(H5L_link(dst_loc, dst_name, &new_loc, lcpl_id, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") diff --git a/src/H5Odbg.c b/src/H5Odbg.c index b731ce9..9285f4b 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -280,7 +280,7 @@ herr_t H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth) { size_t mesg_total = 0, chunk_total = 0, gap_total = 0; - unsigned *sequence; + unsigned *sequence = NULL; unsigned i; /* Local index variable */ herr_t ret_value = SUCCEED; @@ -508,12 +508,15 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i else HDfprintf(stream, "%*s<No info for this message>\n", indent + 6, ""); } /* end for */ - sequence = (unsigned *)H5MM_xfree(sequence); if((mesg_total + gap_total) != chunk_total) HDfprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n"); done: + /* Release resources */ + if(sequence) + sequence = H5MM_xfree(sequence); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_debug_real() */ diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 0eb4ba2..25cac88 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -262,27 +262,58 @@ H5O_efl_copy(const void *_mesg, void *_dest) /* check args */ HDassert(mesg); if(!dest) { - if(NULL == (dest = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))) || - NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_malloc(mesg->nalloc * sizeof(H5O_efl_entry_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - } else if(dest->nalloc < mesg->nalloc) { - H5MM_xfree(dest->slot); - if(NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_malloc(mesg->nalloc * sizeof(H5O_efl_entry_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - } + if(NULL == (dest = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t)))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message") + if(NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t)))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message slots") + } /* end if */ + else if(dest->nalloc < mesg->nalloc) { + H5O_efl_entry_t *temp_slot; /* Temporary pointer to new slot information */ + + /* Allocate new 'slot' information */ + if(NULL == (temp_slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t)))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message slots") + + /* Release old 'slot' information */ + for(u = 0; u < dest->nused; u++) + dest->slot[u].name = (char *)H5MM_xfree(dest->slot[u].name); + dest->slot = (H5O_efl_entry_t *)H5MM_xfree(dest->slot); + + /* Point to new 'slot' information */ + dest->slot = temp_slot; + } /* end if */ + else { + /* Release old 'slot' information */ + for(u = 0; u < dest->nused; u++) + dest->slot[u].name = (char *)H5MM_xfree(dest->slot[u].name); + } /* end else */ dest->heap_addr = mesg->heap_addr; dest->nalloc = mesg->nalloc; dest->nused = mesg->nused; for(u = 0; u < mesg->nused; u++) { dest->slot[u] = mesg->slot[u]; - dest->slot[u].name = H5MM_xstrdup(mesg->slot[u].name); + if(NULL == (dest->slot[u].name = H5MM_xstrdup(mesg->slot[u].name))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message slot name") } /* end for */ /* Set return value */ ret_value = dest; done: + if(NULL == ret_value) { + if(dest && NULL == _dest) { + if(dest->slot) { + for(u = 0; u < mesg->nused; u++) { + if(dest->slot[u].name != NULL && dest->slot[u].name != mesg->slot[u].name) + dest->slot[u].name = (char *)H5MM_xfree(dest->slot[u].name); + } /* end for */ + dest->slot = (H5O_efl_entry_t *)H5MM_xfree(dest->slot); + } /* end if */ + dest = (H5O_efl_t *)H5MM_xfree(dest); + } /* end if */ + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_efl_copy() */ @@ -353,12 +384,13 @@ H5O_efl_reset(void *_mesg) HDassert(mesg); /* reset */ - for(u = 0; u < mesg->nused; u++) - mesg->slot[u].name = (char *)H5MM_xfree(mesg->slot[u].name); + if(mesg->slot) { + for(u = 0; u < mesg->nused; u++) + mesg->slot[u].name = (char *)H5MM_xfree(mesg->slot[u].name); + mesg->slot = (H5O_efl_entry_t *)H5MM_xfree(mesg->slot); + } /* end if */ mesg->heap_addr = HADDR_UNDEF; mesg->nused = mesg->nalloc = 0; - if(mesg->slot) - mesg->slot = (H5O_efl_entry_t *)H5MM_xfree(mesg->slot); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_efl_reset() */ diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c index fb0151f..0e4fe75 100644 --- a/src/H5Ofsinfo.c +++ b/src/H5Ofsinfo.c @@ -84,7 +84,7 @@ H5FL_DEFINE_STATIC(H5O_fsinfo_t); *------------------------------------------------------------------------- */ static void * -H5O_fsinfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, +H5O_fsinfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p) { H5O_fsinfo_t *fsinfo = NULL; /* free-space manager info */ diff --git a/src/H5Olink.c b/src/H5Olink.c index 4ddfbf6..7ddb1e9 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -437,6 +437,14 @@ H5O_link_copy(const void *_mesg, void *_dest) ret_value = dest; done: + if(NULL == ret_value) + if(dest) { + if(dest->name && dest->name != lnk->name) + dest->name = H5MM_xfree(dest->name); + if(NULL == _dest) + dest = H5FL_FREE(H5O_link_t ,dest); + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_link_copy() */ diff --git a/src/H5Oname.c b/src/H5Oname.c index 5ffa870..01df68c 100644 --- a/src/H5Oname.c +++ b/src/H5Oname.c @@ -185,12 +185,16 @@ H5O_name_copy(const void *_mesg, void *_dest) /* copy */ *dest = *mesg; if(NULL == (dest->s = H5MM_xstrdup(mesg->s))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Set return value */ ret_value = dest; done: + if(NULL == ret_value) + if(dest && NULL == _dest) + dest = H5MM_xfree(dest); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_name_copy() */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 3b738a4..0bab7aa 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -25,6 +25,7 @@ /* Other private headers needed by this file */ #include "H5ACprivate.h" /* Metadata cache */ +#include "H5FLprivate.h" /* Free Lists */ /* Object header macros */ #define H5O_NMESGS 8 /*initial number of messages */ @@ -325,7 +326,7 @@ typedef struct H5O_obj_class_t { /* Node in skip list to map addresses from one file to another during object header copy */ typedef struct H5O_addr_map_t { - haddr_t src_addr; /* Address of object in source file */ + H5_obj_t src_obj_pos; /* Location of source object */ haddr_t dst_addr; /* Address of object in destination file */ hbool_t is_locked; /* Indicate that the destination object is locked currently */ hsize_t inc_ref_count; /* Number of deferred increments to reference count */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index d7e4e04..04338e9 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -119,7 +119,10 @@ typedef struct H5O_t H5O_t; /* Fractal heap ID type for shared message & attribute heap IDs. */ -typedef uint64_t H5O_fheap_id_t; +typedef union { + uint8_t id[H5O_FHEAP_ID_LEN]; /* Buffer to hold ID, for encoding/decoding */ + uint64_t val; /* Value, for quick comparisons */ +} H5O_fheap_id_t; /* The object location information for an object */ typedef struct H5O_loc_t { @@ -622,7 +625,7 @@ typedef unsigned H5O_unknown_t; /* Original message type ID */ /* * Free space manager info Message. - * Contains file space management info and + * Contains file space management info and * addresses of free space managers for file memory * (Data structure in memory) */ diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 84fdecc..c5ae3c1 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -148,6 +148,7 @@ H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id); H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); H5_DLL hid_t H5Oopen_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); +H5_DLL htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id); H5_DLL herr_t H5Oget_info(hid_t loc_id, H5O_info_t *oinfo); H5_DLL herr_t H5Oget_info_by_name(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t lapl_id); diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index d7dccbd..231de3b 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -287,9 +287,9 @@ H5O_sdspace_encode(H5F_t *f, uint8_t *p, const void *_mesg) PURPOSE Copies a message from MESG to DEST, allocating DEST if necessary. USAGE - void *H5O_sdspace_copy(mesg, dest) - const void *mesg; IN: Pointer to the source extent dimensionality struct - const void *dest; IN: Pointer to the destination extent dimensionality struct + void *H5O_sdspace_copy(_mesg, _dest) + const void *_mesg; IN: Pointer to the source extent dimensionality struct + const void *_dest; IN: Pointer to the destination extent dimensionality struct RETURNS Pointer to DEST on success, NULL on failure DESCRIPTION @@ -297,27 +297,31 @@ H5O_sdspace_encode(H5F_t *f, uint8_t *p, const void *_mesg) allocating the destination structure if necessary. --------------------------------------------------------------------------*/ static void * -H5O_sdspace_copy(const void *mesg, void *dest) +H5O_sdspace_copy(const void *_mesg, void *_dest) { - const H5S_extent_t *src = (const H5S_extent_t *) mesg; - H5S_extent_t *dst = (H5S_extent_t *) dest; + const H5S_extent_t *mesg = (const H5S_extent_t *)_mesg; + H5S_extent_t *dest = (H5S_extent_t *)_dest; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_sdspace_copy) /* check args */ - HDassert(src); - if(!dst && NULL == (dst = H5FL_MALLOC(H5S_extent_t))) + HDassert(mesg); + if(!dest && NULL == (dest = H5FL_MALLOC(H5S_extent_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy extent information */ - if(H5S_extent_copy(dst, src, TRUE) < 0) + if(H5S_extent_copy(dest, mesg, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy extent") /* Set return value */ - ret_value = dst; + ret_value = dest; done: + if(NULL == ret_value) + if(dest && NULL != _dest) + dest = H5FL_FREE(H5S_extent_t, dest); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_sdspace_copy() */ diff --git a/src/H5Oshared.c b/src/H5Oshared.c index fd7cc8b..cdd9778 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -731,7 +731,7 @@ H5O_shared_debug(const H5O_shared_t *mesg, FILE *stream, int indent, int fwidth) "SOHM"); HDfprintf(stream, "%*s%-*s %016llx\n", indent, "", fwidth, "Heap ID:", - (unsigned long long)mesg->u.heap_id); + (unsigned long long)mesg->u.heap_id.val); break; case H5O_SHARE_TYPE_HERE: @@ -217,7 +217,7 @@ H5Pcreate_class(hid_t parent, const char *name, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class") /* Create the new property list class */ - if(NULL == (pclass = H5P_create_class(par_class, name, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data))) + if(NULL == (pclass = H5P_create_class(par_class, name, FALSE, cls_create, create_data, cls_copy, copy_data, cls_close, close_data))) HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class") /* Get an atom for the class */ @@ -437,27 +437,43 @@ H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close) { - H5P_genclass_t *pclass; /* Property list class to modify */ - herr_t ret_value; /* return value */ + H5P_genclass_t *pclass; /* Property list class to modify */ + H5P_genclass_t *orig_pclass; /* Original property class */ + herr_t ret_value; /* Return value */ - FUNC_ENTER_API(H5Pregister2, FAIL); + FUNC_ENTER_API(H5Pregister2, FAIL) H5TRACE11("e", "i*sz*xxxxxxxx", cls_id, name, size, def_value, prp_create, prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close); /* Check arguments. */ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(cls_id, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); - if(size>0 && def_value==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name") + if(size > 0 && def_value == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default") /* Create the new property list class */ - if((ret_value = H5P_register(pclass,name,size,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class"); + orig_pclass = pclass; + if((ret_value = H5P_register(&pclass, name, size, def_value, prp_create, prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class") + + /* Check if the property class changed and needs to be substituted in the ID */ + if(pclass != orig_pclass) { + H5P_genclass_t *old_pclass; /* Old property class */ + + /* Substitute the new property class in the ID */ + if(NULL == (old_pclass = (H5P_genclass_t *)H5I_subst(cls_id, pclass))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to substitute property class in ID") + HDassert(old_pclass == orig_pclass); + + /* Close the previous class */ + if(H5P_close_class(orig_pclass) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close original property class after substitution") + } /* end if */ done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } /* H5Pregister2() */ @@ -1259,36 +1275,38 @@ done: herr_t H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name) { - void *src_obj, *dst_obj; /* Property objects to copy between */ - herr_t ret_value=SUCCEED; /* return value */ + H5I_type_t src_id_type, dst_id_type; /* ID types */ + herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_API(H5Pcopy_prop, FAIL); + FUNC_ENTER_API(H5Pcopy_prop, FAIL) H5TRACE3("e", "ii*s", dst_id, src_id, name); /* Check arguments. */ - if((H5I_GENPROP_LST != H5I_get_type(src_id) && H5I_GENPROP_CLS != H5I_get_type(src_id)) - || (H5I_GENPROP_LST != H5I_get_type(dst_id) && H5I_GENPROP_CLS != H5I_get_type(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects"); - if(H5I_get_type(src_id) != H5I_get_type(dst_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects"); + if((src_id_type = H5I_get_type(src_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid source ID") + if((dst_id_type = H5I_get_type(dst_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid destination ID") + if((H5I_GENPROP_LST != src_id_type && H5I_GENPROP_CLS != src_id_type) + || (H5I_GENPROP_LST != dst_id_type && H5I_GENPROP_CLS != dst_id_type)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects") + if(src_id_type != dst_id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects") if(!name || !*name) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given"); - if(NULL == (src_obj = H5I_object(src_id)) || NULL == (dst_obj = H5I_object(dst_id))) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist"); + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") /* Compare property lists */ - if(H5I_GENPROP_LST == H5I_get_type(src_id)) { + if(H5I_GENPROP_LST == src_id_type) { if(H5P_copy_prop_plist(dst_id, src_id, name) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between lists"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between lists") } /* end if */ /* Must be property classes */ else { - if(H5P_copy_prop_pclass((H5P_genclass_t *)dst_obj, (H5P_genclass_t *)src_obj, name) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between classes"); + if(H5P_copy_prop_pclass(dst_id, src_id, name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between classes") } /* end else */ done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } /* H5Pcopy_prop() */ diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c index db66366..356c42d 100644 --- a/src/H5Pdapl.c +++ b/src/H5Pdapl.c @@ -129,15 +129,15 @@ H5P_dacc_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_dacc_reg_prop) /* Register the size of raw data chunk cache (elements) */ - if(H5P_register(pclass, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE, &rdcc_nslots, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5D_ACS_DATA_CACHE_NUM_SLOTS_SIZE, &rdcc_nslots, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the size of raw data chunk cache(bytes) */ - if(H5P_register(pclass, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, H5D_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the preemption for reading chunks */ - if(H5P_register(pclass, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, H5D_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, H5D_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index f62d47c..0f16fd3 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -36,8 +36,9 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5Dpkg.h" /* Datasets */ +#include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Ppkg.h" /* Property lists */ @@ -185,19 +186,19 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_dcrt_reg_prop) /* Register the storage layout property */ - if(H5P_register(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &layout, NULL, NULL, NULL, NULL, NULL, H5D_CRT_LAYOUT_CMP, NULL) < 0) + if(H5P_register_real(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &layout, NULL, NULL, NULL, NULL, NULL, H5D_CRT_LAYOUT_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the fill value property */ - if(H5P_register(pclass, H5D_CRT_FILL_VALUE_NAME, H5D_CRT_FILL_VALUE_SIZE, &fill, NULL, NULL, NULL, NULL, NULL, H5D_CRT_FILL_VALUE_CMP, NULL) < 0) + if(H5P_register_real(pclass, H5D_CRT_FILL_VALUE_NAME, H5D_CRT_FILL_VALUE_SIZE, &fill, NULL, NULL, NULL, NULL, NULL, H5D_CRT_FILL_VALUE_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the space allocation time state property */ - if(H5P_register(pclass, H5D_CRT_ALLOC_TIME_STATE_NAME, H5D_CRT_ALLOC_TIME_STATE_SIZE, &alloc_time_state, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_CRT_ALLOC_TIME_STATE_NAME, H5D_CRT_ALLOC_TIME_STATE_SIZE, &alloc_time_state, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the external file list property */ - if(H5P_register(pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &efl, NULL, NULL, NULL, NULL, NULL, H5D_CRT_EXT_FILE_LIST_CMP, NULL) < 0) + if(H5P_register_real(pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &efl, NULL, NULL, NULL, NULL, NULL, H5D_CRT_EXT_FILE_LIST_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pdeprec.c b/src/H5Pdeprec.c index 5c72247..1528df5 100644 --- a/src/H5Pdeprec.c +++ b/src/H5Pdeprec.c @@ -249,8 +249,9 @@ H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close) { - H5P_genclass_t *pclass; /* Property list class to modify */ - herr_t ret_value; /* return value */ + H5P_genclass_t *pclass; /* Property list class to modify */ + H5P_genclass_t *orig_pclass; /* Original property class */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(H5Pregister1, FAIL); H5TRACE10("e", "i*sz*xxxxxxx", cls_id, name, size, def_value, prp_create, @@ -265,9 +266,24 @@ H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); /* Create the new property list class */ - if((ret_value = H5P_register(pclass, name, size, def_value, prp_create, prp_set, prp_get, prp_delete, prp_copy, NULL, prp_close)) < 0) + orig_pclass = pclass; + if((ret_value = H5P_register(&pclass, name, size, def_value, prp_create, prp_set, prp_get, prp_delete, prp_copy, NULL, prp_close)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class"); + /* Check if the property class changed and needs to be substituted in the ID */ + if(pclass != orig_pclass) { + H5P_genclass_t *old_pclass; /* Old property class */ + + /* Substitute the new property class in the ID */ + if(NULL == (old_pclass = (H5P_genclass_t *)H5I_subst(cls_id, pclass))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to substitute property class in ID") + HDassert(old_pclass == orig_pclass); + + /* Close the previous class */ + if(H5P_close_class(orig_pclass) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close original property class after substitution") + } /* end if */ + done: FUNC_LEAVE_API(ret_value); } /* H5Pregister1() */ diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index aab8b57..1186868 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -210,81 +210,81 @@ H5P_dxfr_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_dxfr_reg_prop) /* Register the max. temp buffer size property */ - if(H5P_register(pclass, H5D_XFER_MAX_TEMP_BUF_NAME, H5D_XFER_MAX_TEMP_BUF_SIZE, &def_max_temp_buf, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_MAX_TEMP_BUF_NAME, H5D_XFER_MAX_TEMP_BUF_SIZE, &def_max_temp_buf, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the type conversion buffer property */ - if(H5P_register(pclass, H5D_XFER_TCONV_BUF_NAME, H5D_XFER_TCONV_BUF_SIZE, &def_tconv_buf, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_TCONV_BUF_NAME, H5D_XFER_TCONV_BUF_SIZE, &def_tconv_buf, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the background buffer property */ - if(H5P_register(pclass, H5D_XFER_BKGR_BUF_NAME, H5D_XFER_BKGR_BUF_SIZE, &def_bkgr_buf, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_BKGR_BUF_NAME, H5D_XFER_BKGR_BUF_SIZE, &def_bkgr_buf, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the background buffer type property */ - if(H5P_register(pclass, H5D_XFER_BKGR_BUF_TYPE_NAME, H5D_XFER_BKGR_BUF_TYPE_SIZE, &def_bkgr_buf_type, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_BKGR_BUF_TYPE_NAME, H5D_XFER_BKGR_BUF_TYPE_SIZE, &def_bkgr_buf_type, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the B-Tree node splitting ratios property */ - if(H5P_register(pclass, H5D_XFER_BTREE_SPLIT_RATIO_NAME, H5D_XFER_BTREE_SPLIT_RATIO_SIZE, def_btree_split_ratio, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_BTREE_SPLIT_RATIO_NAME, H5D_XFER_BTREE_SPLIT_RATIO_SIZE, def_btree_split_ratio, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the vlen allocation function property */ - if(H5P_register(pclass, H5D_XFER_VLEN_ALLOC_NAME, H5D_XFER_VLEN_ALLOC_SIZE, &def_vlen_alloc, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_VLEN_ALLOC_NAME, H5D_XFER_VLEN_ALLOC_SIZE, &def_vlen_alloc, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the vlen allocation information property */ - if(H5P_register(pclass, H5D_XFER_VLEN_ALLOC_INFO_NAME, H5D_XFER_VLEN_ALLOC_INFO_SIZE, &def_vlen_alloc_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_VLEN_ALLOC_INFO_NAME, H5D_XFER_VLEN_ALLOC_INFO_SIZE, &def_vlen_alloc_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the vlen free function property */ - if(H5P_register(pclass, H5D_XFER_VLEN_FREE_NAME, H5D_XFER_VLEN_FREE_SIZE, &def_vlen_free, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_VLEN_FREE_NAME, H5D_XFER_VLEN_FREE_SIZE, &def_vlen_free, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the vlen free information property */ - if(H5P_register(pclass, H5D_XFER_VLEN_FREE_INFO_NAME, H5D_XFER_VLEN_FREE_INFO_SIZE, &def_vlen_free_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_VLEN_FREE_INFO_NAME, H5D_XFER_VLEN_FREE_INFO_SIZE, &def_vlen_free_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the file driver ID property */ - if(H5P_register(pclass, H5D_XFER_VFL_ID_NAME, H5D_XFER_VFL_ID_SIZE, &def_vfl_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_VFL_ID_NAME, H5D_XFER_VFL_ID_SIZE, &def_vfl_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the file driver info property */ - if(H5P_register(pclass, H5D_XFER_VFL_INFO_NAME, H5D_XFER_VFL_INFO_SIZE, &def_vfl_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_VFL_INFO_NAME, H5D_XFER_VFL_INFO_SIZE, &def_vfl_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the vector size property */ - if(H5P_register(pclass, H5D_XFER_HYPER_VECTOR_SIZE_NAME, H5D_XFER_HYPER_VECTOR_SIZE_SIZE, &def_hyp_vec_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_HYPER_VECTOR_SIZE_NAME, H5D_XFER_HYPER_VECTOR_SIZE_SIZE, &def_hyp_vec_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") #ifdef H5_HAVE_PARALLEL /* Register the I/O transfer mode property */ - if(H5P_register(pclass, H5D_XFER_IO_XFER_MODE_NAME, H5D_XFER_IO_XFER_MODE_SIZE, &def_io_xfer_mode, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_IO_XFER_MODE_NAME, H5D_XFER_IO_XFER_MODE_SIZE, &def_io_xfer_mode, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - if(H5P_register(pclass, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, H5D_XFER_MPIO_COLLECTIVE_OPT_SIZE, &def_mpio_collective_opt_mode, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, H5D_XFER_MPIO_COLLECTIVE_OPT_SIZE, &def_mpio_collective_opt_mode, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - if(H5P_register(pclass, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME, H5D_XFER_MPIO_CHUNK_OPT_HARD_SIZE, &def_mpio_chunk_opt_mode, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME, H5D_XFER_MPIO_CHUNK_OPT_HARD_SIZE, &def_mpio_chunk_opt_mode, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - if(H5P_register(pclass, H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME, H5D_XFER_MPIO_CHUNK_OPT_NUM_SIZE, &def_mpio_chunk_opt_num, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME, H5D_XFER_MPIO_CHUNK_OPT_NUM_SIZE, &def_mpio_chunk_opt_num, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - if(H5P_register(pclass, H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME, H5D_XFER_MPIO_CHUNK_OPT_RATIO_SIZE, &def_mpio_chunk_opt_ratio, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME, H5D_XFER_MPIO_CHUNK_OPT_RATIO_SIZE, &def_mpio_chunk_opt_ratio, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") #endif /* H5_HAVE_PARALLEL */ /* Register the EDC property */ - if(H5P_register(pclass, H5D_XFER_EDC_NAME, H5D_XFER_EDC_SIZE, &enable_edc, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_EDC_NAME, H5D_XFER_EDC_SIZE, &enable_edc, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the filter callback property */ - if(H5P_register(pclass, H5D_XFER_FILTER_CB_NAME, H5D_XFER_FILTER_CB_SIZE, &filter_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_FILTER_CB_NAME, H5D_XFER_FILTER_CB_SIZE, &filter_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the type conversion callback property */ - if(H5P_register(pclass, H5D_XFER_CONV_CB_NAME, H5D_XFER_CONV_CB_SIZE, &conv_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5D_XFER_CONV_CB_NAME, H5D_XFER_CONV_CB_SIZE, &conv_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the data transform property */ - if(H5P_register(pclass, H5D_XFER_XFORM_NAME, H5D_XFER_XFORM_SIZE, &def_xfer_xform, NULL, NULL, NULL, H5D_XFER_XFORM_DEL, H5D_XFER_XFORM_COPY, NULL, H5D_XFER_XFORM_CLOSE) < 0) + if(H5P_register_real(pclass, H5D_XFER_XFORM_NAME, H5D_XFER_XFORM_SIZE, &def_xfer_xform, NULL, NULL, NULL, H5D_XFER_XFORM_DEL, H5D_XFER_XFORM_COPY, NULL, H5D_XFER_XFORM_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 5d73afe..07b66e7 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -34,6 +34,7 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ @@ -215,80 +216,80 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_facc_reg_prop) /* Register the initial metadata cache resize configuration */ - if(H5P_register(pclass, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, H5F_ACS_META_CACHE_INIT_CONFIG_SIZE, &mdc_initCacheCfg, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, H5F_ACS_META_CACHE_INIT_CONFIG_SIZE, &mdc_initCacheCfg, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the size of raw data chunk cache (elements) */ - if(H5P_register(pclass, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5F_ACS_DATA_CACHE_NUM_SLOTS_SIZE, &rdcc_nslots, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, H5F_ACS_DATA_CACHE_NUM_SLOTS_SIZE, &rdcc_nslots, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the size of raw data chunk cache(bytes) */ - if(H5P_register(pclass, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, H5F_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, H5F_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the preemption for reading chunks */ - if(H5P_register(pclass, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, H5F_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, H5F_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the threshold for alignment */ - if(H5P_register(pclass, H5F_ACS_ALIGN_THRHD_NAME, H5F_ACS_ALIGN_THRHD_SIZE, &threshold, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_ALIGN_THRHD_NAME, H5F_ACS_ALIGN_THRHD_SIZE, &threshold, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the alignment */ - if(H5P_register(pclass, H5F_ACS_ALIGN_NAME, H5F_ACS_ALIGN_SIZE, &alignment, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_ALIGN_NAME, H5F_ACS_ALIGN_SIZE, &alignment, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the minimum metadata allocation block size */ - if(H5P_register(pclass, H5F_ACS_META_BLOCK_SIZE_NAME, H5F_ACS_META_BLOCK_SIZE_SIZE, &meta_block_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_META_BLOCK_SIZE_NAME, H5F_ACS_META_BLOCK_SIZE_SIZE, &meta_block_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the maximum sieve buffer size */ - if(H5P_register(pclass, H5F_ACS_SIEVE_BUF_SIZE_NAME, H5F_ACS_SIEVE_BUF_SIZE_SIZE, &sieve_buf_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_SIEVE_BUF_SIZE_NAME, H5F_ACS_SIEVE_BUF_SIZE_SIZE, &sieve_buf_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the minimum "small data" allocation block size */ - if(H5P_register(pclass, H5F_ACS_SDATA_BLOCK_SIZE_NAME, H5F_ACS_SDATA_BLOCK_SIZE_SIZE, &sdata_block_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_SDATA_BLOCK_SIZE_NAME, H5F_ACS_SDATA_BLOCK_SIZE_SIZE, &sdata_block_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the garbage collection reference */ - if(H5P_register(pclass, H5F_ACS_GARBG_COLCT_REF_NAME, H5F_ACS_GARBG_COLCT_REF_SIZE, &gc_ref, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_GARBG_COLCT_REF_NAME, H5F_ACS_GARBG_COLCT_REF_SIZE, &gc_ref, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the file driver ID */ - if(H5P_register(pclass, H5F_ACS_FILE_DRV_ID_NAME, H5F_ACS_FILE_DRV_ID_SIZE, &driver_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_FILE_DRV_ID_NAME, H5F_ACS_FILE_DRV_ID_SIZE, &driver_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the file driver info */ - if(H5P_register(pclass, H5F_ACS_FILE_DRV_INFO_NAME, H5F_ACS_FILE_DRV_INFO_SIZE, &driver_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_FILE_DRV_INFO_NAME, H5F_ACS_FILE_DRV_INFO_SIZE, &driver_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the file close degree */ - if(H5P_register(pclass, H5F_ACS_CLOSE_DEGREE_NAME, H5F_CLOSE_DEGREE_SIZE, &close_degree, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_CLOSE_DEGREE_NAME, H5F_CLOSE_DEGREE_SIZE, &close_degree, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the offset of family driver info */ - if(H5P_register(pclass, H5F_ACS_FAMILY_OFFSET_NAME, H5F_ACS_FAMILY_OFFSET_SIZE, &family_offset, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_FAMILY_OFFSET_NAME, H5F_ACS_FAMILY_OFFSET_SIZE, &family_offset, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the private property of new family file size. It's used by h5repart only. */ - if(H5P_register(pclass, H5F_ACS_FAMILY_NEWSIZE_NAME, H5F_ACS_FAMILY_NEWSIZE_SIZE, &family_newsize, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_FAMILY_NEWSIZE_NAME, H5F_ACS_FAMILY_NEWSIZE_SIZE, &family_newsize, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the private property of whether convert family to sec2 driver. It's used by h5repart only. */ - if(H5P_register(pclass, H5F_ACS_FAMILY_TO_SEC2_NAME, H5F_ACS_FAMILY_TO_SEC2_SIZE, &family_to_sec2, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_FAMILY_TO_SEC2_NAME, H5F_ACS_FAMILY_TO_SEC2_SIZE, &family_to_sec2, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the data type of multi driver info */ - if(H5P_register(pclass, H5F_ACS_MULTI_TYPE_NAME, H5F_ACS_MULTI_TYPE_SIZE, &mem_type, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_MULTI_TYPE_NAME, H5F_ACS_MULTI_TYPE_SIZE, &mem_type, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the 'use the latest version of the format' flag */ - if(H5P_register(pclass, H5F_ACS_LATEST_FORMAT_NAME, H5F_ACS_LATEST_FORMAT_SIZE, &latest_format, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_LATEST_FORMAT_NAME, H5F_ACS_LATEST_FORMAT_SIZE, &latest_format, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the private property of whether to retrieve the file descriptor from the core VFD */ /* (used internally to the library only) */ - if(H5P_register(pclass, H5F_ACS_WANT_POSIX_FD_NAME, H5F_ACS_WANT_POSIX_FD_SIZE, &want_posix_fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_ACS_WANT_POSIX_FD_NAME, H5F_ACS_WANT_POSIX_FD_SIZE, &want_posix_fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pfcpl.c b/src/H5Pfcpl.c index cb3bccd..a0f2f89 100644 --- a/src/H5Pfcpl.c +++ b/src/H5Pfcpl.c @@ -162,49 +162,49 @@ H5P_fcrt_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_fcrt_reg_prop) /* Register the user block size */ - if(H5P_register(pclass, H5F_CRT_USER_BLOCK_NAME, H5F_CRT_USER_BLOCK_SIZE, &userblock_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_USER_BLOCK_NAME, H5F_CRT_USER_BLOCK_SIZE, &userblock_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the 1/2 rank for symbol table leaf nodes */ - if(H5P_register(pclass, H5F_CRT_SYM_LEAF_NAME, H5F_CRT_SYM_LEAF_SIZE, &sym_leaf_k, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_SYM_LEAF_NAME, H5F_CRT_SYM_LEAF_SIZE, &sym_leaf_k, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the 1/2 rank for btree internal nodes */ - if(H5P_register(pclass, H5F_CRT_BTREE_RANK_NAME, H5F_CRT_BTREE_RANK_SIZE, btree_k, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_BTREE_RANK_NAME, H5F_CRT_BTREE_RANK_SIZE, btree_k, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the byte number for an address */ - if(H5P_register(pclass, H5F_CRT_ADDR_BYTE_NUM_NAME, H5F_CRT_ADDR_BYTE_NUM_SIZE, &sizeof_addr, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_ADDR_BYTE_NUM_NAME, H5F_CRT_ADDR_BYTE_NUM_SIZE, &sizeof_addr, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the byte number for object size */ - if(H5P_register(pclass, H5F_CRT_OBJ_BYTE_NUM_NAME, H5F_CRT_OBJ_BYTE_NUM_SIZE, &sizeof_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_OBJ_BYTE_NUM_NAME, H5F_CRT_OBJ_BYTE_NUM_SIZE, &sizeof_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the superblock version number */ - if(H5P_register(pclass, H5F_CRT_SUPER_VERS_NAME, H5F_CRT_SUPER_VERS_SIZE, &superblock_ver, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_SUPER_VERS_NAME, H5F_CRT_SUPER_VERS_SIZE, &superblock_ver, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the shared OH message information */ - if(H5P_register(pclass,H5F_CRT_SHMSG_NINDEXES_NAME, H5F_CRT_SHMSG_NINDEXES_SIZE, &num_sohm_indexes,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register_real(pclass,H5F_CRT_SHMSG_NINDEXES_NAME, H5F_CRT_SHMSG_NINDEXES_SIZE, &num_sohm_indexes,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - if(H5P_register(pclass,H5F_CRT_SHMSG_INDEX_TYPES_NAME, H5F_CRT_SHMSG_INDEX_TYPES_SIZE, &sohm_index_flags,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register_real(pclass,H5F_CRT_SHMSG_INDEX_TYPES_NAME, H5F_CRT_SHMSG_INDEX_TYPES_SIZE, &sohm_index_flags,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - if(H5P_register(pclass,H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, H5F_CRT_SHMSG_INDEX_MINSIZE_SIZE, &sohm_index_minsizes,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register_real(pclass,H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, H5F_CRT_SHMSG_INDEX_MINSIZE_SIZE, &sohm_index_minsizes,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the shared OH cutoff size information */ - if(H5P_register(pclass,H5F_CRT_SHMSG_LIST_MAX_NAME, H5F_CRT_SHMSG_LIST_MAX_SIZE, &sohm_list_max,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register_real(pclass,H5F_CRT_SHMSG_LIST_MAX_NAME, H5F_CRT_SHMSG_LIST_MAX_SIZE, &sohm_list_max,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - if(H5P_register(pclass,H5F_CRT_SHMSG_BTREE_MIN_NAME, H5F_CRT_SHMSG_BTREE_MIN_SIZE, &sohm_btree_min,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register_real(pclass,H5F_CRT_SHMSG_BTREE_MIN_NAME, H5F_CRT_SHMSG_BTREE_MIN_SIZE, &sohm_btree_min,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the file space handling strategy */ - if(H5P_register(pclass, H5F_CRT_FILE_SPACE_STRATEGY_NAME, H5F_CRT_FILE_SPACE_STRATEGY_SIZE, &file_space_strategy, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_FILE_SPACE_STRATEGY_NAME, H5F_CRT_FILE_SPACE_STRATEGY_SIZE, &file_space_strategy, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the free space section threshold */ - if(H5P_register(pclass, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, H5F_CRT_FREE_SPACE_THRESHOLD_SIZE, &free_space_threshold, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, H5F_CRT_FREE_SPACE_THRESHOLD_SIZE, &free_space_threshold, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Pfmpl.c b/src/H5Pfmpl.c index ab405ca..43c6055 100644 --- a/src/H5Pfmpl.c +++ b/src/H5Pfmpl.c @@ -113,7 +113,7 @@ H5P_fmnt_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_fmnt_reg_prop) /* Register property of whether symlinks is local to file */ - if(H5P_register(pclass, H5F_MNT_SYM_LOCAL_NAME, H5F_MNT_SYM_LOCAL_SIZE, &local, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5F_MNT_SYM_LOCAL_NAME, H5F_MNT_SYM_LOCAL_SIZE, &local, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c index 913c5f1..72784eb 100644 --- a/src/H5Pgcpl.c +++ b/src/H5Pgcpl.c @@ -113,13 +113,11 @@ H5P_gcrt_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_gcrt_reg_prop) /* Register group info property */ - if(H5P_register(pclass, H5G_CRT_GROUP_INFO_NAME, H5G_CRT_GROUP_INFO_SIZE, - &ginfo, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5G_CRT_GROUP_INFO_NAME, H5G_CRT_GROUP_INFO_SIZE, &ginfo, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register link info property */ - if(H5P_register(pclass, H5G_CRT_LINK_INFO_NAME, H5G_CRT_LINK_INFO_SIZE, - &linfo, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5G_CRT_LINK_INFO_NAME, H5G_CRT_LINK_INFO_SIZE, &linfo, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pint.c b/src/H5Pint.c index 7111cba..46a4ee3 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -265,29 +265,29 @@ H5P_do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb) H5P_genprop_t *pcopy=NULL; /* Copy of property to insert into skip list */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_do_prop_cb1); + FUNC_ENTER_NOAPI_NOINIT(H5P_do_prop_cb1) /* Allocate space for a temporary copy of the property value */ if(NULL == (tmp_value = H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value") HDmemcpy(tmp_value,prop->value,prop->size); /* Call "type 1" callback ('create', 'copy' or 'close') */ if(cb(prop->name,prop->size,tmp_value) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed") /* Check if the property value changed */ if((prop->cmp)(tmp_value,prop->value,prop->size)) { /* Make a copy of the class's property */ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property") /* Copy the changed value into the new property */ HDmemcpy(pcopy->value,tmp_value,prop->size); /* Insert the changed property into the property list */ if(H5P_add_prop(slist,pcopy) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into skip list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into skip list") } /* end if */ done: @@ -301,7 +301,7 @@ done: H5P_free_prop(pcopy); } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_do_prop_cb1() */ @@ -451,7 +451,7 @@ H5P_term_interface(void) int nclass=0; int n=0; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_term_interface); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_term_interface) if(H5_interface_initialize_g) { /* Destroy HDF5 library property classes & lists */ @@ -520,7 +520,7 @@ H5P_term_interface(void) H5_interface_initialize_g = 0; } } - FUNC_LEAVE_NOAPI(n); + FUNC_LEAVE_NOAPI(n) } @@ -551,9 +551,9 @@ H5P_copy_pclass(H5P_genclass_t *pclass) H5P_genprop_t *pcopy; /* Copy of property to insert into class */ H5P_genclass_t *ret_value=NULL; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_copy_pclass); + FUNC_ENTER_NOAPI_NOINIT(H5P_copy_pclass) - assert(pclass); + HDassert(pclass); /* * Create new property class object @@ -561,7 +561,7 @@ H5P_copy_pclass(H5P_genclass_t *pclass) /* Create the new property list class */ if(NULL==(new_pclass=H5P_create_class(pclass->parent, pclass->name, 0, pclass->create_func, pclass->create_data, pclass->copy_func, pclass->copy_data, pclass->close_func, pclass->close_data))) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class") /* Copy the properties registered for this class */ if(pclass->nprops>0) { @@ -572,11 +572,11 @@ H5P_copy_pclass(H5P_genclass_t *pclass) while(curr_node!=NULL) { /* Make a copy of the class's property */ if(NULL == (pcopy = H5P_dup_prop((H5P_genprop_t *)H5SL_item(curr_node), H5P_PROP_WITHIN_CLASS))) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property") /* Insert the initialized property into the property list */ if(H5P_add_prop(new_pclass->props,pcopy) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class") /* Increment property count for class */ new_pclass->nprops++; @@ -593,7 +593,7 @@ done: if(ret_value==NULL && new_pclass) H5P_close_class(new_pclass); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_copy_pclass() */ @@ -632,9 +632,9 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */ hid_t ret_value=FAIL; /* return value */ - FUNC_ENTER_NOAPI(H5P_copy_plist, FAIL); + FUNC_ENTER_NOAPI(H5P_copy_plist, FAIL) - assert(old_plist); + HDassert(old_plist); /* * Create new property list object @@ -642,20 +642,20 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) /* Allocate room for the property list */ if(NULL==(new_plist = H5FL_CALLOC(H5P_genplist_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,"memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,"memory allocation failed") /* Set class state */ new_plist->pclass = old_plist->pclass; new_plist->nprops = 0; /* Initially the plist has the same number of properties as the class */ - new_plist->class_init = 0; /* Initially, wait until the class callback finishes to set */ + new_plist->class_init = FALSE; /* Initially, wait until the class callback finishes to set */ /* Initialize the skip list to hold the changed properties */ if((new_plist->props = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties") /* Create the skip list for deleted properties */ if((new_plist->del = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties") /* Create the skip list to hold names of properties already seen * (This prevents a property in the class hierarchy from having it's @@ -663,7 +663,7 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) * already been seen) */ if((seen = H5SL_create(H5SL_TYPE_STR))== NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties") nseen = 0; /* Cycle through the deleted properties & copy them into the new list's deleted section */ @@ -674,15 +674,15 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) /* Duplicate string for insertion into new deleted property skip list */ if((new_name=H5MM_xstrdup((char *)H5SL_item(curr_node))) == NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed") /* Insert property name into deleted list */ if(H5SL_insert(new_plist->del,new_name,new_name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list") /* Add property name to "seen" list */ if(H5SL_insert(seen,new_name,new_name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list") nseen++; /* Get the next property node in the skip list */ @@ -705,19 +705,19 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) if(new_prop->copy) { if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value) < 0) { H5P_free_prop(new_prop); - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property") } /* end if */ } /* end if */ /* Insert the initialized property into the property list */ if(H5P_add_prop(new_plist->props,new_prop) < 0) { H5P_free_prop(new_prop); - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list") } /* end if */ /* Add property name to "seen" list */ if(H5SL_insert(seen,new_prop->name,new_prop->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list") nseen++; /* Increment the number of properties in list */ @@ -748,13 +748,13 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) if(tmp->copy) { /* Call the callback & insert changed value into skip list (if necessary) */ if(H5P_do_prop_cb1(new_plist->props,tmp,tmp->copy) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't create property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't create property") } /* end if */ /* Add property name to "seen" list, if we have other classes to work on */ if(has_parent_class) { if(H5SL_insert(seen,tmp->name,tmp->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list") nseen++; } /* end if */ @@ -772,12 +772,12 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) } /* end while */ /* Increment the number of property lists derived from class */ - if(H5P_access_class(new_plist->pclass,H5P_MOD_INC_LST) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ref count"); + if(H5P_access_class(new_plist->pclass, H5P_MOD_INC_LST) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "Can't increment class ref count") /* Get an atom for the property list */ if((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist, app_ref)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list") /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */ new_plist->plist_id=new_plist_id; @@ -800,7 +800,7 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) } /* end while */ /* Set the class initialization flag */ - new_plist->class_init=1; + new_plist->class_init = TRUE; /* Set the return value */ ret_value=new_plist_id; @@ -813,7 +813,7 @@ done: if(ret_value<0 && new_plist) H5P_close(new_plist); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_copy_plist() */ @@ -859,7 +859,7 @@ H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type) /* Duplicating property for a class */ if(type == H5P_PROP_WITHIN_CLASS) { HDassert(oprop->type == H5P_PROP_WITHIN_CLASS); - HDassert(oprop->shared_name == 0); + HDassert(oprop->shared_name == FALSE); /* Duplicate name */ prop->name = H5MM_xstrdup(oprop->name); @@ -877,10 +877,10 @@ H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type) /* Duplicating a property from a class */ else { HDassert(oprop->type == H5P_PROP_WITHIN_CLASS); - HDassert(oprop->shared_name == 0); + HDassert(oprop->shared_name == FALSE); /* Share the name */ - prop->shared_name = 1; + prop->shared_name = TRUE; /* Set the type */ prop->type = type; @@ -956,26 +956,26 @@ H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type, H5P_genprop_t *prop=NULL; /* Pointer to new property copied */ H5P_genprop_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_create_prop); + FUNC_ENTER_NOAPI_NOINIT(H5P_create_prop) - assert(name); - assert((size>0 && value!=NULL) || (size==0)); - assert(type!=H5P_PROP_WITHIN_UNKNOWN); + HDassert(name); + HDassert((size>0 && value!=NULL) || (size==0)); + HDassert(type!=H5P_PROP_WITHIN_UNKNOWN); /* Allocate the new property */ if(NULL==(prop = H5FL_MALLOC (H5P_genprop_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Set the property initial values */ prop->name = H5MM_xstrdup(name); /* Duplicate name */ - prop->shared_name=0; - prop->size=size; - prop->type=type; + prop->shared_name = FALSE; + prop->size = size; + prop->type = type; /* Duplicate value, if it exists */ if(value!=NULL) { if(NULL==(prop->value = H5MM_malloc (prop->size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemcpy(prop->value,value,prop->size); } /* end if */ else @@ -1009,7 +1009,7 @@ done: } /* end if */ } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_create_prop() */ @@ -1034,21 +1034,21 @@ done: herr_t H5P_add_prop(H5SL_t *slist, H5P_genprop_t *prop) { - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5P_add_prop,FAIL); + FUNC_ENTER_NOAPI(H5P_add_prop, FAIL) - assert(slist); - assert(prop); - assert(prop->type!=H5P_PROP_WITHIN_UNKNOWN); + HDassert(slist); + HDassert(prop); + HDassert(prop->type != H5P_PROP_WITHIN_UNKNOWN); /* Insert property into skip list */ - if(H5SL_insert(slist,prop,prop->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into skip list"); + if(H5SL_insert(slist, prop, prop->name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into skip list") done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_add_prop() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P_add_prop() */ /*-------------------------------------------------------------------------- @@ -1169,21 +1169,21 @@ done: static herr_t H5P_free_prop(H5P_genprop_t *prop) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop) - assert(prop); + HDassert(prop); /* Release the property value if it exists */ if(prop->value) H5MM_xfree(prop->value); /* Only free the name if we own it */ - if(prop->shared_name==0) + if(!prop->shared_name) H5MM_xfree(prop->name); - (void)H5FL_FREE(H5P_genprop_t, prop); + prop = H5FL_FREE(H5P_genprop_t, prop); - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5P_free_prop() */ @@ -1210,21 +1210,21 @@ H5P_free_prop(H5P_genprop_t *prop) static herr_t H5P_free_prop_cb(void *item, void UNUSED *key, void *op_data) { - H5P_genprop_t *tprop=(H5P_genprop_t *)item; /* Temporary pointer to property */ - unsigned make_cb=*(unsigned *)op_data; /* Whether to make property 'close' callback */ + H5P_genprop_t *tprop=(H5P_genprop_t *)item; /* Temporary pointer to property */ + hbool_t make_cb = *(hbool_t *)op_data; /* Whether to make property 'close' callback */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop_cb); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop_cb) - assert(tprop); + HDassert(tprop); /* Call the close callback and ignore the return value, there's nothing we can do about it */ - if(make_cb && tprop->close!=NULL) - (tprop->close)(tprop->name,tprop->size,tprop->value); + if(make_cb && tprop->close != NULL) + (tprop->close)(tprop->name, tprop->size, tprop->value); /* Free the property, ignoring return value, nothing we can do */ H5P_free_prop(tprop); - FUNC_LEAVE_NOAPI(0); + FUNC_LEAVE_NOAPI(0) } /* H5P_free_prop_cb() */ @@ -1252,14 +1252,14 @@ H5P_free_del_name_cb(void *item, void UNUSED *key, void UNUSED *op_data) { char *del_name=(char *)item; /* Temporary pointer to deleted name */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_del_name_cb); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_del_name_cb) - assert(del_name); + HDassert(del_name); /* Free the name */ H5MM_xfree(del_name); - FUNC_LEAVE_NOAPI(0); + FUNC_LEAVE_NOAPI(0) } /* H5P_free_del_name_cb() */ @@ -1288,10 +1288,10 @@ H5P_free_del_name_cb(void *item, void UNUSED *key, void UNUSED *op_data) herr_t H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_access_class); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_access_class) - assert(pclass); - assert(mod>H5P_MOD_ERR && mod<H5P_MOD_MAX); + HDassert(pclass); + HDassert(mod > H5P_MOD_ERR && mod < H5P_MOD_MAX); switch(mod) { case H5P_MOD_INC_CLS: /* Increment the dependant class count*/ @@ -1313,7 +1313,7 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) case H5P_MOD_INC_REF: /* Increment the ID reference count*/ /* Reset the deleted flag if incrementing the reference count */ if(pclass->deleted) - pclass->deleted=0; + pclass->deleted = FALSE; pclass->ref_count++; break; @@ -1321,8 +1321,8 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) pclass->ref_count--; /* Mark the class object as deleted if reference count drops to zero */ - if(pclass->ref_count==0) - pclass->deleted=1; + if(pclass->ref_count == 0) + pclass->deleted = TRUE; break; case H5P_MOD_ERR: @@ -1332,27 +1332,27 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) } /* end switch */ /* Check if we can release the class information now */ - if(pclass->deleted && pclass->plists==0 && pclass->classes==0 ) { - H5P_genclass_t *par_class=pclass->parent; /* Pointer to class's parent */ + if(pclass->deleted && pclass->plists == 0 && pclass->classes == 0) { + H5P_genclass_t *par_class = pclass->parent; /* Pointer to class's parent */ - assert(pclass->name); + HDassert(pclass->name); H5MM_xfree(pclass->name); /* Free the class properties without making callbacks */ if(pclass->props) { - unsigned make_cb=0; + hbool_t make_cb = FALSE; - H5SL_destroy(pclass->props,H5P_free_prop_cb,&make_cb); + H5SL_destroy(pclass->props, H5P_free_prop_cb, &make_cb); } /* end if */ - (void)H5FL_FREE(H5P_genclass_t, pclass); + pclass = H5FL_FREE(H5P_genclass_t, pclass); /* Reduce the number of dependent classes on parent class also */ - if(par_class!=NULL) + if(par_class != NULL) H5P_access_class(par_class, H5P_MOD_DEC_CLS); } /* end if */ - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5P_access_class() */ @@ -1384,11 +1384,11 @@ H5P_check_class(void *_obj, hid_t UNUSED id, void *_key) const H5P_check_class_t *key=(const H5P_check_class_t *)_key; /* Pointer to key information for comparison */ int ret_value=0; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_check_class); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_check_class) - assert(obj); - assert(H5I_GENPROP_CLS==H5I_get_type(id)); - assert(key); + HDassert(obj); + HDassert(H5I_GENPROP_CLS==H5I_get_type(id)); + HDassert(key); /* Check if the class object has the same parent as the new class */ if(obj->parent==key->parent) { @@ -1397,7 +1397,7 @@ H5P_check_class(void *_obj, hid_t UNUSED id, void *_key) ret_value=1; /* Indicate a match */ } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_check_class() */ @@ -1411,7 +1411,7 @@ H5P_check_class(void *_obj, hid_t UNUSED id, void *_key) cls_create, create_data, cls_close, close_data) H5P_genclass_t *par_class; IN: Pointer to parent class const char *name; IN: Name of class we are creating - unsigned internal; IN: Whether this is an internal class or not + hbool_t internal; IN: Whether this is an internal class or not H5P_cls_create_func_t; IN: The callback function to call when each property list in this class is created. void *create_data; IN: Pointer to user data to pass along to class @@ -1435,7 +1435,7 @@ H5P_check_class(void *_obj, hid_t UNUSED id, void *_key) REVISION LOG --------------------------------------------------------------------------*/ H5P_genclass_t * -H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal, +H5P_create_class(H5P_genclass_t *par_class, const char *name, hbool_t internal, H5P_cls_create_func_t cls_create, void *create_data, H5P_cls_copy_func_t cls_copy, void *copy_data, H5P_cls_close_func_t cls_close, void *close_data) @@ -1445,31 +1445,31 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal, FUNC_ENTER_NOAPI(H5P_create_class, NULL) - assert(name); + HDassert(name); /* Allow internal classes to break some rules */ /* (This allows the root of the tree to be created with this routine -QAK) */ - if(!internal) { - assert(par_class); - } + if(!internal) + HDassert(par_class); /* Allocate room for the class */ - if(NULL==(pclass = H5FL_CALLOC(H5P_genclass_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); + if(NULL == (pclass = H5FL_CALLOC(H5P_genclass_t))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, NULL, "propery list class allocation failed") /* Set class state */ pclass->parent = par_class; - pclass->name = H5MM_xstrdup(name); + if(NULL == (pclass->name = H5MM_xstrdup(name))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, NULL, "propery list class name allocation failed") pclass->nprops = 0; /* Classes are created without properties initially */ pclass->plists = 0; /* No properties lists of this class yet */ pclass->classes = 0; /* No classes derived from this class yet */ pclass->ref_count = 1; /* This is the first reference to the new class */ pclass->internal = internal; - pclass->deleted = 0; /* Not deleted yet... :-) */ + pclass->deleted = FALSE; /* Not deleted yet... :-) */ pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */ /* Create the skip list for properties */ - if((pclass->props = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for properties"); + if(NULL == (pclass->props = H5SL_create(H5SL_TYPE_STR))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "can't create skip list for properties") /* Set callback functions and pass-along data */ pclass->create_func = cls_create; @@ -1480,19 +1480,27 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal, pclass->close_data = close_data; /* Increment parent class's derived class value */ - if(par_class!=NULL) { - if(H5P_access_class(par_class,H5P_MOD_INC_CLS) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment parent class ref count"); + if(par_class != NULL) { + if(H5P_access_class(par_class, H5P_MOD_INC_CLS) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, NULL, "Can't increment parent class ref count") } /* end if */ /* Set return value */ - ret_value=pclass; + ret_value = pclass; done: /* Free any resources allocated */ - if(ret_value==NULL) - if(pclass!=NULL) - (void)H5FL_FREE(H5P_genclass_t, pclass); + if(ret_value == NULL) + if(pclass) { + if(pclass->name) + H5MM_xfree(pclass->name); + if(pclass->props) { + hbool_t make_cb = FALSE; + + H5SL_destroy(pclass->props, H5P_free_prop_cb, &make_cb); + } /* end if */ + pclass = H5FL_FREE(H5P_genclass_t, pclass); + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* H5P_create_class() */ @@ -1532,9 +1540,9 @@ H5P_create(H5P_genclass_t *pclass) H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */ H5P_genplist_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_create); + FUNC_ENTER_NOAPI_NOINIT(H5P_create) - assert(pclass); + HDassert(pclass); /* * Create new property list object @@ -1542,20 +1550,20 @@ H5P_create(H5P_genclass_t *pclass) /* Allocate room for the property list */ if(NULL==(plist = H5FL_CALLOC(H5P_genplist_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed") /* Set class state */ plist->pclass = pclass; plist->nprops = 0; /* Initially the plist has the same number of properties as the class */ - plist->class_init = 0; /* Initially, wait until the class callback finishes to set */ + plist->class_init = FALSE; /* Initially, wait until the class callback finishes to set */ /* Create the skip list for changed properties */ if((plist->props = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties") /* Create the skip list for deleted properties */ if((plist->del = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties") /* Create the skip list to hold names of properties already seen * (This prevents a property in the class hierarchy from having it's @@ -1563,7 +1571,7 @@ H5P_create(H5P_genclass_t *pclass) * already been seen) */ if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties") /* * Check if we should copy class properties (up through list of parent classes also), @@ -1586,12 +1594,12 @@ H5P_create(H5P_genclass_t *pclass) if(tmp->create) { /* Call the callback & insert changed value into skip list (if necessary) */ if(H5P_do_prop_cb1(plist->props,tmp,tmp->create) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property") } /* end if */ /* Add property name to "seen" list */ if(H5SL_insert(seen,tmp->name,tmp->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen skip list") /* Increment the number of properties in list */ plist->nprops++; @@ -1608,7 +1616,7 @@ H5P_create(H5P_genclass_t *pclass) /* Increment the number of property lists derived from class */ if(H5P_access_class(plist->pclass,H5P_MOD_INC_LST) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment class ref count"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment class ref count") /* Set return value */ ret_value=plist; @@ -1637,7 +1645,7 @@ done: } /* end if */ } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_create() */ @@ -1671,17 +1679,17 @@ H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref) hid_t plist_id = FAIL; /* Property list ID */ hid_t ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_create_id, FAIL); + FUNC_ENTER_NOAPI(H5P_create_id, FAIL) - assert(pclass); + HDassert(pclass); /* Create the new property list */ if((plist=H5P_create(pclass)) == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list") /* Get an atom for the property list */ if((plist_id = H5I_register(H5I_GENPROP_LST, plist, app_ref)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list") /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */ plist->plist_id=plist_id; @@ -1704,7 +1712,7 @@ H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref) } /* end while */ /* Set the class initialization flag */ - plist->class_init=1; + plist->class_init = TRUE; /* Set the return value */ ret_value=plist_id; @@ -1713,18 +1721,18 @@ done: if(ret_value<0 && plist) H5P_close(plist); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_create_id() */ /*-------------------------------------------------------------------------- NAME - H5P_register + H5P_register_real PURPOSE Internal routine to register a new property in a property list class. USAGE - herr_t H5P_register(class, name, size, default, prp_create, prp_set, prp_get, prp_close) - H5P_genclass_t *class; IN: Property list class to close + herr_t H5P_register_real(class, name, size, default, prp_create, prp_set, prp_get, prp_close) + H5P_genclass_t *class; IN: Property list class to modify const char *name; IN: Name of property to register size_t size; IN: Size of property in bytes void *def_value; IN: Pointer to buffer containing default value @@ -1872,89 +1880,274 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5P_register(H5P_genclass_t *pclass, const char *name, size_t size, +H5P_register_real(H5P_genclass_t *pclass, const char *name, size_t size, const void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close) { - H5P_genclass_t *new_class; /* New class pointer */ - H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */ - H5P_genprop_t *pcopy; /* Property copy */ - herr_t ret_value=SUCCEED; /* Return value */ + H5P_genprop_t *new_prop = NULL; /* Temporary property pointer */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5P_register, FAIL); + FUNC_ENTER_NOAPI(H5P_register_real, FAIL) - assert(pclass); - assert(name); - assert((size>0 && def_value!=NULL) || (size==0)); + HDassert(pclass); + HDassert(0 == pclass->plists); + HDassert(0 == pclass->classes); + HDassert(name); + HDassert((size > 0 && def_value != NULL) || (size == 0)); /* Check for duplicate named properties */ - if(H5SL_search(pclass->props,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); + if(NULL != H5SL_search(pclass->props, name)) + HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists") + + /* Create property object from parameters */ + if(NULL == (new_prop = H5P_create_prop(name, size, H5P_PROP_WITHIN_CLASS, def_value, prp_create, prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property") + + /* Insert property into property list class */ + if(H5P_add_prop(pclass->props, new_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class") + + /* Increment property count for class */ + pclass->nprops++; + + /* Update the revision for the class */ + pclass->revision = H5P_GET_NEXT_REV; + +done: + if(ret_value < 0) + if(new_prop && H5P_free_prop(new_prop) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close property") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P_register_real() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_register + PURPOSE + Internal routine to register a new property in a property list class. + USAGE + herr_t H5P_register(class, name, size, default, prp_create, prp_set, prp_get, prp_close) + H5P_genclass_t **class; IN: Property list class to modify + const char *name; IN: Name of property to register + size_t size; IN: Size of property in bytes + void *def_value; IN: Pointer to buffer containing default value + for property in newly created property lists + H5P_prp_create_func_t prp_create; IN: Function pointer to property + creation callback + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback + H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback + H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Registers a new property with a property list class. The property will + exist in all property list objects of that class after this routine is + finished. The name of the property must not already exist. The default + property value must be provided and all new property lists created with this + property will have the property value set to the default provided. Any of + the callback routines may be set to NULL if they are not needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'default' pointer for a + zero-sized property may be set to NULL. The property 'create' & 'close' + callbacks are called for zero-sized properties, but the 'set' and 'get' + callbacks are never called. + + The 'create' callback is called when a new property list with this + property is being created. H5P_prp_create_func_t is defined as: + typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, + size_t size, void *initial_value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being created. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *initial_value; IN/OUT: The initial value for the property being created. + (The 'default' value passed to H5Pregister2) + The 'create' routine may modify the value to be set and those changes will + be stored as the initial value of the property. If the 'create' routine + returns a negative value, the new property value is not copied into the + property and the property list creation routine returns an error value. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'delete' callback is called when a property is deleted from a + property list. H5P_prp_del_func_t is defined as: + typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list the property is deleted from. + const char *name; IN: The name of the property being deleted. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value of the property being deleted. + The 'delete' routine may modify the value passed in, but the value is not + used by the library when the 'delete' routine returns. If the + 'delete' routine returns a negative value, the property list deletion + routine returns an error value but the property is still deleted. + + The 'copy' callback is called when a property list with this + property is copied. H5P_prp_copy_func_t is defined as: + typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being copied. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being copied. + The 'copy' routine may modify the value to be copied and those changes will be + stored as the value of the property. If the 'copy' routine returns a + negative value, the new property value is not copied into the property and + the property list copy routine returns an error value. + + The 'compare' callback is called when a property list with this + property is compared to another property list. H5P_prp_compare_func_t is + defined as: + typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, + size_t size); + where the parameters to the callback function are: + const void *value1; IN: The value of the first property being compared. + const void *value2; IN: The value of the second property being compared. + size_t size; IN: The size of the property value + The 'compare' routine may not modify the values to be compared. The + 'compare' routine should return a positive value if VALUE1 is greater than + VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 + and VALUE2 are equal. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_register(H5P_genclass_t **ppclass, const char *name, size_t size, + const void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, + H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete, + H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, + H5P_prp_close_func_t prp_close) +{ + H5P_genclass_t *pclass = *ppclass; /* Pointer to class to modify */ + H5P_genclass_t *new_class = NULL; /* New class pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_register, FAIL) + + /* Sanity check */ + HDassert(ppclass); + HDassert(pclass); /* Check if class needs to be split because property lists or classes have * been created since the last modification was made to the class. */ - if(pclass->plists>0 || pclass->classes>0) { - if((new_class=H5P_create_class(pclass->parent,pclass->name, - pclass->internal,pclass->create_func,pclass->create_data, - pclass->copy_func,pclass->copy_data, - pclass->close_func,pclass->close_data)) == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy class"); + if(pclass->plists > 0 || pclass->classes > 0) { + if(NULL == (new_class = H5P_create_class(pclass->parent, pclass->name, + pclass->internal, pclass->create_func, pclass->create_data, + pclass->copy_func, pclass->copy_data, + pclass->close_func, pclass->close_data))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy class") /* Walk through the skip list of the old class and copy properties */ - if(pclass->nprops>0) { + if(pclass->nprops > 0) { H5SL_node_t *curr_node; /* Current node in skip list */ /* Walk through the properties in the old class */ - curr_node=H5SL_first(pclass->props); + curr_node = H5SL_first(pclass->props); while(curr_node != NULL) { + H5P_genprop_t *pcopy; /* Property copy */ + /* Make a copy of the class's property */ if(NULL == (pcopy = H5P_dup_prop((H5P_genprop_t *)H5SL_item(curr_node), H5P_PROP_WITHIN_CLASS))) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") - /* Insert the initialized property into the property list */ - if(H5P_add_prop(new_class->props,pcopy) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + /* Insert the initialized property into the property class */ + if(H5P_add_prop(new_class->props, pcopy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class") /* Increment property count for class */ new_class->nprops++; /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); + curr_node = H5SL_next(curr_node); } /* end while */ } /* end if */ /* Use the new class instead of the old one */ - pclass=new_class; + pclass = new_class; } /* end if */ - /* Create property object from parameters */ - if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_CLASS,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close)) == NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); - - /* Insert property into property list class */ - if(H5P_add_prop(pclass->props,new_prop) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); - - /* Increment property count for class */ - pclass->nprops++; + /* Really register the property in the class */ + if(H5P_register_real(pclass, name, size, def_value, prp_create, prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "can't register property") - /* Update the revision for the class */ - pclass->revision = H5P_GET_NEXT_REV; + /* Update pointer to pointer to class, if a new one was generated */ + if(new_class) + *ppclass = pclass; done: - if(ret_value==FAIL) { - if(new_prop!=NULL) { - if(new_prop->name!=NULL) - H5MM_xfree(new_prop->name); - if(new_prop->value!=NULL) - H5MM_xfree(new_prop->value); - (void)H5FL_FREE(H5P_genprop_t, new_prop); - } /* end if */ - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); + if(ret_value < 0) + if(new_class && H5P_close_class(new_class) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close new property class") + + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_register() */ @@ -2103,72 +2296,62 @@ H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close) { - H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* Return value */ + H5P_genprop_t *new_prop = NULL; /* Temporary property pointer */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_insert); + FUNC_ENTER_NOAPI_NOINIT(H5P_insert) - assert(plist); - assert(name); - assert((size>0 && value!=NULL) || (size==0)); + HDassert(plist); + HDassert(name); + HDassert((size > 0 && value != NULL) || (size == 0)); /* Check for duplicate named properties */ - if(H5SL_search(plist->props,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); + if(NULL != H5SL_search(plist->props, name)) + HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists") /* Check if the property has been deleted */ - if(H5SL_search(plist->del,name)!=NULL) { + if(NULL != H5SL_search(plist->del, name)) { /* Remove the property name from the deleted property skip list */ - if(H5SL_remove(plist->del,name) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from deleted skip list"); - - /* Fall through to add property to list */ + if(NULL == H5SL_remove(plist->del, name)) + HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from deleted skip list") } /* end if */ else { H5P_genclass_t *tclass; /* Temporary class pointer */ /* Check if the property is already in the class hierarchy */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { + tclass = plist->pclass; + while(tclass) { + if(tclass->nprops > 0) { /* Find the property in the class */ - if(H5SL_search(tclass->props,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); + if(NULL != H5SL_search(tclass->props, name)) + HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists") } /* end if */ /* Go up to parent class */ - tclass=tclass->parent; + tclass = tclass->parent; } /* end while */ - - /* Fall through to add property to list */ } /* end else */ /* Ok to add to property list */ /* Create property object from parameters */ - if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_LIST,value,NULL,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close)) == NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); + if(NULL == (new_prop = H5P_create_prop(name, size, H5P_PROP_WITHIN_LIST, value, NULL, prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "Can't create property") /* Insert property into property list class */ - if(H5P_add_prop(plist->props,new_prop) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + if(H5P_add_prop(plist->props, new_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "Can't insert property into class") /* Increment property count for class */ plist->nprops++; done: - if(ret_value==FAIL) { - if(new_prop!=NULL) { - if(new_prop->name!=NULL) - H5MM_xfree(new_prop->name); - if(new_prop->value!=NULL) - H5MM_xfree(new_prop->value); - (void)H5FL_FREE(H5P_genprop_t, new_prop); - } /* end if */ - } /* end if */ + if(ret_value < 0) + if(new_prop && H5P_free_prop(new_prop) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close property") - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_insert() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P_insert() */ /*-------------------------------------------------------------------------- @@ -2209,21 +2392,21 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value) H5P_genprop_t *prop; /* Temporary property pointer */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5P_set, FAIL); + FUNC_ENTER_NOAPI(H5P_set, FAIL) - assert(plist); - assert(name); - assert(value); + HDassert(plist); + HDassert(name); + HDassert(value); /* Check if the property has been deleted */ if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") /* Find property in changed list */ if(NULL != (prop = (H5P_genprop_t *)H5SL_search(plist->props, name))) { /* Check for property size >0 */ if(prop->size==0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size"); + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") /* Make a copy of the value and pass to 'set' callback */ if(prop->set!=NULL) { @@ -2231,13 +2414,13 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value) /* Make a copy of the current value, in case the callback fails */ if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") HDmemcpy(tmp_value,value,prop->size); /* Call user's callback */ if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value) < 0) { H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") } /* end if */ /* Copy new [possibly unchanged] value into property value */ @@ -2264,7 +2447,7 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value) /* Check for property size >0 */ if(prop->size==0) - HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size"); + HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size") /* Make a copy of the value and pass to 'set' callback */ if(prop->set!=NULL) { @@ -2272,26 +2455,26 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value) /* Make a copy of the current value, in case the callback fails */ if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") HDmemcpy(tmp_value,value,prop->size); /* Call user's callback */ if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value) < 0) { H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") } /* end if */ if((prop->cmp)(tmp_value,prop->value,prop->size)) { /* Make a copy of the class's property */ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property") /* Copy new value into property value */ HDmemcpy(pcopy->value,tmp_value,pcopy->size); /* Insert the changed property into the property list */ if(H5P_add_prop(plist->props,pcopy) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") } /* end if */ /* Free the temporary value buffer */ @@ -2302,13 +2485,13 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value) if((prop->cmp)(value,prop->value,prop->size)) { /* Make a copy of the class's property */ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property") HDmemcpy(pcopy->value,value,pcopy->size); /* Insert the changed property into the property list */ if(H5P_add_prop(plist->props,pcopy) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") } /* end if */ } /* end else */ @@ -2324,11 +2507,11 @@ H5P_set(H5P_genplist_t *plist, const char *name, const void *value) /* If we get this far, then it wasn't in the list of changed properties, * nor in the properties in the class hierarchy, indicate an error */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_set() */ @@ -2356,39 +2539,39 @@ done: htri_t H5P_exist_plist(H5P_genplist_t *plist, const char *name) { - htri_t ret_value=FAIL; /* return value */ + htri_t ret_value = FAIL; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_plist); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_plist) - assert(plist); - assert(name); + HDassert(plist); + HDassert(name); /* Check for property in deleted property list */ - if(H5SL_search(plist->del,name)!=NULL) - ret_value=0; + if(H5SL_search(plist->del, name) != NULL) + ret_value = FALSE; else { /* Check for property in changed property list */ - if(H5SL_search(plist->props,name)!=NULL) - ret_value=1; + if(H5SL_search(plist->props, name) != NULL) + ret_value = TRUE; else { H5P_genclass_t *tclass; /* Temporary class pointer */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(H5SL_search(tclass->props,name)!=NULL) - HGOTO_DONE(1); + tclass = plist->pclass; + while(tclass != NULL) { + if(H5SL_search(tclass->props, name) != NULL) + HGOTO_DONE(TRUE) /* Go up to parent class */ - tclass=tclass->parent; + tclass = tclass->parent; } /* end while */ /* If we've reached here, we couldn't find the property */ - ret_value=0; + ret_value = FALSE; } /* end else */ } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_exist_plist() */ @@ -2402,11 +2585,11 @@ done: H5P_genclass_t *pclass; IN: Property class to check const char *name; IN: Name of property to check for RETURNS - Success: Positive if the property exists in the property list, zero + Success: Positive if the property exists in the property class, zero if the property does not exist. Failure: negative value DESCRIPTION - This routine checks if a property exists within a property list. + This routine checks if a property exists within a property class. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS @@ -2416,20 +2599,34 @@ done: htri_t H5P_exist_pclass(H5P_genclass_t *pclass, const char *name) { - htri_t ret_value=FAIL; /* return value */ + htri_t ret_value = FAIL; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_pclass); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_pclass) - assert(pclass); - assert(name); + HDassert(pclass); + HDassert(name); /* Check for property in property list */ - if(H5SL_search(pclass->props,name) == NULL) - ret_value=0; - else - ret_value=1; + if(H5SL_search(pclass->props, name) != NULL) + ret_value = TRUE; + else { + H5P_genclass_t *tclass; /* Temporary class pointer */ + + tclass = pclass->parent; + while(tclass != NULL) { + if(H5SL_search(tclass->props, name) != NULL) + HGOTO_DONE(TRUE) + + /* Go up to parent class */ + tclass = tclass->parent; + } /* end while */ - FUNC_LEAVE_NOAPI(ret_value); + /* If we've reached here, we couldn't find the property */ + ret_value = FALSE; + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_exist_pclass() */ @@ -2461,21 +2658,21 @@ H5P_get_size_plist(H5P_genplist_t *plist, const char *name, size_t *size) H5P_genprop_t *prop; /* Temporary property pointer */ herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_plist); + FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_plist) - assert(plist); - assert(name); - assert(size); + HDassert(plist); + HDassert(name); + HDassert(size); /* Find property */ if((prop=H5P_find_prop_plist(plist,name)) == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") /* Get property size */ *size=prop->size; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_size_plist() */ @@ -2507,21 +2704,21 @@ H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, size_t *size) H5P_genprop_t *prop; /* Temporary property pointer */ herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_pclass); + FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_pclass) - assert(pclass); - assert(name); - assert(size); + HDassert(pclass); + HDassert(name); + HDassert(size); /* Find property */ if((prop=H5P_find_prop_pclass(pclass,name)) == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") /* Get property size */ *size=prop->size; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_size_pclass() */ @@ -2549,14 +2746,14 @@ H5P_get_class(const H5P_genplist_t *plist) { H5P_genclass_t *ret_value; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class) HDassert(plist); /* Get property size */ ret_value = plist->pclass; - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_class() */ @@ -2583,7 +2780,7 @@ H5P_get_class(const H5P_genplist_t *plist) herr_t H5P_get_nprops_plist(const H5P_genplist_t *plist, size_t *nprops) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_nprops_plist); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_nprops_plist) HDassert(plist); HDassert(nprops); @@ -2591,7 +2788,7 @@ H5P_get_nprops_plist(const H5P_genplist_t *plist, size_t *nprops) /* Get property size */ *nprops = plist->nprops; - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5P_get_nprops_plist() */ @@ -2669,7 +2866,7 @@ H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2) int cmp_value; /* Value from comparison */ int ret_value = 0; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_prop); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_prop) HDassert(prop1); HDassert(prop2); @@ -2727,7 +2924,7 @@ H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2) } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_cmp_prop() */ @@ -2760,7 +2957,7 @@ H5P_cmp_class(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2) int cmp_value; /* Value from comparison */ int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_class); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_class) HDassert(pclass1); HDassert(pclass2); @@ -2833,7 +3030,7 @@ H5P_cmp_class(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2) } /* end while */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_cmp_class() */ @@ -2866,7 +3063,7 @@ H5P_cmp_plist(const H5P_genplist_t *plist1, const H5P_genplist_t *plist2) int cmp_value; /* Value from comparison */ int ret_value = 0; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_plist); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_plist) HDassert(plist1); HDassert(plist2); @@ -2940,7 +3137,7 @@ H5P_cmp_plist(const H5P_genplist_t *plist1, const H5P_genplist_t *plist2) HGOTO_DONE(cmp_value); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_cmp_plist() */ @@ -2972,10 +3169,10 @@ H5P_isa_class_real(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2) { htri_t ret_value; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_isa_class_real); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_isa_class_real) - assert(pclass1); - assert(pclass2); + HDassert(pclass1); + HDassert(pclass2); /* Compare property classes */ if(H5P_cmp_class(pclass1, pclass2) == 0) { @@ -2989,7 +3186,7 @@ H5P_isa_class_real(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2) } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_isa_class_real() */ @@ -3025,20 +3222,20 @@ H5P_isa_class(hid_t plist_id, hid_t pclass_id) H5P_genclass_t *pclass; /* Property list class */ htri_t ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_isa_class, FAIL); + FUNC_ENTER_NOAPI(H5P_isa_class, FAIL) /* Check arguments. */ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class") /* Compare the property list's class against the other class */ if((ret_value = H5P_isa_class_real(plist->pclass, pclass)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_isa_class() */ @@ -3152,18 +3349,18 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_ int curr_idx = 0; /* Current iteration index */ int ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_plist); + FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_plist) HDassert(idx); HDassert(iter_func); /* Get the property list object */ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Create the skip list to hold names of properties already seen */ if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties") /* Walk through the changed properties in the list */ if(H5SL_count(plist->props) > 0) { @@ -3186,7 +3383,7 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_ /* Add property name to "seen" list */ if(H5SL_insert(seen,tmp->name,tmp->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list") /* Get the next property node in the skip list */ curr_node=H5SL_next(curr_node); @@ -3224,7 +3421,7 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_ /* Add property name to "seen" list */ if(H5SL_insert(seen,tmp->name,tmp->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list") } /* end if */ /* Get the next property node in the skip list */ @@ -3244,7 +3441,7 @@ done: if(seen!=NULL) H5SL_close(seen); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_iterate_plist() */ @@ -3308,14 +3505,14 @@ H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *ite int curr_idx=0; /* Current iteration index */ int ret_value=FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_pclass); + FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_pclass) - assert(idx); - assert(iter_func); + HDassert(idx); + HDassert(iter_func); /* Get the property list object */ if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class") /* Cycle through the properties and call the callback */ curr_idx=0; @@ -3344,7 +3541,7 @@ done: /* Set the index we stopped at */ *idx=curr_idx; - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_iterate_pclass() */ @@ -3380,16 +3577,16 @@ H5P_peek_unsigned(H5P_genplist_t *plist, const char *name) { unsigned ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_peek_unsigned, UFAIL); + FUNC_ENTER_NOAPI(H5P_peek_unsigned, UFAIL) - assert(plist); - assert(name); + HDassert(plist); + HDassert(name); /* Get the value to return, don't worry about the return value, we can't return it */ H5P_get(plist,name,&ret_value); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_peek_unsigned() */ @@ -3425,16 +3622,16 @@ H5P_peek_hid_t(H5P_genplist_t *plist, const char *name) { hid_t ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_peek_hid_t, FAIL); + FUNC_ENTER_NOAPI(H5P_peek_hid_t, FAIL) - assert(plist); - assert(name); + HDassert(plist); + HDassert(name); /* Get the value to return, don't worry about the return value, we can't return it */ H5P_get(plist,name,&ret_value); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_peek_hid_t() */ @@ -3470,16 +3667,16 @@ H5P_peek_voidp(H5P_genplist_t *plist, const char *name) { void * ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_peek_voidp, NULL); + FUNC_ENTER_NOAPI(H5P_peek_voidp, NULL) - assert(plist); - assert(name); + HDassert(plist); + HDassert(name); /* Get the value to return, don't worry about the return value, we can't return it */ H5P_get(plist,name,&ret_value); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_peek_voidp() */ @@ -3515,16 +3712,16 @@ H5P_peek_size_t(H5P_genplist_t *plist, const char *name) { size_t ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_peek_size_t, UFAIL); + FUNC_ENTER_NOAPI(H5P_peek_size_t, UFAIL) - assert(plist); - assert(name); + HDassert(plist); + HDassert(name); /* Get the value to return, don't worry about the return value, we can't return it */ H5P_get(plist,name,&ret_value); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_peek_size_t() */ @@ -3563,21 +3760,21 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value) H5P_genprop_t *prop; /* Temporary property pointer */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5P_get, FAIL); + FUNC_ENTER_NOAPI(H5P_get, FAIL) - assert(plist); - assert(name); - assert(value); + HDassert(plist); + HDassert(name); + HDassert(value); /* Check if the property has been deleted */ if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") /* Find property */ if((prop = (H5P_genprop_t *)H5SL_search(plist->props,name))!=NULL) { /* Check for property size >0 */ if(prop->size==0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size"); + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") /* Make a copy of the value and pass to 'get' callback */ if(prop->get!=NULL) { @@ -3585,12 +3782,12 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value) /* Make a copy of the current value, in case the callback fails */ if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") HDmemcpy(tmp_value,prop->value,prop->size); /* Call user's callback */ if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value") /* Copy new [possibly unchanged] value into return value */ HDmemcpy(value,tmp_value,prop->size); @@ -3614,7 +3811,7 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value) if((prop = (H5P_genprop_t *)H5SL_search(tclass->props,name))!=NULL) { /* Check for property size >0 */ if(prop->size==0) - HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size"); + HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size") /* Call the 'get' callback, if there is one */ if(prop->get!=NULL) { @@ -3622,13 +3819,13 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value) /* Make a copy of the current value, in case the callback fails */ if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") HDmemcpy(tmp_value,prop->value,prop->size); /* Call user's callback */ if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value) < 0) { H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") } /* end if */ if((prop->cmp)(tmp_value,prop->value,prop->size)) { @@ -3636,14 +3833,14 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value) /* Make a copy of the class's property */ if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property") /* Copy new value into property value */ HDmemcpy(pcopy->value,tmp_value,prop->size); /* Insert the changed property into the property list */ if(H5P_add_prop(plist->props,pcopy) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") } /* end if */ /* Copy new [possibly unchanged] value into return value */ @@ -3668,11 +3865,11 @@ H5P_get(const H5P_genplist_t *plist, const char *name, void *value) /* If we get this far, then it wasn't in the list of changed properties, * nor in the properties in the class hierarchy, indicate an error */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get() */ @@ -3710,14 +3907,14 @@ H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) char *del_name; /* Pointer to deleted name */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5P_remove,FAIL); + FUNC_ENTER_NOAPI(H5P_remove, FAIL) - assert(plist); - assert(name); + HDassert(plist); + HDassert(name); /* Indicate that the property isn't in the list if it has been deleted already */ if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") /* Get the property node from the changed property skip list */ if((prop = (H5P_genprop_t *)H5SL_search(plist->props,name))!=NULL) { @@ -3725,20 +3922,20 @@ H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) if(prop->del!=NULL) { /* Call user's callback */ if((*(prop->del))(plist_id,name,prop->size,prop->value) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value") } /* end if */ /* Duplicate string for insertion into new deleted property skip list */ if((del_name=H5MM_xstrdup(name)) == NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed") /* Insert property name into deleted list */ if(H5SL_insert(plist->del,del_name,del_name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list") /* Remove the property from the skip list */ if(H5SL_remove(plist->props,prop->name) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list") /* Free the property, ignoring return value, nothing we can do */ H5P_free_prop(prop); @@ -3763,13 +3960,13 @@ H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) /* Allocate space for a temporary copy of the property value */ if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value") HDmemcpy(tmp_value,prop->value,prop->size); /* Call user's callback */ if((*(prop->del))(plist_id,name,prop->size,tmp_value) < 0) { H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value") } /* end if */ /* Release the temporary value buffer */ @@ -3778,11 +3975,11 @@ H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) /* Duplicate string for insertion into new deleted property skip list */ if((del_name=H5MM_xstrdup(name)) == NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed") /* Insert property name into deleted list */ if(H5SL_insert(plist->del,del_name,del_name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list") /* Decrement the number of properties in list */ plist->nprops--; @@ -3799,11 +3996,11 @@ H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) /* If we get this far, then it wasn't in the list of changed properties, * nor in the properties in the class hierarchy, indicate an error */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_remove() */ @@ -3847,36 +4044,36 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) H5P_genprop_t *new_prop=NULL; /* Pointer to new property */ herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_plist); + FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_plist) - assert(name); + HDassert(name); /* Get the objects to operate on */ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_id)) || NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist"); + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist") /* If the property exists in the destination alread */ if(H5P_find_prop_plist(dst_plist,name)!=NULL) { /* Delete the property from the destination list, calling the 'close' callback if necessary */ if(H5P_remove(dst_id,dst_plist,name) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property") /* Get the pointer to the source property */ prop=H5P_find_prop_plist(src_plist,name); /* Make a copy of the source property */ if((new_prop=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property") /* Call property copy callback, if it exists */ if(new_prop->copy) { if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property") } /* end if */ /* Insert the initialized property into the property list */ if(H5P_add_prop(dst_plist->props,new_prop) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list") /* Increment the number of properties in list */ dst_plist->nprops++; @@ -3888,17 +4085,17 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) /* Create property object from parameters */ if((new_prop=H5P_create_prop(prop->name,prop->size,H5P_PROP_WITHIN_LIST,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close)) == NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property") /* Call property creation callback, if it exists */ if(new_prop->create) { if((new_prop->create)(new_prop->name,new_prop->size,new_prop->value) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property") } /* end if */ /* Insert property into property list class */ if(H5P_add_prop(dst_plist->props,new_prop) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class") /* Increment property count for class */ dst_plist->nprops++; @@ -3912,7 +4109,7 @@ done: H5P_free_prop(new_prop); } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_copy_prop_plist() */ @@ -3946,36 +4143,59 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, const char *name) +H5P_copy_prop_pclass(hid_t dst_id, hid_t src_id, const char *name) { + H5P_genclass_t *src_pclass; /* Source property class, containing property to copy */ + H5P_genclass_t *dst_pclass; /* Destination property class */ + H5P_genclass_t *orig_dst_pclass; /* Original destination property class */ H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* return value */ + herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_pclass); + FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_pclass) - assert(dst_pclass); - assert(src_pclass); - assert(name); + /* Sanity check */ + HDassert(name); + + /* Get propery list classes */ + if(NULL == (src_pclass = (H5P_genclass_t *)H5I_object(src_id))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "source property class object doesn't exist") + if(NULL == (dst_pclass = (H5P_genclass_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "destination property class object doesn't exist") + + /* Get the property from the source */ + if(NULL == (prop = H5P_find_prop_pclass(src_pclass, name))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to locate property") /* If the property exists in the destination already */ - if(H5P_exist_pclass(dst_pclass,name)) { + if(H5P_exist_pclass(dst_pclass, name)) { /* Delete the old property from the destination class */ - if(H5P_unregister(dst_pclass,name) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + if(H5P_unregister(dst_pclass, name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property") } /* end if */ - /* Get the property from the source */ - if((prop=H5P_find_prop_pclass(src_pclass,name)) == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to locate property"); - /* Register the property into the destination */ - if(H5P_register(dst_pclass,name,prop->size,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + orig_dst_pclass = dst_pclass; + if(H5P_register(&dst_pclass, name, prop->size, prop->value, prop->create, prop->set, prop->get, prop->del, prop->copy, prop->cmp, prop->close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property") + + /* Check if the property class changed and needs to be substituted in the ID */ + if(dst_pclass != orig_dst_pclass) { + H5P_genclass_t *old_dst_pclass; /* Old destination property class */ + + /* Substitute the new destination property class in the ID */ + if(NULL == (old_dst_pclass = (H5P_genclass_t *)H5I_subst(dst_id, dst_pclass))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to substitute property class in ID") + HDassert(old_dst_pclass == orig_dst_pclass); + + /* Close the previous class */ + if(H5P_close_class(orig_dst_pclass) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close original property class after substitution") + } /* end if */ done: /* Cleanup, if necessary */ - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_copy_prop_pclass() */ @@ -4006,18 +4226,18 @@ H5P_unregister(H5P_genclass_t *pclass, const char *name) H5P_genprop_t *prop; /* Temporary property pointer */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_unregister); + FUNC_ENTER_NOAPI_NOINIT(H5P_unregister) - assert(pclass); - assert(name); + HDassert(pclass); + HDassert(name); /* Get the property node from the skip list */ if((prop = (H5P_genprop_t *)H5SL_search(pclass->props,name)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") /* Remove the property from the skip list */ if(H5SL_remove(pclass->props,prop->name) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list") /* Free the property, ignoring return value, nothing we can do */ H5P_free_prop(prop); @@ -4029,7 +4249,7 @@ H5P_unregister(H5P_genclass_t *pclass, const char *name) pclass->revision = H5P_GET_NEXT_REV; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_unregister() */ @@ -4071,14 +4291,14 @@ H5P_close(void *_plist) unsigned make_cb=0; /* Operator data for property free callback */ herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_close); + FUNC_ENTER_NOAPI_NOINIT(H5P_close) - assert(plist); + HDassert(plist); /* Make call to property list class close callback, if needed * (up through chain of parent classes also) */ - if(plist->class_init !=0) { + if(plist->class_init) { tclass = plist->pclass; while(NULL != tclass) { if(NULL != tclass->close_func) { @@ -4097,7 +4317,7 @@ H5P_close(void *_plist) * already been seen) */ if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties") nseen = 0; /* Walk through the changed properties in the list */ @@ -4115,7 +4335,7 @@ H5P_close(void *_plist) /* Add property name to "seen" list */ if(H5SL_insert(seen,tmp->name,tmp->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list") nseen++; /* Get the next property node in the skip list */ @@ -4152,7 +4372,7 @@ H5P_close(void *_plist) /* Allocate space for a temporary copy of the property value */ if(NULL==(tmp_value=H5MM_malloc(tmp->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value") HDmemcpy(tmp_value,tmp->value,tmp->size); /* Call the 'close' callback */ @@ -4165,7 +4385,7 @@ H5P_close(void *_plist) /* Add property name to "seen" list, if we have other classes to work on */ if(has_parent_class) { if(H5SL_insert(seen,tmp->name,tmp->name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list") nseen++; } /* end if */ } /* end if */ @@ -4181,7 +4401,7 @@ H5P_close(void *_plist) /* Decrement class's dependant property list value! */ if(H5P_access_class(plist->pclass,H5P_MOD_DEC_LST) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count") /* Free the list of 'seen' properties */ H5SL_close(seen); @@ -4201,7 +4421,7 @@ done: if(seen != NULL) H5SL_close(seen); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_close() */ @@ -4230,15 +4450,15 @@ H5P_get_class_name(H5P_genclass_t *pclass) { char *ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_get_class_name, NULL); + FUNC_ENTER_NOAPI(H5P_get_class_name, NULL) - assert(pclass); + HDassert(pclass); /* Get class name */ ret_value=H5MM_xstrdup(pclass->name); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_class_name() */ @@ -4271,9 +4491,9 @@ H5P_get_class_path(H5P_genclass_t *pclass) size_t my_path_len; /* This class's name's length */ char *ret_value; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_get_class_path); + FUNC_ENTER_NOAPI_NOINIT(H5P_get_class_path) - assert(pclass); + HDassert(pclass); /* Recursively build the full path */ if(pclass->parent!=NULL) { @@ -4288,7 +4508,7 @@ H5P_get_class_path(H5P_genclass_t *pclass) * separator, this class's name and the string terminator */ if(NULL == (ret_value = (char *)H5MM_malloc(par_path_len + 1 + my_path_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for class name"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for class name") /* Build the full path for this class */ HDstrcpy(ret_value,par_path); @@ -4305,7 +4525,7 @@ H5P_get_class_path(H5P_genclass_t *pclass) ret_value=H5MM_xstrdup(pclass->name); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_class_path() */ @@ -4359,7 +4579,7 @@ H5P_open_class_path(const char *path) /* Find the class with this name & parent by iterating over the open classes */ if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE))) - HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class"); + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class") /* Advance the pointer in the path to the start of the next component */ curr_name=delimit+1; @@ -4411,14 +4631,14 @@ H5P_get_class_parent(const H5P_genclass_t *pclass) { H5P_genclass_t *ret_value; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class_parent); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class_parent) - assert(pclass); + HDassert(pclass); /* Get property size */ ret_value = pclass->parent; - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_class_parent() */ @@ -4442,18 +4662,18 @@ H5P_get_class_parent(const H5P_genclass_t *pclass) herr_t H5P_close_class(void *_pclass) { - H5P_genclass_t *pclass=(H5P_genclass_t *)_pclass; - herr_t ret_value=SUCCEED; /* Return value */ + H5P_genclass_t *pclass = (H5P_genclass_t *)_pclass; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_close_class); + FUNC_ENTER_NOAPI_NOINIT(H5P_close_class) - assert(pclass); + HDassert(pclass); /* Decrement the reference count & check if the object should go away */ - if(H5P_access_class(pclass,H5P_MOD_DEC_REF) < 0) - HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, FAIL, "Can't decrement ID ref count"); + if(H5P_access_class(pclass, H5P_MOD_DEC_REF) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't decrement ID ref count") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_close_class() */ diff --git a/src/H5Plapl.c b/src/H5Plapl.c index 608240f..22cef28 100644 --- a/src/H5Plapl.c +++ b/src/H5Plapl.c @@ -158,27 +158,23 @@ H5P_lacc_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_lacc_reg_prop) /* Register property for number of links traversed */ - if(H5P_register(pclass, H5L_ACS_NLINKS_NAME, H5L_ACS_NLINKS_SIZE, - &nlinks, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5L_ACS_NLINKS_NAME, H5L_ACS_NLINKS_SIZE, &nlinks, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register property for external link prefix */ - if(H5P_register(pclass, H5L_ACS_ELINK_PREFIX_NAME, H5L_ACS_ELINK_PREFIX_SIZE, - &elink_prefix, NULL, NULL, NULL, H5L_ACS_ELINK_PREFIX_DEL, H5L_ACS_ELINK_PREFIX_COPY, NULL, H5L_ACS_ELINK_PREFIX_CLOSE) < 0) + if(H5P_register_real(pclass, H5L_ACS_ELINK_PREFIX_NAME, H5L_ACS_ELINK_PREFIX_SIZE, &elink_prefix, NULL, NULL, NULL, H5L_ACS_ELINK_PREFIX_DEL, H5L_ACS_ELINK_PREFIX_COPY, NULL, H5L_ACS_ELINK_PREFIX_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register fapl for link access */ - if(H5P_register(pclass, H5L_ACS_ELINK_FAPL_NAME, H5L_ACS_ELINK_FAPL_SIZE, &def_fapl_id, NULL, NULL, NULL, H5L_ACS_ELINK_FAPL_DEL, H5L_ACS_ELINK_FAPL_COPY, NULL, H5L_ACS_ELINK_FAPL_CLOSE) < 0) + if(H5P_register_real(pclass, H5L_ACS_ELINK_FAPL_NAME, H5L_ACS_ELINK_FAPL_SIZE, &def_fapl_id, NULL, NULL, NULL, H5L_ACS_ELINK_FAPL_DEL, H5L_ACS_ELINK_FAPL_COPY, NULL, H5L_ACS_ELINK_FAPL_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register property for external link file access flags */ - if(H5P_register(pclass, H5L_ACS_ELINK_FLAGS_NAME, H5L_ACS_ELINK_FLAGS_SIZE, - &elink_flags, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5L_ACS_ELINK_FLAGS_NAME, H5L_ACS_ELINK_FLAGS_SIZE, &elink_flags, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register property for external link file traversal callback */ - if(H5P_register(pclass, H5L_ACS_ELINK_CB_NAME, H5L_ACS_ELINK_CB_SIZE, - &elink_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5L_ACS_ELINK_CB_NAME, H5L_ACS_ELINK_CB_SIZE, &elink_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Plcpl.c b/src/H5Plcpl.c index 1e4355e..ffc68fa 100644 --- a/src/H5Plcpl.c +++ b/src/H5Plcpl.c @@ -119,8 +119,7 @@ H5P_lcrt_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI(H5P_lcrt_reg_prop, FAIL) /* Register create intermediate groups property */ - if(H5P_register(pclass, H5L_CRT_INTERMEDIATE_GROUP_NAME, H5L_CRT_INTERMEDIATE_GROUP_SIZE, - &intmd_group, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5L_CRT_INTERMEDIATE_GROUP_NAME, H5L_CRT_INTERMEDIATE_GROUP_SIZE, &intmd_group, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index 9f144f1..ac46228 100755 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -136,23 +136,19 @@ H5P_ocrt_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_reg_prop) /* Register max. compact attribute storage property */ - if(H5P_register(pclass, H5O_CRT_ATTR_MAX_COMPACT_NAME, H5O_CRT_ATTR_MAX_COMPACT_SIZE, - &attr_max_compact, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5O_CRT_ATTR_MAX_COMPACT_NAME, H5O_CRT_ATTR_MAX_COMPACT_SIZE, &attr_max_compact, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register min. dense attribute storage property */ - if(H5P_register(pclass, H5O_CRT_ATTR_MIN_DENSE_NAME, H5O_CRT_ATTR_MIN_DENSE_SIZE, - &attr_min_dense, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5O_CRT_ATTR_MIN_DENSE_NAME, H5O_CRT_ATTR_MIN_DENSE_SIZE, &attr_min_dense, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register object header flags property */ - if(H5P_register(pclass, H5O_CRT_OHDR_FLAGS_NAME, H5O_CRT_OHDR_FLAGS_SIZE, - &ohdr_flags, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5O_CRT_OHDR_FLAGS_NAME, H5O_CRT_OHDR_FLAGS_SIZE, &ohdr_flags, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") /* Register the pipeline property */ - if(H5P_register(pclass, H5O_CRT_PIPELINE_NAME, H5O_CRT_PIPELINE_SIZE, - &pline, NULL, NULL, NULL, NULL, NULL, H5O_CRT_PIPELINE_CMP, NULL) < 0) + if(H5P_register_real(pclass, H5O_CRT_PIPELINE_NAME, H5O_CRT_PIPELINE_SIZE, &pline, NULL, NULL, NULL, NULL, NULL, H5O_CRT_PIPELINE_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Pocpypl.c b/src/H5Pocpypl.c index 2b43428..963dddc 100755 --- a/src/H5Pocpypl.c +++ b/src/H5Pocpypl.c @@ -118,8 +118,7 @@ H5P_ocpy_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI(H5P_ocpy_reg_prop, FAIL) /* Register copy options property */ - if(H5P_register(pclass, H5O_CPY_OPTION_NAME, H5O_CPY_OPTION_SIZE, - &ocpy_option, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5O_CPY_OPTION_NAME, H5O_CPY_OPTION_SIZE, &ocpy_option, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index fd9c65a..1e71049 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -69,7 +69,7 @@ typedef struct H5P_genprop_t { size_t size; /* Size of property value */ void *value; /* Pointer to property value */ H5P_prop_within_t type; /* Type of object the property is within */ - unsigned shared_name; /* Boolean: whether the name is shared or not */ + hbool_t shared_name; /* Whether the name is shared or not */ /* Callback function pointers & info */ H5P_prp_create_func_t create; /* Function to call when a property is created */ @@ -89,8 +89,8 @@ struct H5P_genclass_t { unsigned plists; /* Number of property lists that have been created since the last modification to the class */ unsigned classes; /* Number of classes that have been derived since the last modification to the class */ unsigned ref_count; /* Number of oustanding ID's open on this class object */ - unsigned internal; /* Whether this class is internal to the library or not */ - unsigned deleted; /* Whether this class has been deleted and is waiting for dependent classes & proplists to close */ + hbool_t internal; /* Whether this class is internal to the library or not */ + hbool_t deleted; /* Whether this class has been deleted and is waiting for dependent classes & proplists to close */ unsigned revision; /* Revision number of a particular class (global) */ H5SL_t *props; /* Skip list containing properties */ @@ -106,9 +106,9 @@ struct H5P_genclass_t { /* Define structure to hold property list information */ struct H5P_genplist_t { H5P_genclass_t *pclass; /* Pointer to class info */ - hid_t plist_id; /* Copy of the property list ID (for use in close callback) */ - size_t nprops; /* Number of properties in class */ - unsigned class_init:1; /* Whether the class initialization callback finished successfully */ + hid_t plist_id; /* Copy of the property list ID (for use in close callback) */ + size_t nprops; /* Number of properties in class */ + hbool_t class_init; /* Whether the class initialization callback finished successfully */ H5SL_t *del; /* Skip list containing names of deleted properties */ H5SL_t *props; /* Skip list containing properties */ }; @@ -155,6 +155,16 @@ H5_DLL H5P_genclass_t *H5P_create_class(H5P_genclass_t *par_class, H5P_cls_copy_func_t cls_copy, void *copy_data, H5P_cls_close_func_t cls_close, void *close_data); H5_DLL H5P_genclass_t *H5P_copy_pclass(H5P_genclass_t *pclass); +H5_DLL herr_t H5P_register_real(H5P_genclass_t *pclass, const char *name, size_t size, + const void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, + H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete, + H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, + H5P_prp_close_func_t prp_close); +H5_DLL herr_t H5P_register(H5P_genclass_t **pclass, const char *name, size_t size, + const void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, + H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete, + H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, + H5P_prp_close_func_t prp_close); H5_DLL herr_t H5P_add_prop(H5SL_t *props, H5P_genprop_t *prop); H5_DLL herr_t H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod); H5_DLL htri_t H5P_exist_pclass(H5P_genclass_t *pclass, const char *name); @@ -171,8 +181,7 @@ H5_DLL int H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, H5_DLL int H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *iter_data); H5_DLL herr_t H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name); -H5_DLL herr_t H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, - const char *name); +H5_DLL herr_t H5P_copy_prop_pclass(hid_t dst_id, hid_t src_id, const char *name); H5_DLL herr_t H5P_unregister(H5P_genclass_t *pclass, const char *name); H5_DLL char *H5P_get_class_path(H5P_genclass_t *pclass); H5_DLL H5P_genclass_t *H5P_open_class_path(const char *path); diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index f544dbc..ab3f1d0 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -70,11 +70,6 @@ H5_DLL htri_t H5P_exist_plist(H5P_genplist_t *plist, const char *name); H5_DLL char *H5P_get_class_name(H5P_genclass_t *pclass); H5_DLL herr_t H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, hbool_t recurse); -H5_DLL herr_t H5P_register(H5P_genclass_t *pclass, const char *name, size_t size, - const void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, - H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete, - H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, - H5P_prp_close_func_t prp_close); H5_DLL hid_t H5P_get_driver(H5P_genplist_t *plist); H5_DLL void * H5P_get_driver_info(H5P_genplist_t *plist); H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, diff --git a/src/H5Pstrcpl.c b/src/H5Pstrcpl.c index 7e3195e..5125511 100644 --- a/src/H5Pstrcpl.c +++ b/src/H5Pstrcpl.c @@ -117,8 +117,7 @@ H5P_strcrt_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_NOAPI(H5P_strcrt_reg_prop, FAIL) /* Register character encoding */ - if(H5P_register(pclass, H5P_STRCRT_CHAR_ENCODING_NAME, H5P_STRCRT_CHAR_ENCODING_SIZE, - &char_encoding, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register_real(pclass, H5P_STRCRT_CHAR_ENCODING_NAME, H5P_STRCRT_CHAR_ENCODING_SIZE, &char_encoding, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: @@ -20,6 +20,7 @@ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gprivate.h" /* Groups */ diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index 9dcfa45..0e2acc8 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -41,6 +41,7 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gprivate.h" /* Groups */ #include "H5Oprivate.h" /* Object headers */ diff --git a/src/H5SMmessage.c b/src/H5SMmessage.c index 9a214ea..32ded03 100644 --- a/src/H5SMmessage.c +++ b/src/H5SMmessage.c @@ -201,7 +201,7 @@ H5SM_message_compare(const void *rec1, const void *rec2) * message in the index, we've found the message. */ if(mesg->location == H5SM_IN_HEAP && key->message.location == H5SM_IN_HEAP) { - if(key->message.u.heap_loc.fheap_id == mesg->u.heap_loc.fheap_id) + if(key->message.u.heap_loc.fheap_id.val == mesg->u.heap_loc.fheap_id.val) HGOTO_DONE(0); } /* end if */ else if(mesg->location == H5SM_IN_OH && key->message.location == H5SM_IN_OH) { @@ -301,7 +301,7 @@ H5SM_message_encode(uint8_t *raw, const void *_nrecord, void *_ctx) if(message->location == H5SM_IN_HEAP) { UINT32ENCODE(raw, message->u.heap_loc.ref_count); - UINT64ENCODE(raw, message->u.heap_loc.fheap_id); + HDmemcpy(raw, message->u.heap_loc.fheap_id.id, (size_t)H5O_FHEAP_ID_LEN); } /* end if */ else { HDassert(message->location == H5SM_IN_OH); @@ -342,7 +342,7 @@ H5SM_message_decode(const uint8_t *raw, void *_nrecord, void *_ctx) if(message->location == H5SM_IN_HEAP) { UINT32DECODE(raw, message->u.heap_loc.ref_count); - UINT64DECODE(raw, message->u.heap_loc.fheap_id); + HDmemcpy(message->u.heap_loc.fheap_id.id, raw, (size_t)H5O_FHEAP_ID_LEN); } /* end if */ else { HDassert(message->location == H5SM_IN_OH); diff --git a/src/H5Shyper.c b/src/H5Shyper.c index bdcdc28..0565cf3 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -5421,17 +5421,17 @@ H5S_hyper_spans_nelem (H5S_hyper_span_info_t *spans) REVISION LOG --------------------------------------------------------------------------*/ static H5S_hyper_span_info_t * -H5S_hyper_make_spans (unsigned rank, const hsize_t *start, const hsize_t *stride, +H5S_hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride, const hsize_t *count, const hsize_t *block) { - H5S_hyper_span_info_t *down; /* Pointer to spans in next dimension down */ - H5S_hyper_span_t *span; /* New hyperslab span */ - H5S_hyper_span_t *last_span; /* Current position in hyperslab span list */ - H5S_hyper_span_t *head; /* Head of new hyperslab span list */ - hsize_t stride_iter; /* Iterator over the stride values */ - int i; /* Counters */ - unsigned u; /* Counters */ - H5S_hyper_span_info_t *ret_value = NULL; + H5S_hyper_span_info_t *down; /* Pointer to spans in next dimension down */ + H5S_hyper_span_t *span; /* New hyperslab span */ + H5S_hyper_span_t *last_span; /* Current position in hyperslab span list */ + H5S_hyper_span_t *head; /* Head of new hyperslab span list */ + hsize_t stride_iter; /* Iterator over the stride values */ + int i; /* Counters */ + unsigned u; /* Counters */ + H5S_hyper_span_info_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_make_spans); @@ -5446,6 +5446,10 @@ H5S_hyper_make_spans (unsigned rank, const hsize_t *start, const hsize_t *stride down = NULL; for(i = (rank - 1); i >= 0; i--) { + /* Sanity check */ + if(0 == count[i]) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, NULL, "count == 0 is invalid") + /* Start a new list in this dimension */ head = NULL; last_span = NULL; @@ -5454,11 +5458,11 @@ H5S_hyper_make_spans (unsigned rank, const hsize_t *start, const hsize_t *stride for(u = 0, stride_iter = 0; u < count[i]; u++, stride_iter += stride[i]) { /* Allocate a span node */ if(NULL == (span = H5FL_MALLOC(H5S_hyper_span_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span") + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Set the span's basic information */ span->low = start[i] + stride_iter; - span->high = span->low + (block[i]-1); + span->high = span->low + (block[i] - 1); span->nelem = block[i]; span->pstride = stride[i]; span->next = NULL; @@ -5484,7 +5488,7 @@ H5S_hyper_make_spans (unsigned rank, const hsize_t *start, const hsize_t *stride /* Allocate a span info node */ if(NULL == (down = H5FL_MALLOC(H5S_hyper_span_info_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span"); + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Set the reference count */ down->count = 0; @@ -5509,17 +5513,17 @@ done: if(head && down) if(down->head != head) down = NULL; - + do { if(down) { head = down->head; - (void)H5FL_FREE(H5S_hyper_span_info_t, down); + down = H5FL_FREE(H5S_hyper_span_info_t, down); } /* end if */ down = head->down; - + while(head) { last_span = head->next; - (void)H5FL_FREE(H5S_hyper_span_t, head); + head = H5FL_FREE(H5S_hyper_span_t, head); head = last_span; } /* end while */ } while(down); @@ -7374,74 +7378,70 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter, /* Advance the hyperslab iterator */ /* Check if we are done */ - if(io_bytes_left>0) { + if(io_bytes_left > 0) { /* Move to next span in fastest changing dimension */ - curr_span=curr_span->next; + curr_span = curr_span->next; - if(curr_span!=NULL) { + if(NULL != curr_span) { /* Move location offset of destination */ - loc_off+=(curr_span->low-abs_arr[fast_dim])*elem_size; + loc_off += (curr_span->low - abs_arr[fast_dim]) * elem_size; /* Move iterator for fastest changing dimension */ - abs_arr[fast_dim]=curr_span->low; + abs_arr[fast_dim] = curr_span->low; } /* end if */ } /* end if */ else { - abs_arr[fast_dim]+=span_size/elem_size; + abs_arr[fast_dim] += span_size / elem_size; /* Check if we are still within the span */ - if(abs_arr[fast_dim]<=curr_span->high) { - iter->u.hyp.span[fast_dim]=curr_span; - - goto partial_done; /* finished with partial span */ + if(abs_arr[fast_dim] <= curr_span->high) { + iter->u.hyp.span[fast_dim] = curr_span; } /* end if */ /* If we walked off that span, advance to the next span */ else { /* Advance span in this dimension */ - curr_span=curr_span->next; + curr_span = curr_span->next; /* Check if we have a valid span in this dimension still */ - if(curr_span!=NULL) { + if(NULL != curr_span) { /* Reset absolute position */ - abs_arr[fast_dim]=curr_span->low; - iter->u.hyp.span[fast_dim]=curr_span; - - goto partial_done; /* finished with partial span */ + abs_arr[fast_dim] = curr_span->low; + iter->u.hyp.span[fast_dim] = curr_span; } /* end if */ } /* end else */ } /* end else */ /* Adjust iterator pointers */ - if(curr_span==NULL) { + if(NULL == curr_span) { /* Same as code in main loop */ /* Start at the next fastest dim */ - curr_dim=fast_dim-1; + curr_dim = fast_dim - 1; /* Work back up through the dimensions */ - while(curr_dim>=0) { + while(curr_dim >= 0) { /* Reset the current span */ - curr_span=iter->u.hyp.span[curr_dim]; + curr_span = iter->u.hyp.span[curr_dim]; /* Increment absolute position */ abs_arr[curr_dim]++; /* Check if we are still within the span */ - if(abs_arr[curr_dim]<=curr_span->high) { + if(abs_arr[curr_dim] <= curr_span->high) { break; } /* end if */ /* If we walked off that span, advance to the next span */ else { /* Advance span in this dimension */ - curr_span=curr_span->next; + curr_span = curr_span->next; /* Check if we have a valid span in this dimension still */ - if(curr_span!=NULL) { + if(NULL != curr_span) { /* Reset the span in the current dimension */ - ispan[curr_dim]=curr_span; + ispan[curr_dim] = curr_span; /* Reset absolute position */ - abs_arr[curr_dim]=curr_span->low; + abs_arr[curr_dim] = curr_span->low; break; } /* end if */ @@ -7452,63 +7452,61 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter, } /* end else */ } /* end while */ - /* Check if we are finished with the spans in the tree */ - if(curr_dim<0) { - /* We had better be done with I/O or bad things are going to happen... */ - assert(io_bytes_left==0); - - goto partial_done; /* finished with partial span */ - } /* end if */ - else { + /* Check if we have more spans in the tree */ + if(curr_dim >= 0) { /* Walk back down the iterator positions, reseting them */ - while(curr_dim<fast_dim) { - assert(curr_span); - assert(curr_span->down); - assert(curr_span->down->head); + while(curr_dim < fast_dim) { + HDassert(curr_span); + HDassert(curr_span->down); + HDassert(curr_span->down->head); /* Increment current dimension */ curr_dim++; /* Set the new span_info & span for this dimension */ - iter->u.hyp.span[curr_dim]=curr_span->down->head; + iter->u.hyp.span[curr_dim] = curr_span->down->head; /* Advance span down the tree */ - curr_span=curr_span->down->head; + curr_span = curr_span->down->head; /* Reset the absolute offset for the dim */ - abs_arr[curr_dim]=curr_span->low; + abs_arr[curr_dim] = curr_span->low; } /* end while */ /* Verify that the curr_span points to the fastest dim */ - assert(curr_span==iter->u.hyp.span[fast_dim]); - } /* end else */ + HDassert(curr_span == iter->u.hyp.span[fast_dim]); - /* Reset the buffer offset */ - for(i=0, loc_off=0; i<ndims; i++) - loc_off+=(abs_arr[i]+off_arr[i])*slab[i]; + /* Reset the buffer offset */ + for(i = 0, loc_off = 0; i < ndims; i++) + loc_off += (abs_arr[i] + off_arr[i]) * slab[i]; + } /* end else */ + else + /* We had better be done with I/O or bad things are going to happen... */ + HDassert(io_bytes_left == 0); } /* end if */ } /* end if */ -partial_done: /* Yes, goto's are evil, so sue me... :-) */ - /* Perform the I/O on the elements, based on the position of the iterator */ - while(io_bytes_left>0 && curr_seq<maxseq) { + while(io_bytes_left > 0 && curr_seq < maxseq) { + /* Sanity check */ + HDassert(curr_span); + /* Adjust location offset of destination to compensate for initial increment below */ - loc_off-=curr_span->pstride; + loc_off -= curr_span->pstride; /* Loop over all the spans in the fastest changing dimension */ - while(curr_span!=NULL) { + while(curr_span != NULL) { /* Move location offset of destination */ - loc_off+=curr_span->pstride; + loc_off += curr_span->pstride; /* Compute the number of elements to attempt in this span */ - H5_ASSIGN_OVERFLOW(span_size,curr_span->nelem,hsize_t,size_t); + H5_ASSIGN_OVERFLOW(span_size, curr_span->nelem, hsize_t, size_t); /* Check number of elements against upper bounds allowed */ - if(span_size>=io_bytes_left) { + if(span_size >= io_bytes_left) { /* Trim the number of bytes to output */ - span_size=io_bytes_left; - io_bytes_left=0; + span_size = io_bytes_left; + io_bytes_left = 0; /* COMMON */ /* Store the I/O information for the span */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 5f4c74d..d2e46cf 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -384,8 +384,8 @@ H5S_point_iter_release (H5S_sel_iter_t UNUSED * iter) static herr_t H5S_point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *coord) { - H5S_pnt_node_t *top, *curr, *new_node; /* Point selection nodes */ - unsigned i; /* Counter */ + H5S_pnt_node_t *top = NULL, *curr = NULL, *new_node = NULL; /* Point selection nodes */ + unsigned u; /* Counter */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5S_point_add) @@ -395,26 +395,27 @@ H5S_point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *co HDassert(coord); HDassert(op == H5S_SELECT_SET || op == H5S_SELECT_APPEND || op == H5S_SELECT_PREPEND); - top = curr = NULL; - for(i = 0; i < num_elem; i++) { + for(u = 0; u < num_elem; u++) { /* Allocate space for the new node */ if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node") + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node") + /* Initialize fields in node */ + new_node->next = NULL; if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(space->extent.rank * sizeof(hsize_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information") + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information") /* Copy over the coordinates */ - HDmemcpy(new_node->pnt, coord + (i * space->extent.rank), (space->extent.rank * sizeof(hsize_t))); + HDmemcpy(new_node->pnt, coord + (u * space->extent.rank), (space->extent.rank * sizeof(hsize_t))); /* Link into list */ - new_node->next = NULL; if(top == NULL) top = new_node; else curr->next = new_node; curr = new_node; } /* end for */ + new_node = NULL; /* Insert the list of points selected in the proper place */ if(op == H5S_SELECT_SET || op == H5S_SELECT_PREPEND) { @@ -426,13 +427,15 @@ H5S_point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *co space->select.sel_info.pnt_lst->head = top; } /* end if */ else { /* op==H5S_SELECT_APPEND */ - new_node = space->select.sel_info.pnt_lst->head; - if(new_node != NULL) { - while(new_node->next != NULL) - new_node = new_node->next; + H5S_pnt_node_t *tmp_node; /* Temporary point selection node */ + + tmp_node = space->select.sel_info.pnt_lst->head; + if(tmp_node != NULL) { + while(tmp_node->next != NULL) + tmp_node = tmp_node->next; /* Append new list to point selection */ - new_node->next = top; + tmp_node->next = top; } /* end if */ else space->select.sel_info.pnt_lst->head = top; @@ -445,6 +448,20 @@ H5S_point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *co space->select.num_elem += num_elem; done: + if(ret_value < 0) { + /* Release possibly partially initialized new node */ + if(new_node) + new_node = H5FL_FREE(H5S_pnt_node_t, new_node); + + /* Release possible linked list of nodes */ + while(top) { + curr = top->next; + H5MM_xfree(top->pnt); + top = H5FL_FREE(H5S_pnt_node_t, top); + top = curr; + } /* end while */ + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5S_point_add() */ @@ -477,20 +494,19 @@ H5S_point_release (H5S_t *space) HDassert(space); /* Delete all the nodes from the list */ - curr=space->select.sel_info.pnt_lst->head; - while(curr!=NULL) { - next=curr->next; + curr = space->select.sel_info.pnt_lst->head; + while(curr != NULL) { + next = curr->next; H5MM_xfree(curr->pnt); - (void)H5FL_FREE(H5S_pnt_node_t, curr); - curr=next; + curr = H5FL_FREE(H5S_pnt_node_t, curr); + curr = next; } /* end while */ /* Free & reset the point list header */ - (void)H5FL_FREE(H5S_pnt_list_t, space->select.sel_info.pnt_lst); - space->select.sel_info.pnt_lst=NULL; + space->select.sel_info.pnt_lst = H5FL_FREE(H5S_pnt_list_t, space->select.sel_info.pnt_lst); /* Reset the number of elements in the selection */ - space->select.num_elem=0; + space->select.num_elem = 0; FUNC_LEAVE_NOAPI(SUCCEED) } /* H5S_point_release() */ @@ -34,6 +34,7 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ @@ -1937,9 +1938,9 @@ done: * Raymond Lu * 4 December 2009 * Added a flag as a parameter to indicate whether the caller is - * H5Tdetect_class. I also added the check for VL string type + * H5Tdetect_class. I also added the check for VL string type * just like the public function. Because we want to tell users - * VL string is a string type but we treat it as a VL type + * VL string is a string type but we treat it as a VL type * internally, H5T_detect_class needs to know where the caller * is from. *------------------------------------------------------------------------- @@ -1962,7 +1963,7 @@ H5T_detect_class(const H5T_t *dt, H5T_class_t cls, hbool_t from_api) */ if(from_api && H5T_IS_VL_STRING(dt->shared)) HGOTO_DONE(H5T_STRING == cls); - + /* Check if this type is the correct type */ if(dt->shared->type==cls) HGOTO_DONE(TRUE); @@ -3852,7 +3853,7 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset) /* Sanity check */ HDassert(dt1); HDassert(dt2); - + /* the easy case */ if(dt1 == dt2) HGOTO_DONE(0); diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 46a1ac8..2320b28 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -32,6 +32,7 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5FOprivate.h" /* File objects */ #include "H5Iprivate.h" /* IDs */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index bfa5d56..cda9011 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -10501,6 +10501,8 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, sfirst = (ssize_t)(src.prec - 1); is_max_neg = 0; } + if(sfirst < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "zero bit not found") /* Sign bit has been negated if bit vector isn't 0x80...00. Set all bits in front of * sign bit to 0 in the temporary buffer because they're all negated from the previous diff --git a/src/H5Tdeprec.c b/src/H5Tdeprec.c index 9d9ad36..07d3865 100644 --- a/src/H5Tdeprec.c +++ b/src/H5Tdeprec.c @@ -41,6 +41,7 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5FOprivate.h" /* File objects */ #include "H5Iprivate.h" /* IDs */ diff --git a/src/H5Tenum.c b/src/H5Tenum.c index f955a7e..6da6931 100644 --- a/src/H5Tenum.c +++ b/src/H5Tenum.c @@ -466,10 +466,11 @@ H5T_enum_nameof(const H5T_t *dt, const void *value, char *name/*out*/, size_t si /* Set return value */ ret_value=name; - if (H5T_close(copied_dt)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close data type"); - done: + if(copied_dt) + if(H5T_close(copied_dt) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close data type"); + FUNC_LEAVE_NOAPI(ret_value) } @@ -591,9 +592,11 @@ H5T_enum_valueof(const H5T_t *dt, const char *name, void *value/*out*/) HDmemcpy(value, copied_dt->shared->u.enumer.value+md*copied_dt->shared->size, copied_dt->shared->size); - if (H5T_close(copied_dt)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close data type"); - done: + if(copied_dt) + if(H5T_close(copied_dt) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close data type") + FUNC_LEAVE_NOAPI(ret_value) } + diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 8d8920b..b22e3e5 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -38,7 +38,7 @@ static H5T_t *H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction size_t *struct_align, size_t *offset, size_t *comp_size); static H5T_t *H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size); -static H5T_t* H5T_get_native_bitfield(size_t prec, H5T_direction_t direction, +static H5T_t* H5T_get_native_bitfield(size_t prec, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size); static herr_t H5T_cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, size_t nelems, size_t align, size_t *struct_align); @@ -795,7 +795,7 @@ done: *------------------------------------------------------------------------- */ static H5T_t* -H5T_get_native_bitfield(size_t prec, H5T_direction_t direction, size_t *struct_align, +H5T_get_native_bitfield(size_t prec, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) { H5T_t *dt; /* Appropriate native datatype to copy */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 412012a..8a6ee05 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -161,7 +161,7 @@ H5T_vlen_create(const H5T_t *base) /* Build new type */ if(NULL == (dt = H5T_alloc())) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, NULL, "memory allocation failed") dt->shared->type = H5T_VLEN; /* @@ -169,7 +169,8 @@ H5T_vlen_create(const H5T_t *base) * data, not point to the same VL sequences) */ dt->shared->force_conv = TRUE; - dt->shared->parent = H5T_copy(base, H5T_COPY_ALL); + if(NULL == (dt->shared->parent = H5T_copy(base, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy base datatype") /* Inherit encoding version from base type */ dt->shared->version = base->shared->version; @@ -185,6 +186,10 @@ H5T_vlen_create(const H5T_t *base) ret_value = dt; done: + if(!ret_value) + if(dt && H5T_close(dt) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, NULL, "unable to release datatype info") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_vlen_create() */ @@ -280,11 +285,11 @@ H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* Set file ID (since this VL is on disk) */ dt->shared->u.vlen.f = f; break; - + case H5T_LOC_BADLOC: /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined * location for VL type and leaves it for the caller to decide. - */ + */ break; default: diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index 8e32ab7..5927713 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -16,6 +16,7 @@ #define H5Z_PACKAGE /*suppress error about including H5Zpkg */ #include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ diff --git a/src/H5detect.c b/src/H5detect.c index ebd042d..8fc1690 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -109,7 +109,6 @@ static void detect_C99_integers32(void); static void detect_C99_integers64(void); static void detect_alignments(void); static void insert_libhdf5_settings(FILE *flibinfo); -static void make_libinfo(void); static size_t align_g[] = {1, 2, 4, 8, 16}; static jmp_buf jbuf_g; @@ -504,99 +503,6 @@ sigbus_handler(int UNUSED signo) /*------------------------------------------------------------------------- - * Function: insert_libhdf5_settings - * - * Purpose: insert the contents of libhdf5.settings into a file - * represented by flibinfo. - * Make it an empty string if H5_HAVE_EMBEDDED_LIBINFO is not - * defined, i.e., not enabled. - * - * Return: void - * - * Programmer: Albert Cheng - * Apr 20, 2009 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -#define LIBSETTINGSFNAME "libhdf5.settings" -static void -insert_libhdf5_settings(FILE *flibinfo) -{ -#ifdef H5_HAVE_EMBEDDED_LIBINFO - FILE *fsettings; /* for files libhdf5.settings */ - int inchar; - int bol=0; /* indicates the beginning of a new line */ - - if (NULL==(fsettings=HDfopen(LIBSETTINGSFNAME, "r"))){ - perror(LIBSETTINGSFNAME); - exit(1); - } - /* print variable definition and the string */ - fprintf(flibinfo, "char H5libhdf5_settings[]=\n"); - bol++; - while (EOF != (inchar = getc(fsettings))){ - if (bol){ - /* Start a new line */ - fprintf(flibinfo, "\t\""); - bol = 0; - } - if (inchar == '\n'){ - /* end of a line */ - fprintf(flibinfo, "\\n\"\n"); - bol++; - }else{ - putc(inchar, flibinfo); - } - } - if (feof(fsettings)){ - /* wrap up */ - if (!bol){ - /* EOF found without a new line */ - fprintf(flibinfo, "\\n\"\n"); - }; - fprintf(flibinfo, ";\n\n"); - }else{ - fprintf(stderr, "Read errors encountered with %s\n", LIBSETTINGSFNAME); - exit(1); - } - if (0 != fclose(fsettings)){ - perror(LIBSETTINGSFNAME); - exit(1); - } -#else - /* print variable definition and an empty string */ - fprintf(flibinfo, "char H5libhdf5_settings[]=\"\";\n"); -#endif -} - - -/*------------------------------------------------------------------------- - * Function: make_libinfo - * - * Purpose: Create the embedded library information definition. - * This sets up for a potential extension that the declaration - * is printed to a file different from stdout. - * - * Return: void - * - * Programmer: Albert Cheng - * Sep 15, 2009 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -make_libinfo(void) -{ - /* print variable definition and then the string as a macro. */ - insert_libhdf5_settings(stdout); -} - - -/*------------------------------------------------------------------------- * Function: print_results * * Purpose: Prints information about the detected data types. @@ -677,9 +583,6 @@ print_results(int nd, detected_t *d, int na, malign_t *misc_align) /*******************/\n\ \n"); - /* Generate embedded library information variable definition */ - make_libinfo(); - /* The interface initialization function */ printf("\n\ \n\ @@ -1154,8 +1057,8 @@ find_bias(int epos, int esize, int *perm, void *_a) /*------------------------------------------------------------------------- * Function: print_header - * - * Purpose: Prints the C file header for the generated file. + * + * Purpose: Prints the C file header for the generated file. * * Return: void * diff --git a/src/H5make_libsettings.c b/src/H5make_libsettings.c new file mode 100644 index 0000000..771c510 --- /dev/null +++ b/src/H5make_libsettings.c @@ -0,0 +1,278 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*keep this declaration near the top of this file -RPM*/ +static const char *FileHeader = "\n\ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\ + * Copyright by The HDF Group. *\n\ + * Copyright by the Board of Trustees of the University of Illinois. *\n\ + * All rights reserved. *\n\ + * *\n\ + * This file is part of HDF5. The full HDF5 copyright notice, including *\n\ + * terms governing use, modification, and redistribution, is contained in *\n\ + * the files COPYING and Copyright.html. COPYING can be found at the root *\n\ + * of the source code distribution tree; Copyright.html can be found at the *\n\ + * root level of an installed copy of the electronic HDF5 document set and *\n\ + * is linked from the top-level documents page. It can also be found at *\n\ + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *\n\ + * access to either file, you may request a copy from help@hdfgroup.org. *\n\ + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"; +/* + * + * Created: H5make_libsettings.c + * 17 Mar 2010 + * Quincey Koziol + * + * Purpose: Generate the H5libsettings.h header file from the + * libhdf5.settings file. + * + *------------------------------------------------------------------------- + */ +#include <stdio.h> +#include <time.h> +#include "H5private.h" + +#define LIBSETTINGSFNAME "libhdf5.settings" + + +/*------------------------------------------------------------------------- + * Function: insert_libhdf5_settings + * + * Purpose: insert the contents of libhdf5.settings into a file + * represented by flibinfo. + * Make it an empty string if H5_HAVE_EMBEDDED_LIBINFO is not + * defined, i.e., not enabled. + * + * Return: void + * + * Programmer: Albert Cheng + * Apr 20, 2009 + * + *------------------------------------------------------------------------- + */ +static void +insert_libhdf5_settings(FILE *flibinfo) +{ +#ifdef H5_HAVE_EMBEDDED_LIBINFO + FILE *fsettings; /* for files libhdf5.settings */ + int inchar; + int bol=0; /* indicates the beginning of a new line */ + + if (NULL==(fsettings=HDfopen(LIBSETTINGSFNAME, "r"))){ + perror(LIBSETTINGSFNAME); + exit(1); + } + /* print variable definition and the string */ + fprintf(flibinfo, "static const char H5libhdf5_settings[]=\n"); + bol++; + while (EOF != (inchar = getc(fsettings))){ + if (bol){ + /* Start a new line */ + fprintf(flibinfo, "\t\""); + bol = 0; + } + if (inchar == '\n'){ + /* end of a line */ + fprintf(flibinfo, "\\n\"\n"); + bol++; + }else{ + putc(inchar, flibinfo); + } + } + if (feof(fsettings)){ + /* wrap up */ + if (!bol){ + /* EOF found without a new line */ + fprintf(flibinfo, "\\n\"\n"); + }; + fprintf(flibinfo, ";\n\n"); + }else{ + fprintf(stderr, "Read errors encountered with %s\n", LIBSETTINGSFNAME); + exit(1); + } + if (0 != fclose(fsettings)){ + perror(LIBSETTINGSFNAME); + exit(1); + } +#else + /* print variable definition and an empty string */ + fprintf(flibinfo, "static const char H5libhdf5_settings[]=\"\";\n"); +#endif +} /* insert_libhdf5_settings() */ + + +/*------------------------------------------------------------------------- + * Function: make_libinfo + * + * Purpose: Create the embedded library information definition. + * This sets up for a potential extension that the declaration + * is printed to a file different from stdout. + * + * Return: void + * + * Programmer: Albert Cheng + * Sep 15, 2009 + * + *------------------------------------------------------------------------- + */ +static void +make_libinfo(void) +{ + /* print variable definition and then the string as a macro. */ + insert_libhdf5_settings(stdout); +} + + +/*------------------------------------------------------------------------- + * Function: print_header + * + * Purpose: Prints the C file header for the generated file. + * + * Return: void + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Mar 12 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +print_header(void) +{ + time_t now = time(NULL); + struct tm *tm = localtime(&now); + char real_name[30]; + char host_name[256]; + int i; + const char *s; +#ifdef H5_HAVE_GETPWUID + struct passwd *pwd = NULL; +#else + int pwd = 1; +#endif + static const char *month_name[] = + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + static const char *purpose = "\ +This machine-generated source code contains\n\ +information about the library build configuration\n"; + + /* + * The real name is the first item from the passwd gecos field. + */ +#ifdef H5_HAVE_GETPWUID + { + size_t n; + char *comma; + if ((pwd = getpwuid(getuid()))) { + if ((comma = strchr(pwd->pw_gecos, ','))) { + n = MIN(sizeof(real_name)-1, (unsigned)(comma-pwd->pw_gecos)); + strncpy(real_name, pwd->pw_gecos, n); + real_name[n] = '\0'; + } else { + strncpy(real_name, pwd->pw_gecos, sizeof(real_name)); + real_name[sizeof(real_name) - 1] = '\0'; + } + } else { + real_name[0] = '\0'; + } + } +#else + real_name[0] = '\0'; +#endif + + /* + * The FQDM of this host or the empty string. + */ +#ifdef H5_HAVE_GETHOSTNAME + if (gethostname(host_name, sizeof(host_name)) < 0) { + host_name[0] = '\0'; + } +#else + host_name[0] = '\0'; +#endif + + /* + * The file header: warning, copyright notice, build information. + */ + printf("/* Generated automatically by H5make_libsettings -- do not edit */\n\n\n"); + puts(FileHeader); /*the copyright notice--see top of this file */ + + printf(" *\n * Created:\t\t%s %2d, %4d\n", + month_name[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year); + if (pwd || real_name[0] || host_name[0]) { + printf(" *\t\t\t"); + if (real_name[0]) printf("%s <", real_name); +#ifdef H5_HAVE_GETPWUID + if (pwd) fputs(pwd->pw_name, stdout); +#endif + if (host_name[0]) printf("@%s", host_name); + if (real_name[0]) printf(">"); + putchar('\n'); + } + printf(" *\n * Purpose:\t\t"); + for (s = purpose; *s; s++) { + putchar(*s); + if ('\n' == *s && s[1]) printf(" *\t\t\t"); + } + + printf(" *\n * Modifications:\n *\n"); + printf(" *\tDO NOT MAKE MODIFICATIONS TO THIS FILE!\n"); + printf(" *\tIt was generated by code in `H5make_libsettings.c'.\n"); + + printf(" *\n *"); + for (i = 0; i < 73; i++) putchar('-'); + printf("\n */\n\n"); + +} + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Main entry point. + * + * Return: Success: exit(0) + * + * Failure: exit(1) + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 12, 1996 + * + * Modifications: + * Albert Cheng, 2004/05/20 + * Some compilers, e.g., Intel C v7.0, took a long time to compile + * with optimization when a module routine contains many code lines. + * Divide up all those types detections macros into subroutines, both + * to avoid the compiler optimization error and cleaner codes. + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + + print_header(); + + /* Generate embedded library information variable definition */ + make_libinfo(); + + return 0; +} + diff --git a/src/H5private.h b/src/H5private.h index c0b5054..277fe70 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1143,7 +1143,7 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...); #ifndef HDsrandom #define HDsrandom(S) HDsrand(S) #endif /* HDsrandom */ - #elif H5_HAVE_RANDOM +#elif H5_HAVE_RANDOM #ifndef HDsrand #define HDsrand(S) srandom(S) #endif /* HDsrand */ @@ -1535,7 +1535,6 @@ typedef struct H5_debug_t { extern H5_debug_t H5_debug_g; #define H5DEBUG(X) (H5_debug_g.pkg[H5_PKG_##X].stream) -extern char H5libhdf5_settings[]; /* embedded library information */ /*------------------------------------------------------------------------- * Purpose: These macros are inserted automatically just after the diff --git a/src/H5public.h b/src/H5public.h index 5c1aff8..7213909 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -71,10 +71,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 59 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 64 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "FA_a4" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.59-FA_a4" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.64-FA_a4" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5system.c b/src/H5system.c index 9d93d9c..5725218 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -592,7 +592,7 @@ HDremove_all(const char *fname) * This implementation is taken from the Cygwin source distribution at * src/winsup/mingw/mingwex/gettimeofday.c * - * The original source code was contributed by + * The original source code was contributed by * Danny Smith <dannysmith@users.sourceforge.net> * and released in the public domain. * @@ -606,7 +606,7 @@ HDremove_all(const char *fname) /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ #define _W32_FT_OFFSET (116444736000000000ULL) -int +int HDgettimeofday(struct timeval *tv, void *tz) { union { diff --git a/src/H5trace.c b/src/H5trace.c index b554b80..8c83505 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -916,172 +916,189 @@ H5_trace (const double *returning, const char *func, const char *type, ...) break; case 'i': - if (ptr) { - if (vp) { - fprintf (out, "0x%lx", (unsigned long)vp); - } else { + if(ptr) { + if(vp) + fprintf(out, "0x%lx", (unsigned long)vp); + else fprintf(out, "NULL"); - } - } else { + } /* end if */ + else { hid_t obj = va_arg (ap, hid_t); - if (H5P_DEFAULT == obj) { - fprintf (out, "H5P_DEFAULT"); - } else if (obj<0) { - fprintf (out, "FAIL"); - } else { - switch (H5I_TYPE(obj)) { /* Use internal H5I macro instead of function call */ + + if(H5P_DEFAULT == obj) + fprintf(out, "H5P_DEFAULT"); + else if(obj < 0) + fprintf(out, "FAIL"); + else { + switch(H5I_TYPE(obj)) { /* Use internal H5I macro instead of function call */ case H5I_UNINIT: - fprintf (out, "%ld (uninit - error)", (long)obj); + fprintf(out, "%ld (uninit - error)", (long)obj); break; + case H5I_BADID: - fprintf (out, "%ld (error)", (long)obj); + fprintf(out, "%ld (error)", (long)obj); break; + case H5I_FILE: fprintf(out, "%ld (file)", (long)obj); break; + case H5I_GROUP: fprintf(out, "%ld (group)", (long)obj); break; + case H5I_DATATYPE: - if (obj==H5T_NATIVE_SCHAR_g) { + if(obj == H5T_NATIVE_SCHAR_g) fprintf(out, "H5T_NATIVE_SCHAR"); - } else if (obj==H5T_NATIVE_UCHAR_g) { + else if(obj == H5T_NATIVE_UCHAR_g) fprintf(out, "H5T_NATIVE_UCHAR"); - } else if (obj==H5T_NATIVE_SHORT_g) { + else if(obj == H5T_NATIVE_SHORT_g) fprintf(out, "H5T_NATIVE_SHORT"); - } else if (obj==H5T_NATIVE_USHORT_g) { + else if(obj == H5T_NATIVE_USHORT_g) fprintf(out, "H5T_NATIVE_USHORT"); - } else if (obj==H5T_NATIVE_INT_g) { + else if(obj == H5T_NATIVE_INT_g) fprintf(out, "H5T_NATIVE_INT"); - } else if (obj==H5T_NATIVE_UINT_g) { + else if(obj == H5T_NATIVE_UINT_g) fprintf(out, "H5T_NATIVE_UINT"); - } else if (obj==H5T_NATIVE_LONG_g) { + else if(obj == H5T_NATIVE_LONG_g) fprintf(out, "H5T_NATIVE_LONG"); - } else if (obj==H5T_NATIVE_ULONG_g) { + else if(obj == H5T_NATIVE_ULONG_g) fprintf(out, "H5T_NATIVE_ULONG"); - } else if (obj==H5T_NATIVE_LLONG_g) { + else if(obj == H5T_NATIVE_LLONG_g) fprintf(out, "H5T_NATIVE_LLONG"); - } else if (obj==H5T_NATIVE_ULLONG_g) { + else if(obj == H5T_NATIVE_ULLONG_g) fprintf(out, "H5T_NATIVE_ULLONG"); - } else if (obj==H5T_NATIVE_FLOAT_g) { + else if(obj == H5T_NATIVE_FLOAT_g) fprintf(out, "H5T_NATIVE_FLOAT"); - } else if (obj==H5T_NATIVE_DOUBLE_g) { + else if(obj == H5T_NATIVE_DOUBLE_g) fprintf(out, "H5T_NATIVE_DOUBLE"); #if H5_SIZEOF_LONG_DOUBLE !=0 - } else if (obj==H5T_NATIVE_LDOUBLE_g) { + else if(obj == H5T_NATIVE_LDOUBLE_g) fprintf(out, "H5T_NATIVE_LDOUBLE"); #endif - } else if (obj==H5T_IEEE_F32BE_g) { + else if(obj == H5T_IEEE_F32BE_g) fprintf(out, "H5T_IEEE_F32BE"); - } else if (obj==H5T_IEEE_F32LE_g) { + else if(obj == H5T_IEEE_F32LE_g) fprintf(out, "H5T_IEEE_F32LE"); - } else if (obj==H5T_IEEE_F64BE_g) { + else if(obj == H5T_IEEE_F64BE_g) fprintf(out, "H5T_IEEE_F64BE"); - } else if (obj==H5T_IEEE_F64LE_g) { + else if(obj == H5T_IEEE_F64LE_g) fprintf(out, "H5T_IEEE_F64LE"); - } else if (obj==H5T_STD_I8BE_g) { + else if(obj == H5T_STD_I8BE_g) fprintf(out, "H5T_STD_I8BE"); - } else if (obj==H5T_STD_I8LE_g) { + else if(obj == H5T_STD_I8LE_g) fprintf(out, "H5T_STD_I8LE"); - } else if (obj==H5T_STD_I16BE_g) { + else if(obj == H5T_STD_I16BE_g) fprintf(out, "H5T_STD_I16BE"); - } else if (obj==H5T_STD_I16LE_g) { + else if(obj == H5T_STD_I16LE_g) fprintf(out, "H5T_STD_I16LE"); - } else if (obj==H5T_STD_I32BE_g) { + else if(obj == H5T_STD_I32BE_g) fprintf(out, "H5T_STD_I32BE"); - } else if (obj==H5T_STD_I32LE_g) { + else if(obj == H5T_STD_I32LE_g) fprintf(out, "H5T_STD_I32LE"); - } else if (obj==H5T_STD_I64BE_g) { + else if(obj == H5T_STD_I64BE_g) fprintf(out, "H5T_STD_I64BE"); - } else if (obj==H5T_STD_I64LE_g) { + else if(obj == H5T_STD_I64LE_g) fprintf(out, "H5T_STD_I64LE"); - } else if (obj==H5T_STD_U8BE_g) { + else if(obj == H5T_STD_U8BE_g) fprintf(out, "H5T_STD_U8BE"); - } else if (obj==H5T_STD_U8LE_g) { + else if(obj == H5T_STD_U8LE_g) fprintf(out, "H5T_STD_U8LE"); - } else if (obj==H5T_STD_U16BE_g) { + else if(obj == H5T_STD_U16BE_g) fprintf(out, "H5T_STD_U16BE"); - } else if (obj==H5T_STD_U16LE_g) { + else if(obj == H5T_STD_U16LE_g) fprintf(out, "H5T_STD_U16LE"); - } else if (obj==H5T_STD_U32BE_g) { + else if(obj == H5T_STD_U32BE_g) fprintf(out, "H5T_STD_U32BE"); - } else if (obj==H5T_STD_U32LE_g) { + else if(obj == H5T_STD_U32LE_g) fprintf(out, "H5T_STD_U32LE"); - } else if (obj==H5T_STD_U64BE_g) { + else if(obj == H5T_STD_U64BE_g) fprintf(out, "H5T_STD_U64BE"); - } else if (obj==H5T_STD_U64LE_g) { + else if(obj == H5T_STD_U64LE_g) fprintf(out, "H5T_STD_U64LE"); - } else if (obj==H5T_STD_B8BE_g) { + else if(obj == H5T_STD_B8BE_g) fprintf(out, "H5T_STD_B8BE"); - } else if (obj==H5T_STD_B8LE_g) { + else if(obj == H5T_STD_B8LE_g) fprintf(out, "H5T_STD_B8LE"); - } else if (obj==H5T_STD_B16BE_g) { + else if(obj == H5T_STD_B16BE_g) fprintf(out, "H5T_STD_B16BE"); - } else if (obj==H5T_STD_B16LE_g) { + else if(obj == H5T_STD_B16LE_g) fprintf(out, "H5T_STD_B16LE"); - } else if (obj==H5T_STD_B32BE_g) { + else if(obj == H5T_STD_B32BE_g) fprintf(out, "H5T_STD_B32BE"); - } else if (obj==H5T_STD_B32LE_g) { + else if(obj == H5T_STD_B32LE_g) fprintf(out, "H5T_STD_B32LE"); - } else if (obj==H5T_STD_B64BE_g) { + else if(obj == H5T_STD_B64BE_g) fprintf(out, "H5T_STD_B64BE"); - } else if (obj==H5T_STD_B64LE_g) { + else if(obj == H5T_STD_B64LE_g) fprintf(out, "H5T_STD_B64LE"); - } else if (obj==H5T_C_S1_g) { + else if(obj == H5T_C_S1_g) fprintf(out, "H5T_C_S1"); - } else if (obj==H5T_FORTRAN_S1_g) { + else if(obj == H5T_FORTRAN_S1_g) fprintf(out, "H5T_FORTRAN_S1"); - } else { + else fprintf(out, "%ld (dtype)", (long)obj); - } break; + case H5I_DATASPACE: fprintf(out, "%ld (dspace)", (long)obj); /* Save the rank of simple data spaces for arrays */ /* This may generate recursive call to the library... -QAK */ { - H5S_t *space = (H5S_t *)H5I_object(obj); - if (H5S_SIMPLE==H5S_GET_EXTENT_TYPE(space)) { - asize[argno] = H5S_GET_EXTENT_NDIMS(space); - } + H5S_t *space; + + if(NULL != (space = (H5S_t *)H5I_object(obj))) + if(H5S_SIMPLE == H5S_GET_EXTENT_TYPE(space)) + asize[argno] = H5S_GET_EXTENT_NDIMS(space); } break; + case H5I_DATASET: fprintf(out, "%ld (dset)", (long)obj); break; + case H5I_ATTR: fprintf(out, "%ld (attr)", (long)obj); break; + case H5I_REFERENCE: fprintf(out, "%ld (reference)", (long)obj); break; + case H5I_VFL: fprintf(out, "%ld (file driver)", (long)obj); break; + case H5I_GENPROP_CLS: fprintf(out, "%ld (genprop class)", (long)obj); break; + case H5I_GENPROP_LST: fprintf(out, "%ld (genprop list)", (long)obj); break; + case H5I_ERROR_CLASS: fprintf(out, "%ld (err class)", (long)obj); break; + case H5I_ERROR_MSG: fprintf(out, "%ld (err msg)", (long)obj); break; + case H5I_ERROR_STACK: fprintf(out, "%ld (err stack)", (long)obj); break; + case H5I_NTYPES: fprintf (out, "%ld (ntypes - error)", (long)obj); break; + default: fprintf(out, "%ld (unknown class)", (long)obj); break; - } - } - } + } /* end switch */ + } /* end else */ + } /* end else */ break; case 'I': diff --git a/src/Makefile.am b/src/Makefile.am index 5c5a7aa..899cdde 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ include $(top_srcdir)/config/lt_vers.am # Use -g to force no optimization since many compilers (e.g., Intel) takes # a long time to compile it with any optimization on. H5detect is used # to generate H5Tinit.c once. So, optimization is not critical. -noinst_PROGRAMS = H5detect +noinst_PROGRAMS = H5detect H5make_libsettings H5detect_CFLAGS = -g $(AM_CFLAGS) # Our main target, the HDF5 library @@ -36,7 +36,7 @@ lib_LTLIBRARIES=libhdf5.la libhdf5_la_LDFLAGS= -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE) $(AM_LDFLAGS) # H5Tinit.c is a generated file, and should be cleaned. -MOSTLYCLEANFILES=H5Tinit.c +MOSTLYCLEANFILES=H5Tinit.c H5lib_settings.h # H5pubconf.h is generated by configure, and should be cleaned. DISTCLEANFILES=H5pubconf.h @@ -137,6 +137,20 @@ H5Tinit.c: H5detect$(EXEEXT) (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ ($(RM) $@ ; exit 1) +H5.o H5.lo: H5lib_settings.h + +# Build configuration header file generation +# The LD_LIBRARY_PATH setting is a kludge. +# Things should have been all set during H5make_libsettings making. +# Remove the generated .h file if errors occur unless HDF5_Make_Ignore +# is set to ignore the error. +H5lib_settings.h: H5make_libsettings$(EXEEXT) libhdf5.settings + LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) | \ + sed -e 's/-L/:/g' -e 's/ //g'`" \ + $(RUNSERIAL) ./H5make_libsettings$(EXEEXT) > H5lib_settings.h || \ + (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ + ($(RM) $@ ; exit 1) + # Error header generation # # Actually, H5Einit.h, H5Eterm.h, H5Edefin.h and H5Epubgen.h all diff --git a/src/Makefile.in b/src/Makefile.in index dcabcfe..059176a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -59,7 +59,7 @@ DIST_COMMON = $(include_HEADERS) $(srcdir)/H5config.h.in \ $(srcdir)/libhdf5.settings.in $(top_srcdir)/config/commence.am \ $(top_srcdir)/config/conclude.am \ $(top_srcdir)/config/lt_vers.am COPYING -noinst_PROGRAMS = H5detect$(EXEEXT) +noinst_PROGRAMS = H5detect$(EXEEXT) H5make_libsettings$(EXEEXT) TESTS = subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -158,6 +158,9 @@ H5detect_LDADD = $(LDADD) H5detect_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(H5detect_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ +H5make_libsettings_SOURCES = H5make_libsettings.c +H5make_libsettings_OBJECTS = H5make_libsettings.$(OBJEXT) +H5make_libsettings_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/bin/depcomp am__depfiles_maybe = depfiles @@ -171,8 +174,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libhdf5_la_SOURCES) H5detect.c -DIST_SOURCES = $(libhdf5_la_SOURCES) H5detect.c +SOURCES = $(libhdf5_la_SOURCES) H5detect.c H5make_libsettings.c +DIST_SOURCES = $(libhdf5_la_SOURCES) H5detect.c H5make_libsettings.c DATA = $(settings_DATA) HEADERS = $(include_HEADERS) ETAGS = etags @@ -441,7 +444,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 49 +LT_VERS_REVISION = 54 LT_VERS_AGE = 0 H5detect_CFLAGS = -g $(AM_CFLAGS) @@ -452,7 +455,7 @@ lib_LTLIBRARIES = libhdf5.la libhdf5_la_LDFLAGS = -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE) $(AM_LDFLAGS) # H5Tinit.c is a generated file, and should be cleaned. -MOSTLYCLEANFILES = H5Tinit.c +MOSTLYCLEANFILES = H5Tinit.c H5lib_settings.h # H5pubconf.h is generated by configure, and should be cleaned. DISTCLEANFILES = H5pubconf.h @@ -656,6 +659,9 @@ clean-noinstPROGRAMS: H5detect$(EXEEXT): $(H5detect_OBJECTS) $(H5detect_DEPENDENCIES) @rm -f H5detect$(EXEEXT) $(H5detect_LINK) $(H5detect_OBJECTS) $(H5detect_LDADD) $(LIBS) +H5make_libsettings$(EXEEXT): $(H5make_libsettings_OBJECTS) $(H5make_libsettings_DEPENDENCIES) + @rm -f H5make_libsettings$(EXEEXT) + $(LINK) $(H5make_libsettings_OBJECTS) $(H5make_libsettings_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -919,6 +925,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5checksum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5dbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5detect-H5detect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5make_libsettings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5system.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5timer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5trace.Plo@am__quote@ @@ -1250,6 +1257,20 @@ H5Tinit.c: H5detect$(EXEEXT) (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ ($(RM) $@ ; exit 1) +H5.o H5.lo: H5lib_settings.h + +# Build configuration header file generation +# The LD_LIBRARY_PATH setting is a kludge. +# Things should have been all set during H5make_libsettings making. +# Remove the generated .h file if errors occur unless HDF5_Make_Ignore +# is set to ignore the error. +H5lib_settings.h: H5make_libsettings$(EXEEXT) libhdf5.settings + LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) | \ + sed -e 's/-L/:/g' -e 's/ //g'`" \ + $(RUNSERIAL) ./H5make_libsettings$(EXEEXT) > H5lib_settings.h || \ + (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ + ($(RM) $@ ; exit 1) + # Error header generation # # Actually, H5Einit.h, H5Eterm.h, H5Edefin.h and H5Epubgen.h all |