diff options
Diffstat (limited to 'src')
131 files changed, 7393 insertions, 4437 deletions
@@ -61,6 +61,10 @@ static void H5_debug_mask(const char*); /* Library Private Variables */ /*****************************/ +/* HDF5 API Entered variable */ +/* (move to H5.c when new FUNC_ENTER macros in actual use -QAK) */ +hbool_t H5_api_entered_g = FALSE; + /* statically initialize block for pthread_once call used in initializing */ /* the first global mutex */ #ifdef H5_HAVE_THREADSAFE @@ -348,7 +352,7 @@ H5dont_atexit(void) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API_NOINIT_NOFS(H5dont_atexit) + FUNC_ENTER_API_NOINIT_NOERR_NOFS(H5dont_atexit) H5TRACE0("e",""); if(H5_dont_atexit_g) @@ -622,10 +626,10 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) char substr[] = H5_VERS_SUBRELEASE; static int checked = 0; /* If we've already checked the version info */ static unsigned int disable_version_check = 0; /* Set if the version check should be disabled */ - herr_t ret_value=SUCCEED; /* Return value */ - static char *version_mismatch_warning=VERSION_MISMATCH_WARNING; + static const char *version_mismatch_warning = VERSION_MISMATCH_WARNING; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API_NOINIT_NOFS(H5check_version) + FUNC_ENTER_API_NOINIT_NOERR_NOFS(H5check_version) H5TRACE3("e", "IuIuIu", majnum, minnum, relnum); /* Don't check again, if we already have */ @@ -692,7 +696,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) */ sprintf(lib_str, "HDF5 library version: %d.%d.%d", H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); - if (*substr){ + if(*substr) { HDstrcat(lib_str, "-"); HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1); } /* end if */ @@ -769,7 +773,7 @@ H5close(void) * whole library just to release it all right away. It is safe to call * this function for an uninitialized library. */ - FUNC_ENTER_API_NOINIT_NOFS(H5close) + FUNC_ENTER_API_NOINIT_NOERR_NOFS(H5close) H5TRACE0("e",""); H5_term_library(); diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c index a0035b3..7d0bb4c 100644 --- a/src/H5Abtree2.c +++ b/src/H5Abtree2.c @@ -90,7 +90,6 @@ static herr_t H5A_dense_btree2_corder_debug(FILE *stream, const H5F_t *f, hid_t /* v2 B-tree driver callbacks for 'name' index */ static herr_t H5A_dense_btree2_name_store(void *native, const void *udata); -static herr_t H5A_dense_btree2_name_retrieve(void *udata, const void *native); static herr_t H5A_dense_btree2_name_compare(const void *rec1, const void *rec2); static herr_t H5A_dense_btree2_name_encode(const H5F_t *f, uint8_t *raw, const void *native); @@ -108,7 +107,8 @@ static herr_t H5A_dense_fh_name_cmp(const void *obj, size_t obj_len, void *op_da /*********************/ /* v2 B-tree class for indexing 'name' field of attributes */ const H5B2_class_t H5A_BT2_NAME[1]={{ /* B-tree class information */ - H5B2_ATTR_DENSE_NAME_ID, /* Type of B-tree */ + H5B2_ATTR_DENSE_NAME_ID, /* Type of B-tree */ + "H5B2_ATTR_DENSE_NAME_ID", /* Name of B-tree class */ sizeof(H5A_dense_bt2_name_rec_t), /* Size of native record */ H5A_dense_btree2_name_store, /* Record storage callback */ H5A_dense_btree2_name_compare, /* Record comparison callback */ @@ -118,8 +118,9 @@ const H5B2_class_t H5A_BT2_NAME[1]={{ /* B-tree class information */ }}; /* v2 B-tree class for indexing 'creation order' field of attributes */ -const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */ - H5B2_ATTR_DENSE_CORDER_ID, /* Type of B-tree */ +const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */ + H5B2_ATTR_DENSE_CORDER_ID, /* Type of B-tree */ + "H5B2_ATTR_DENSE_CORDER_ID", /* Name of B-tree class */ sizeof(H5A_dense_bt2_corder_rec_t),/* Size of native record */ H5A_dense_btree2_corder_store, /* Record storage callback */ H5A_dense_btree2_corder_compare, /* Record comparison callback */ diff --git a/src/H5Adense.c b/src/H5Adense.c index bc5ddfb..c9da207 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -186,8 +186,10 @@ herr_t H5A_dense_create(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo) { H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */ - H5HF_t *fheap; /* Fractal heap handle */ - size_t bt2_rrec_size; /* v2 B-tree raw record size */ + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for names */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5A_dense_create, FAIL) @@ -234,20 +236,22 @@ HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len); } #endif /* NDEBUG */ - /* Close the fractal heap */ - if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") - /* Create the name index v2 B-tree */ - bt2_rrec_size = 4 + /* Name's hash value */ + HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam)); + bt2_cparam.cls = H5A_BT2_NAME; + bt2_cparam.node_size = (size_t)H5A_NAME_BT2_NODE_SIZE; + bt2_cparam.rrec_size = 4 + /* Name's hash value */ 4 + /* Creation order index */ 1 + /* Message flags */ H5O_FHEAP_ID_LEN; /* Fractal heap ID */ - if(H5B2_create(f, dxpl_id, H5A_BT2_NAME, - (size_t)H5A_NAME_BT2_NODE_SIZE, bt2_rrec_size, - H5A_NAME_BT2_SPLIT_PERC, H5A_NAME_BT2_MERGE_PERC, - &ainfo->name_bt2_addr) < 0) + bt2_cparam.split_percent = H5A_NAME_BT2_SPLIT_PERC; + bt2_cparam.merge_percent = H5A_NAME_BT2_MERGE_PERC; + if(NULL == (bt2_name = H5B2_create(f, dxpl_id, &bt2_cparam))) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2_name, &ainfo->name_bt2_addr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get v2 B-tree address for name index") #ifdef QAK HDfprintf(stderr, "%s: ainfo->name_bt2_addr = %a\n", FUNC, ainfo->name_bt2_addr); #endif /* QAK */ @@ -255,20 +259,34 @@ HDfprintf(stderr, "%s: ainfo->name_bt2_addr = %a\n", FUNC, ainfo->name_bt2_addr) /* Check if we should create a creation order index v2 B-tree */ if(ainfo->index_corder) { /* Create the creation order index v2 B-tree */ - bt2_rrec_size = 4 + /* Creation order index */ + HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam)); + bt2_cparam.cls = H5A_BT2_CORDER; + bt2_cparam.node_size = (size_t)H5A_CORDER_BT2_NODE_SIZE; + bt2_cparam.rrec_size = 4 + /* Creation order index */ 1 + /* Message flags */ H5O_FHEAP_ID_LEN; /* Fractal heap ID */ - if(H5B2_create(f, dxpl_id, H5A_BT2_CORDER, - (size_t)H5A_CORDER_BT2_NODE_SIZE, bt2_rrec_size, - H5A_CORDER_BT2_SPLIT_PERC, H5A_CORDER_BT2_MERGE_PERC, - &ainfo->corder_bt2_addr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index") + bt2_cparam.split_percent = H5A_CORDER_BT2_SPLIT_PERC; + bt2_cparam.merge_percent = H5A_CORDER_BT2_MERGE_PERC; + if(NULL == (bt2_corder = H5B2_create(f, dxpl_id, &bt2_cparam))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for creation order index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2_corder, &ainfo->corder_bt2_addr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get v2 B-tree address for creation order index") #ifdef QAK HDfprintf(stderr, "%s: ainfo->corder_bt2_addr = %a\n", FUNC, ainfo->corder_bt2_addr); #endif /* QAK */ } /* end if */ done: + /* Release resources */ + if(fheap && H5HF_close(fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_create() */ @@ -326,6 +344,7 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *na H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ htri_t attr_exists; /* Attribute exists in v2 B-tree */ H5A_t *ret_value = NULL; /* Return value */ @@ -363,6 +382,10 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *na } /* end if */ } /* end if */ + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open v2 B-tree for name index") + /* Create the "udata" information for v2 B-tree record find */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -376,7 +399,7 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char *na udata.found_op_data = &ret_value; /* Find & copy the attribute in the 'name' index */ - if((attr_exists = H5B2_find(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, NULL, NULL)) < 0) + if((attr_exists = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't search for attribute in name index") else if(attr_exists == FALSE) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute in name index") @@ -387,6 +410,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close v2 B-tree for name index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_open() */ @@ -411,6 +436,8 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr) H5A_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */ H5HF_t *fheap = NULL; /* Fractal heap handle for attributes */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */ uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */ unsigned mesg_flags = 0; /* Flags for storing message */ @@ -500,6 +527,10 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert attribute into fractal heap") } /* end else */ + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Create the callback information for v2 B-tree record insertion */ udata.common.f = f; udata.common.dxpl_id = dxpl_id; @@ -514,15 +545,19 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr) /* udata.id already set */ /* Insert attribute into 'name' tracking v2 B-tree */ - if(H5B2_insert(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata) < 0) + if(H5B2_insert(bt2_name, dxpl_id, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree") /* Check if we should create a creation order index v2 B-tree record */ if(ainfo->index_corder) { - /* Insert the record into the creation order index v2 B-tree */ + /* Open the creation order index v2 B-tree */ HDassert(H5F_addr_defined(ainfo->corder_bt2_addr)); - if(H5B2_insert(f, dxpl_id, H5A_BT2_CORDER, ainfo->corder_bt2_addr, &udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree") + if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, ainfo->corder_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + + /* Insert the record into the creation order index v2 B-tree */ + if(H5B2_insert(bt2_corder, dxpl_id, &udata) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree") } /* end if */ done: @@ -531,6 +566,10 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer") @@ -594,6 +633,7 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed) { H5A_dense_bt2_name_rec_t *record = (H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */ H5A_bt2_od_wrt_t *op_data = (H5A_bt2_od_wrt_t *)_op_data; /* "op data" from v2 B-tree modify */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */ uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */ herr_t ret_value = SUCCEED; /* Return value */ @@ -619,6 +659,10 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed) if(H5F_addr_defined(op_data->corder_bt2_addr)) { H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2_corder = H5B2_open(op_data->f, op_data->dxpl_id, op_data->corder_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + /* Create the "udata" information for v2 B-tree record modify */ udata.f = op_data->f; udata.dxpl_id = op_data->dxpl_id; @@ -632,7 +676,7 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed) udata.found_op_data = NULL; /* Modify record for creation order index */ - if(H5B2_modify(op_data->f, op_data->dxpl_id, H5A_BT2_CORDER, op_data->corder_bt2_addr, &udata, H5A_dense_write_bt2_cb2, &op_data->attr->sh_loc.u.heap_id) < 0) + if(H5B2_modify(bt2_corder, op_data->dxpl_id, &udata, H5A_dense_write_bt2_cb2, &op_data->attr->sh_loc.u.heap_id) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to modify record in v2 B-tree") } /* end if */ @@ -677,6 +721,8 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed) done: /* Release resources */ + if(bt2_corder && H5B2_close(bt2_corder, op_data->dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer") @@ -704,6 +750,7 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr) H5A_bt2_od_wrt_t op_data; /* "Op data" for v2 B-tree modify */ H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -742,6 +789,10 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr) if(NULL == (fheap = H5HF_open(f, dxpl_id, ainfo->fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Create the "udata" information for v2 B-tree record modify */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -763,7 +814,7 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr) op_data.corder_bt2_addr = ainfo->corder_bt2_addr; /* Modify attribute through 'name' tracking v2 B-tree */ - if(H5B2_modify(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, H5A_dense_write_bt2_cb, &op_data) < 0) + if(H5B2_modify(bt2_name, dxpl_id, &udata, H5A_dense_write_bt2_cb, &op_data) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to modify record in v2 B-tree") done: @@ -772,6 +823,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_write() */ @@ -841,6 +894,7 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ H5A_t *attr_copy = NULL; /* Copy of attribute to rename */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ @@ -881,6 +935,10 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * if(NULL == (fheap = H5HF_open(f, dxpl_id, ainfo->fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Create the "udata" information for v2 B-tree record modify */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -894,7 +952,7 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * udata.found_op_data = &attr_copy; /* Get copy of attribute through 'name' tracking v2 B-tree */ - if((attr_exists = H5B2_find(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, NULL, NULL)) < 0) + if((attr_exists = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index") else if(attr_exists == FALSE) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute in name index") @@ -962,6 +1020,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") if(attr_copy) H5O_msg_free(H5O_ATTR_ID, attr_copy); @@ -1087,7 +1147,7 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ - const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ herr_t ret_value; /* Return value */ @@ -1111,7 +1171,6 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf if(order == H5_ITER_NATIVE) { HDassert(H5F_addr_defined(ainfo->name_bt2_addr)); bt2_addr = ainfo->name_bt2_addr; - bt2_class = H5A_BT2_NAME; } /* end if */ else bt2_addr = HADDR_UNDEF; @@ -1124,7 +1183,6 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf * the links, a table will be built. */ bt2_addr = ainfo->corder_bt2_addr; - bt2_class = H5A_BT2_CORDER; } /* end else */ /* Check on iteration order */ @@ -1156,6 +1214,10 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf } /* end if */ } /* end if */ + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index") + /* Construct the user data for v2 B-tree iterator callback */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -1169,7 +1231,7 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, const H5O_ainfo_t *ainf /* Iterate over the records in the v2 B-tree's "native" order */ /* (by hash of name) */ - if((ret_value = H5B2_iterate(f, dxpl_id, bt2_class, bt2_addr, H5A_dense_iterate_bt2_cb, &udata)) < 0) + if((ret_value = H5B2_iterate(bt2, dxpl_id, H5A_dense_iterate_bt2_cb, &udata)) < 0) HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed"); /* Update the last attribute examined, if requested */ @@ -1193,6 +1255,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index") if(atable.attrs && H5A_attr_release_table(&atable) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table") @@ -1219,18 +1283,23 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_udata) const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; H5A_bt2_ud_rm_t *udata = (H5A_bt2_ud_rm_t *)_udata; /* User data for callback */ H5A_t *attr = *(H5A_t **)udata->common.found_op_data; /* Pointer to attribute to remove */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_remove_bt2_cb) /* Check for removing the link from the creation order index */ if(H5F_addr_defined(udata->corder_bt2_addr)) { + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2_corder = H5B2_open(udata->common.f, udata->common.dxpl_id, udata->corder_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + /* Set up the user data for the v2 B-tree 'record remove' callback */ udata->common.corder = attr->shared->crt_idx; /* Remove the record from the creation order index v2 B-tree */ - if(H5B2_remove(udata->common.f, udata->common.dxpl_id, H5A_BT2_CORDER, udata->corder_bt2_addr, udata, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove attribute from creation order index v2 B-tree") + if(H5B2_remove(bt2_corder, udata->common.dxpl_id, udata, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from creation order index v2 B-tree") } /* end if */ /* Check for removing shared attribute */ @@ -1251,6 +1320,10 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_udata) } /* end else */ done: + /* Release resources */ + if(bt2_corder && H5B2_close(bt2_corder, udata->common.dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_remove_bt2_cb() */ @@ -1274,6 +1347,7 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * H5A_bt2_ud_rm_t udata; /* User data for v2 B-tree record removal */ H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ H5A_t *attr_copy = NULL; /* Copy of attribute to remove */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1311,6 +1385,10 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * } /* end if */ } /* end if */ + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Set up the user data for the v2 B-tree 'record remove' callback */ udata.common.f = f; udata.common.dxpl_id = dxpl_id; @@ -1323,7 +1401,7 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * udata.corder_bt2_addr = ainfo->corder_bt2_addr; /* Remove the record from the name index v2 B-tree */ - if(H5B2_remove(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, H5A_dense_remove_bt2_cb, &udata) < 0) + if(H5B2_remove(bt2_name, dxpl_id, &udata, H5A_dense_remove_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from name index v2 B-tree") done: @@ -1332,6 +1410,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") if(attr_copy) H5O_msg_free_real(H5O_MSG_ATTR, attr_copy); @@ -1356,6 +1436,7 @@ static herr_t H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) { H5HF_t *fheap; /* Fractal heap handle */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; /* v2 B-tree record */ H5A_bt2_ud_rmbi_t *bt2_udata = (H5A_bt2_ud_rmbi_t *)_bt2_udata; /* User data for callback */ H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */ @@ -1398,22 +1479,15 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) /* Check for removing the link from the "other" index (creation order, when name used and vice versa) */ if(H5F_addr_defined(bt2_udata->other_bt2_addr)) { H5A_bt2_ud_common_t other_bt2_udata; /* Info for B-tree callbacks */ - const H5B2_class_t *other_bt2_class; /* Class of "other" v2 B-tree */ /* Determine the index being used */ if(bt2_udata->idx_type == H5_INDEX_NAME) { - /* Set the class of the "other" index */ - other_bt2_class = H5A_BT2_CORDER; - /* Set up the user data for the v2 B-tree 'record remove' callback */ other_bt2_udata.corder = fh_udata.attr->shared->crt_idx; } /* end if */ else { HDassert(bt2_udata->idx_type == H5_INDEX_CRT_ORDER); - /* Set the class of the "other" index */ - other_bt2_class = H5A_BT2_NAME; - /* Set up the user data for the v2 B-tree 'record remove' callback */ other_bt2_udata.f = bt2_udata->f; other_bt2_udata.dxpl_id = bt2_udata->dxpl_id; @@ -1425,10 +1499,14 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) other_bt2_udata.found_op_data = NULL; } /* end else */ + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(bt2_udata->f, bt2_udata->dxpl_id, bt2_udata->other_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index") + /* Set the common information for the v2 B-tree remove operation */ /* Remove the record from the "other" index v2 B-tree */ - if(H5B2_remove(bt2_udata->f, bt2_udata->dxpl_id, other_bt2_class, bt2_udata->other_bt2_addr, &other_bt2_udata, NULL, NULL) < 0) + if(H5B2_remove(bt2, bt2_udata->dxpl_id, &other_bt2_udata, NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove record from 'other' index v2 B-tree") } /* end if */ @@ -1459,6 +1537,8 @@ H5A_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) done: /* Release resources */ + if(bt2 && H5B2_close(bt2, bt2_udata->dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index") if(fh_udata.attr) H5O_msg_free(H5O_ATTR_ID, fh_udata.attr); @@ -1487,7 +1567,7 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ - const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ haddr_t bt2_addr; /* Address of v2 B-tree to use for operation */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1507,7 +1587,6 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, */ if(order == H5_ITER_NATIVE) { bt2_addr = ainfo->name_bt2_addr; - bt2_class = H5A_BT2_NAME; HDassert(H5F_addr_defined(bt2_addr)); } /* end if */ else @@ -1521,7 +1600,6 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, * the links, a table will be built. */ bt2_addr = ainfo->corder_bt2_addr; - bt2_class = H5A_BT2_CORDER; } /* end else */ /* If there is an index defined for the field, use it */ @@ -1553,6 +1631,10 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, } /* end if */ } /* end if */ + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index") + /* Set up the user data for the v2 B-tree 'record remove' callback */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -1562,7 +1644,7 @@ H5A_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, udata.other_bt2_addr = idx_type == H5_INDEX_NAME ? ainfo->corder_bt2_addr : ainfo->name_bt2_addr; /* Remove the record from the name index v2 B-tree */ - if(H5B2_remove_by_idx(f, dxpl_id, bt2_class, bt2_addr, order, n, H5A_dense_remove_by_idx_bt2_cb, &udata) < 0) + if(H5B2_remove_by_idx(bt2, dxpl_id, order, n, H5A_dense_remove_by_idx_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from v2 B-tree index") } /* end if */ else { @@ -1586,6 +1668,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index") if(atable.attrs && H5A_attr_release_table(&atable) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table") @@ -1613,6 +1697,7 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ htri_t ret_value = TRUE; /* Return value */ @@ -1649,6 +1734,10 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * } /* end if */ } /* end if */ + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Create the "udata" information for v2 B-tree record 'find' */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -1662,7 +1751,7 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, const char * udata.found_op_data = NULL; /* Find the attribute in the 'name' index */ - if((ret_value = H5B2_find(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &udata, NULL, NULL)) < 0) + if((ret_value = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index") done: @@ -1671,6 +1760,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_exists() */ @@ -1785,7 +1876,7 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo) udata.found_op_data = NULL; /* Delete name index v2 B-tree */ - if(H5B2_delete(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, H5A_dense_delete_bt2_cb, &udata) < 0) + if(H5B2_delete(f, dxpl_id, ainfo->name_bt2_addr, H5A_dense_delete_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index") ainfo->name_bt2_addr = HADDR_UNDEF; @@ -1797,8 +1888,8 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo) /* Check if we should delete the creation order index v2 B-tree */ if(H5F_addr_defined(ainfo->corder_bt2_addr)) { /* Delete the creation order index, without adjusting the ref. count on the attributes */ - if(H5B2_delete(f, dxpl_id, H5A_BT2_CORDER, ainfo->corder_bt2_addr, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index") + if(H5B2_delete(f, dxpl_id, ainfo->corder_bt2_addr, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index") ainfo->corder_bt2_addr = HADDR_UNDEF; } /* end if */ diff --git a/src/H5Aint.c b/src/H5Aint.c index 475239a..ab1d32c 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -314,6 +314,7 @@ herr_t H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5_index_t idx_type, H5_iter_order_t order, H5A_attr_table_t *atable) { + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ hsize_t nrec; /* # of records in v2 B-tree */ herr_t ret_value = SUCCEED; /* Return value */ @@ -326,9 +327,13 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, HDassert(H5F_addr_defined(ainfo->name_bt2_addr)); HDassert(atable); + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Retrieve # of records in "name" B-tree */ /* (should be same # of records in all indices) */ - if(H5B2_get_nrec(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &nrec) < 0) + if(H5B2_get_nrec(bt2_name, &nrec) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index") /* Set size of table */ @@ -371,6 +376,10 @@ H5A_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, atable->attrs = NULL; done: + /* Release resources */ + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_build_table() */ @@ -692,6 +701,7 @@ done: htri_t H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_ainfo_t *ainfo) { + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5A_get_ainfo, FAIL) @@ -713,9 +723,13 @@ H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_ainfo_t *ainfo) if(ainfo->nattrs == HSIZET_MAX) { /* Check if we are using "dense" attribute storage */ if(H5F_addr_defined(ainfo->fheap_addr)) { + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo->name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Retrieve # of records in "name" B-tree */ /* (should be same # of records in all indices) */ - if(H5B2_get_nrec(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &ainfo->nattrs) < 0) + if(H5B2_get_nrec(bt2_name, &ainfo->nattrs) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index") } /* end if */ else @@ -725,6 +739,10 @@ H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_ainfo_t *ainfo) } /* end if */ done: + /* Release resources */ + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_get_ainfo() */ @@ -1286,7 +1286,7 @@ H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, { herr_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5B_iterate, FAIL) + FUNC_ENTER_NOAPI_NOERR(H5B_iterate, -) /* * Check arguments. @@ -41,7 +41,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5B2pkg.h" /* v2 B-trees */ #include "H5Eprivate.h" /* Error handling */ -#include "H5MFprivate.h" /* File memory management */ + /****************/ /* Local Macros */ @@ -67,8 +67,35 @@ /* Package Variables */ /*********************/ -/* Declare a free list to manage the H5B2_t struct */ -H5FL_DEFINE(H5B2_t); +/* v2 B-tree client ID to class mapping */ + +/* Remember to add client ID to H5B2_subid_t in H5B2private.h when adding a new + * client class.. + */ +extern const H5B2_class_t H5B2_TEST[1]; +extern const H5B2_class_t H5HF_BT2_INDIR[1]; +extern const H5B2_class_t H5HF_BT2_FILT_INDIR[1]; +extern const H5B2_class_t H5HF_BT2_DIR[1]; +extern const H5B2_class_t H5HF_BT2_FILT_DIR[1]; +extern const H5B2_class_t H5G_BT2_NAME[1]; +extern const H5B2_class_t H5G_BT2_CORDER[1]; +extern const H5B2_class_t H5SM_INDEX[1]; +extern const H5B2_class_t H5A_BT2_NAME[1]; +extern const H5B2_class_t H5A_BT2_CORDER[1]; + +const H5B2_class_t *const H5B2_client_class_g[] = { + H5B2_TEST, /* 0 - H5B2_TEST_ID */ + H5HF_BT2_INDIR, /* 1 - H5B2_FHEAP_HUGE_INDIR_ID */ + H5HF_BT2_FILT_INDIR, /* 2 - H5B2_FHEAP_HUGE_FILT_INDIR_ID */ + H5HF_BT2_DIR, /* 3 - H5B2_FHEAP_HUGE_DIR_ID */ + H5HF_BT2_FILT_DIR, /* 4 - H5B2_FHEAP_HUGE_FILT_DIR_ID */ + H5G_BT2_NAME, /* 5 - H5B2_GRP_DENSE_NAME_ID */ + H5G_BT2_CORDER, /* 6 - H5B2_GRP_DENSE_CORDER_ID */ + H5SM_INDEX, /* 7 - H5B2_SOHM_INDEX_ID */ + H5A_BT2_NAME, /* 8 - H5B2_ATTR_DENSE_NAME_ID */ + H5A_BT2_CORDER, /* 9 - H5B2_ATTR_DENSE_CORDER_ID */ +}; + /*****************************/ /* Library Private Variables */ @@ -79,6 +106,10 @@ H5FL_DEFINE(H5B2_t); /* Local Variables */ /*******************/ +/* Declare a free list to manage the H5B2_t struct */ +H5FL_DEFINE_STATIC(H5B2_t); + + /*------------------------------------------------------------------------- * Function: H5B2_create @@ -94,63 +125,129 @@ H5FL_DEFINE(H5B2_t); * *------------------------------------------------------------------------- */ -herr_t -H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - size_t node_size, size_t rrec_size, - unsigned split_percent, unsigned merge_percent, haddr_t *addr_p) +H5B2_t * +H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam) { - H5B2_t *bt2 = NULL; /* The new B-tree header information */ - herr_t ret_value = SUCCEED; + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + haddr_t hdr_addr; /* B-tree header address */ + H5B2_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5B2_create, FAIL) + FUNC_ENTER_NOAPI(H5B2_create, NULL) /* * Check arguments. */ HDassert(f); - HDassert(type); - HDassert(node_size > 0); - HDassert(rrec_size > 0); - HDassert(merge_percent > 0 && merge_percent <= 100); - HDassert(split_percent > 0 && split_percent <= 100); - HDassert(merge_percent < (split_percent / 2)); - HDassert(addr_p); + HDassert(cparam); - /* - * Allocate file and memory data structures. - */ + /* H5B2 interface sanity check */ + HDcompile_assert(H5B2_NUM_BTREE_ID == NELMTS(H5B2_client_class_g)); + + /* Create shared v2 B-tree header */ + if(HADDR_UNDEF == (hdr_addr = H5B2_hdr_create(f, dxpl_id, cparam))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't create v2 B-tree header") + + /* Create v2 B-tree wrapper */ if(NULL == (bt2 = H5FL_MALLOC(H5B2_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree header") + HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for v2 B-tree info") - /* Assign internal information */ - HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t)); - bt2->root.addr = HADDR_UNDEF; - bt2->root.node_nrec = 0; - bt2->root.all_nrec = 0; + /* Look up the B-tree header */ + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, NULL, NULL, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header") + + /* Point v2 B-tree wrapper at header and bump it's ref count */ + bt2->hdr = hdr; + if(H5B2_hdr_incr(bt2->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment reference count on shared v2 B-tree header") - /* Initialize shared B-tree info */ - if(H5B2_shared_init(f, bt2, type, 0, node_size, rrec_size, split_percent, merge_percent) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared B-tree info") + /* Increment # of files using this v2 B-tree header */ + if(H5B2_hdr_fuse_incr(bt2->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment file reference count on shared v2 B-tree header") - /* Allocate space for the header on disk */ - if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)H5B2_HEADER_SIZE(f)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree header") + /* Set file pointer for this v2 B-tree open context */ + bt2->f = f; - /* Cache the new B-tree node */ - if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, *addr_p, bt2, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree header to cache") + /* Set the return value */ + ret_value = bt2; done: - if(ret_value < 0) { - if(bt2) - (void)H5B2_cache_hdr_dest(f, bt2); - } /* end if */ + 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(H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close v2 B-tree") FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_create() */ /*------------------------------------------------------------------------- + * Function: H5B2_open + * + * Purpose: Opens an existing v2 B-tree in the file. + * + * Return: Pointer to v2 B-tree wrapper on success + * NULL on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 15 2009 + * + *------------------------------------------------------------------------- + */ +H5B2_t * +H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr) +{ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_open) + + /* Check arguments. */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + + /* Look up the B-tree header */ + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header") + + /* Check for pending heap deletion */ + if(hdr->pending_delete) + HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, NULL, "can't open v2 B-tree pending deletion") + + /* Create v2 B-tree info */ + if(NULL == (bt2 = H5FL_MALLOC(H5B2_t))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for v2 B-tree info") + + /* Point v2 B-tree wrapper at header */ + bt2->hdr = hdr; + if(H5B2_hdr_incr(bt2->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment reference count on shared v2 B-tree header") + + /* Increment # of files using this v2 B-tree header */ + if(H5B2_hdr_fuse_incr(bt2->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment file reference count on shared v2 B-tree header") + + /* Set file pointer for this v2 B-tree open context */ + bt2->f = f; + + /* Set the return value */ + ret_value = bt2; + +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(H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close v2 B-tree") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5B2_open() */ + + +/*------------------------------------------------------------------------- * Function: H5B2_insert * * Purpose: Adds a new record to the B-tree. @@ -164,68 +261,87 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - void *udata) +H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - unsigned bt2_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for B-tree header */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - herr_t ret_value = SUCCEED; + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_insert, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); + HDassert(udata); - /* Look up the b-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Check if the root node is allocated yet */ - if(!H5F_addr_defined(bt2->root.addr)) { + if(!H5F_addr_defined(hdr->root.addr)) { /* Create root node as leaf node in B-tree */ - if(H5B2_create_leaf(f, dxpl_id, bt2->shared, &(bt2->root)) < 0) + if(H5B2_create_leaf(hdr, dxpl_id, &(hdr->root)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create root node") - - /* Mark B-tree header as dirty, since we updated the address of the root node */ - bt2_flags |= H5AC__DIRTIED_FLAG; } /* end if */ /* Check if we need to split the root node (equiv. to a 1->2 node split) */ - else if(bt2->root.node_nrec == shared->node_info[shared->depth].split_nrec) { + else if(hdr->root.node_nrec == hdr->node_info[hdr->depth].split_nrec) { /* Split root node */ - if(H5B2_split_root(f, dxpl_id, bt2, &bt2_flags) < 0) + if(H5B2_split_root(hdr, dxpl_id) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split root node") } /* end if */ /* Attempt to insert record into B-tree */ - if(shared->depth > 0) { - if(H5B2_insert_internal(f, dxpl_id, bt2->shared, shared->depth, &bt2_flags, &bt2->root, udata) < 0) + if(hdr->depth > 0) { + if(H5B2_insert_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, udata) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node") } /* end if */ else { - if(H5B2_insert_leaf(f, dxpl_id, bt2->shared, &bt2->root, udata) < 0) + if(H5B2_insert_leaf(hdr, dxpl_id, &hdr->root, udata) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node") } /* end else */ - /* Mark parent node as dirty */ - bt2_flags |= H5AC__DIRTIED_FLAG; + /* Mark B-tree header as dirty */ + if(H5B2_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty") done: - /* Release the B-tree header info */ - if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_insert() */ /*------------------------------------------------------------------------- + * Function: H5B2_get_addr + * + * Purpose: Get the address of a v2 B-tree + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 5 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_get_addr(const H5B2_t *bt2, haddr_t *addr_p) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5B2_get_addr) + + /* + * Check arguments. + */ + HDassert(bt2); + HDassert(addr_p); + + /* Retrieve the header address for this v2 B-tree */ + *addr_p = bt2->hdr->addr; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B2_get_addr() */ + + +/*------------------------------------------------------------------------- * Function: H5B2_iterate * * Purpose: Iterate over all the records in the B-tree, in "in-order" @@ -243,61 +359,30 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - H5B2_operator_t op, void *op_data) +H5B2_iterate(H5B2_t *bt2, hid_t dxpl_id, H5B2_operator_t op, void *op_data) { - H5B2_t *bt2=NULL; /* Pointer to the B-tree header */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */ - hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */ - H5B2_node_ptr_t root_ptr; /* Node pointer info for root node */ - unsigned depth; /* Current depth of the tree */ - herr_t ret_value = SUCCEED; + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5B2_iterate, FAIL) + FUNC_ENTER_NOAPI_NOERR(H5B2_iterate, -) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); HDassert(op); - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") - - /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */ - bt2_shared = bt2->shared; - H5RC_INC(bt2_shared); - incr_rc = TRUE; + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); - - /* Make copy of the root node pointer */ - root_ptr = bt2->root; - - /* Current depth of the tree */ - depth = shared->depth; - - /* Release header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - bt2 = NULL; + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Iterate through records */ - if(root_ptr.node_nrec > 0) { + if(hdr->root.node_nrec > 0) { /* Iterate through nodes */ - if((ret_value = H5B2_iterate_node(f, dxpl_id, bt2_shared, depth, &root_ptr, op, op_data)) < 0) + if((ret_value = H5B2_iterate_node(hdr, dxpl_id, hdr->depth, &hdr->root, op, op_data)) < 0) HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed"); } /* end if */ -done: - /* Check if we need to decrement the reference count for the B-tree's shared info */ - if(incr_rc) - H5RC_DEC(bt2_shared); - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_iterate() */ @@ -326,49 +411,32 @@ done: *------------------------------------------------------------------------- */ htri_t -H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - void *udata, H5B2_found_t op, void *op_data) +H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op, + void *op_data) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - H5RC_t *bt2_shared = NULL; /* Pointer to ref-counter for shared B-tree info */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - hbool_t incr_rc = FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */ unsigned depth; /* Current depth of the tree */ int cmp; /* Comparison value of records */ unsigned idx; /* Location of record which matches key */ - htri_t ret_value = TRUE /* Return value */; + htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_NOAPI(H5B2_find, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); - - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + HDassert(bt2); - /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */ - bt2_shared = bt2->shared; - H5RC_INC(bt2_shared); - incr_rc = TRUE; + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Make copy of the root node pointer to start search with */ - curr_node_ptr = bt2->root; + curr_node_ptr = hdr->root; /* Current depth of the tree */ - depth = shared->depth; - - /* Release header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - bt2 = NULL; + depth = hdr->depth; /* Check for empty tree */ if(curr_node_ptr.node_nrec == 0) @@ -381,11 +449,11 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */ /* Lock B-tree current node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Locate node pointer for child */ - cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); if(cmp > 0) idx++; @@ -394,7 +462,7 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, next_node_ptr=internal->node_ptrs[idx]; /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Set pointer to next node to load */ @@ -402,16 +470,16 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, } /* end if */ else { /* Make callback for current record */ - if(op && (op)(H5B2_INT_NREC(internal, shared, idx), op_data) < 0) { + if(op && (op)(H5B2_INT_NREC(internal, hdr, idx), op_data) < 0) { /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") } /* end if */ /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Indicate record found */ @@ -426,15 +494,15 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */ /* Lock B-tree leaf node */ - if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Locate record */ - cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx); if(cmp != 0) { /* Unlock leaf node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Record not found */ @@ -442,9 +510,9 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, } /* end if */ else { /* Make callback for current record */ - if(op && (op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) { + if(op && (op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) { /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") @@ -452,15 +520,11 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, } /* end else */ /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") } /* end block */ done: - /* Check if we need to decrement the reference count for the B-tree's shared info */ - if(incr_rc) - H5RC_DEC(bt2_shared); - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_find() */ @@ -484,48 +548,31 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - H5_iter_order_t order, hsize_t idx, H5B2_found_t op, void *op_data) +H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx, + H5B2_found_t op, void *op_data) { - H5B2_t *bt2=NULL; /* Pointer to the B-tree header */ - H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */ unsigned depth; /* Current depth of the tree */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_index, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); HDassert(op); - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") - - /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */ - bt2_shared = bt2->shared; - H5RC_INC(bt2_shared); - incr_rc = TRUE; + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Make copy of the root node pointer to start search with */ - curr_node_ptr = bt2->root; + curr_node_ptr = hdr->root; /* Current depth of the tree */ - depth = shared->depth; - - /* Release header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - bt2 = NULL; + depth = hdr->depth; /* Check for empty tree */ if(curr_node_ptr.node_nrec == 0) @@ -546,7 +593,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, unsigned u; /* Local index variable */ /* Lock B-tree current node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Search for record with correct index */ @@ -557,7 +604,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, next_node_ptr = internal->node_ptrs[u]; /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Set pointer to next node to load */ @@ -570,16 +617,16 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, /* Check if record is in this node */ if(internal->node_ptrs[u].all_nrec == idx) { /* Make callback for current record */ - if((op)(H5B2_INT_NREC(internal, shared, u), op_data) < 0) { + if((op)(H5B2_INT_NREC(internal, hdr, u), op_data) < 0) { /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") } /* end if */ /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_DONE(SUCCEED); @@ -599,7 +646,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, next_node_ptr = internal->node_ptrs[u]; /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Set pointer to next node to load */ @@ -618,31 +665,27 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */ /* Lock B-tree leaf node */ - if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Sanity check index */ HDassert(idx < leaf->nrec); /* Make callback for correct record */ - if((op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) { + if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) { /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") } /* end if */ /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") } /* end block */ done: - /* Check if we need to decrement the reference count for the B-tree's shared info */ - if(incr_rc) - H5RC_DEC(bt2_shared); - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_index() */ @@ -661,70 +704,61 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - void *udata, H5B2_remove_t op, void *op_data) +H5B2_remove(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_remove_t op, + void *op_data) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - unsigned bt2_flags = H5AC__NO_FLAGS_SET; - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - herr_t ret_value = SUCCEED; + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_remove, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); - /* Look up the b-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Check for empty B-tree */ - if(bt2->root.all_nrec == 0) + if(0 == hdr->root.all_nrec) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree") /* Attempt to remove record from B-tree */ - if(shared->depth > 0) { + if(hdr->depth > 0) { hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */ - if(H5B2_remove_internal(f, dxpl_id, bt2->shared, &depth_decreased, NULL, shared->depth, - &(bt2->cache_info), &bt2_flags, &bt2->root, udata, op, op_data) < 0) + if(H5B2_remove_internal(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth, + &(hdr->cache_info), NULL, &hdr->root, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node") /* Check for decreasing the depth of the B-tree */ if(depth_decreased) { /* Destroy free list factories for previous depth */ - if(shared->node_info[shared->depth].nat_rec_fac) - if(H5FL_fac_term(shared->node_info[shared->depth].nat_rec_fac) < 0) + if(hdr->node_info[hdr->depth].nat_rec_fac) + if(H5FL_fac_term(hdr->node_info[hdr->depth].nat_rec_fac) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory") - if(shared->node_info[shared->depth].node_ptr_fac) - if(H5FL_fac_term(shared->node_info[shared->depth].node_ptr_fac) < 0) + if(hdr->node_info[hdr->depth].node_ptr_fac) + if(H5FL_fac_term(hdr->node_info[hdr->depth].node_ptr_fac) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory") - shared->depth -= depth_decreased; + hdr->depth -= (uint16_t)depth_decreased; } /* end for */ } /* end if */ else { - if(H5B2_remove_leaf(f, dxpl_id, bt2->shared, &bt2->root, udata, op, op_data) < 0) + if(H5B2_remove_leaf(hdr, dxpl_id, &hdr->root, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node") } /* end else */ /* Decrement # of records in B-tree */ - bt2->root.all_nrec--; + hdr->root.all_nrec--; - /* Mark parent node as dirty */ - bt2_flags |= H5AC__DIRTIED_FLAG; + /* Mark B-tree header as dirty */ + if(H5B2_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty") done: - /* Release the B-tree header info */ - if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_remove() */ @@ -743,79 +777,69 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_remove_t op, - void *op_data) +H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, + hsize_t idx, H5B2_remove_t op, void *op_data) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - unsigned bt2_flags = H5AC__NO_FLAGS_SET; - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - herr_t ret_value = SUCCEED; + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_remove_by_idx, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); - /* Look up the b-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Check for empty B-tree */ - if(bt2->root.all_nrec == 0) + if(0 == hdr->root.all_nrec) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree") /* Check for index greater than the number of records in the tree */ - if(idx >= bt2->root.all_nrec) + if(idx >= hdr->root.all_nrec) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree doesn't have that many records") /* Check for reverse indexing and map requested index to appropriate forward index */ - if(order == H5_ITER_DEC) - idx = bt2->root.all_nrec - (idx + 1); + if(H5_ITER_DEC == order) + idx = hdr->root.all_nrec - (idx + 1); /* Attempt to remove record from B-tree */ - if(shared->depth > 0) { + if(hdr->depth > 0) { hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */ - if(H5B2_remove_internal_by_idx(f, dxpl_id, bt2->shared, &depth_decreased, NULL, shared->depth, - &(bt2->cache_info), &bt2_flags, &bt2->root, idx, op, op_data) < 0) + if(H5B2_remove_internal_by_idx(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth, + &(hdr->cache_info), NULL, &hdr->root, idx, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node") /* Check for decreasing the depth of the B-tree */ if(depth_decreased) { /* Destroy free list factories for previous depth */ - if(shared->node_info[shared->depth].nat_rec_fac) - if(H5FL_fac_term(shared->node_info[shared->depth].nat_rec_fac) < 0) + if(hdr->node_info[hdr->depth].nat_rec_fac) + if(H5FL_fac_term(hdr->node_info[hdr->depth].nat_rec_fac) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory") - if(shared->node_info[shared->depth].node_ptr_fac) - if(H5FL_fac_term(shared->node_info[shared->depth].node_ptr_fac) < 0) + if(hdr->node_info[hdr->depth].node_ptr_fac) + if(H5FL_fac_term(hdr->node_info[hdr->depth].node_ptr_fac) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory") - shared->depth -= depth_decreased; + hdr->depth -= (uint16_t)depth_decreased; } /* end for */ } /* end if */ else { - if(H5B2_remove_leaf_by_idx(f, dxpl_id, bt2->shared, &bt2->root, (unsigned)idx, op, op_data) < 0) + if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, &hdr->root, (unsigned)idx, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node") } /* end else */ /* Decrement # of records in B-tree */ - bt2->root.all_nrec--; + hdr->root.all_nrec--; - /* Mark parent node as dirty */ - bt2_flags |= H5AC__DIRTIED_FLAG; + /* Mark B-tree header as dirty */ + if(H5B2_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty") done: - /* Release the B-tree header info */ - if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_remove_by_idx() */ @@ -834,33 +858,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - hsize_t *nrec) +H5B2_get_nrec(const H5B2_t *bt2, hsize_t *nrec) { - H5B2_t *bt2=NULL; /* Pointer to the B-tree header */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5B2_get_nrec, FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_get_nrec) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); HDassert(nrec); - /* Look up the B-tree header */ - if (NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") - /* Get B-tree number of records */ - *nrec = bt2->root.all_nrec; - -done: - /* Release B-tree header node */ - if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") + *nrec = bt2->hdr->root.all_nrec; - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5B2_get_nrec() */ @@ -890,112 +899,44 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - H5B2_compare_t range, void *udata, H5B2_found_t op, void *op_data) +H5B2_neighbor(H5B2_t *bt2, hid_t dxpl_id, H5B2_compare_t range, void *udata, + H5B2_found_t op, void *op_data) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - herr_t ret_value = SUCCEED; + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_neighbor, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); HDassert(op); - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Check for empty tree */ - if(!H5F_addr_defined(bt2->root.addr)) + if(!H5F_addr_defined(hdr->root.addr)) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records") /* Attempt to find neighbor record in B-tree */ - if(shared->depth > 0) { - if(H5B2_neighbor_internal(f, dxpl_id, bt2->shared, shared->depth, &bt2->root, NULL, range, udata, op, op_data)<0) + if(hdr->depth > 0) { + if(H5B2_neighbor_internal(hdr, dxpl_id, hdr->depth, &hdr->root, NULL, range, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree internal node") } /* end if */ else { - if(H5B2_neighbor_leaf(f, dxpl_id, bt2->shared, &bt2->root, NULL, range, udata, op, op_data)<0) + if(H5B2_neighbor_leaf(hdr, dxpl_id, &hdr->root, NULL, range, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree leaf node") } /* end else */ done: - /* Release the B-tree header info */ - if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_neighbor() */ /*------------------------------------------------------------------------- - * Function: H5B2_delete - * - * Purpose: Delete an entire B-tree from a file. - * - * The 'OP' routine is called for each record and the - * OP_DATA pointer, to allow caller to perform an operation as - * each record is removed from the B-tree. - * - * If 'OP' is NULL, the records are just removed in the process - * of deleting the B-tree. - * - * Note: The records are _not_ guaranteed to be visited in order. - * - * Return: Non-negative on success, negative on failure. - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 9 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5B2_delete(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - H5B2_remove_t op, void *op_data) -{ - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5B2_delete, FAIL) - - /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); - - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") - - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); - - /* Delete all nodes in B-tree */ - if(H5F_addr_defined(bt2->root.addr)) - if(H5B2_delete_node(f, dxpl_id, bt2->shared, shared->depth, &bt2->root, op, op_data) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes") - -done: - /* Release the B-tree header info */ - if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to delete B-tree header info") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5B2_delete() */ - - -/*------------------------------------------------------------------------- * Function: H5B2_modify * * Purpose: Locate the specified information in a B-tree and modify it. @@ -1016,53 +957,36 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - void *udata, H5B2_modify_t op, void *op_data) +H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op, + void *op_data) { - H5B2_t *bt2=NULL; /* Pointer to the B-tree header */ - H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */ unsigned depth; /* Current depth of the tree */ int cmp; /* Comparison value of records */ unsigned idx; /* Location of record which matches key */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_modify, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); HDassert(op); - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") - - /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */ - bt2_shared = bt2->shared; - H5RC_INC(bt2_shared); - incr_rc = TRUE; + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Make copy of the root node pointer to start search with */ - curr_node_ptr = bt2->root; + curr_node_ptr = hdr->root; /* Current depth of the tree */ - depth = shared->depth; - - /* Release header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - bt2 = NULL; + depth = hdr->depth; /* Check for empty tree */ - if(curr_node_ptr.node_nrec==0) + if(0 == curr_node_ptr.node_nrec) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records") /* Walk down B-tree to find record or leaf node where record is located */ @@ -1073,20 +997,20 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */ /* Lock B-tree current node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_WRITE))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Locate node pointer for child */ - cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); if(cmp > 0) idx++; if(cmp != 0) { /* Get node pointer for next node to search */ - next_node_ptr=internal->node_ptrs[idx]; + next_node_ptr = internal->node_ptrs[idx]; /* Unlock current node */ - if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Set pointer to next node to load */ @@ -1096,12 +1020,12 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, hbool_t changed; /* Whether the 'modify' callback changed the record */ /* Make callback for current record */ - if ( (op)(H5B2_INT_NREC(internal,shared,idx), op_data, &changed) <0) { + if((op)(H5B2_INT_NREC(internal, hdr, idx), op_data, &changed) < 0) { /* Make certain that the callback didn't modify the value if it failed */ - HDassert(changed==FALSE); + HDassert(changed == FALSE); /* Unlock current node */ - if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree find operation") @@ -1111,7 +1035,7 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, internal_flags |= changed ? H5AC__DIRTIED_FLAG : 0; /* Unlock current node */ - if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, internal_flags) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, internal_flags) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_DONE(SUCCEED); @@ -1127,15 +1051,15 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, hbool_t changed = FALSE;/* Whether the 'modify' callback changed the record */ /* Lock B-tree leaf node */ - if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_WRITE))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Locate record */ - cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx); if(cmp != 0) { /* Unlock leaf node */ - if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Note: don't push error on stack, leave that to next higher level, @@ -1150,12 +1074,12 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, } /* end if */ else { /* Make callback for current record */ - if ((op)(H5B2_LEAF_NREC(leaf,shared,idx), op_data, &changed) <0) { + if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data, &changed) < 0) { /* Make certain that the callback didn't modify the value if it failed */ - HDassert(changed==FALSE); + HDassert(changed == FALSE); /* Unlock current node */ - if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree find operation") @@ -1166,94 +1090,155 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, leaf_flags |= (changed ? H5AC__DIRTIED_FLAG : 0); /* Unlock current node */ - if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, leaf_flags) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, leaf_flags) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") } done: - /* Check if we need to decrement the reference count for the B-tree's shared info */ - if(incr_rc) - H5RC_DEC(bt2_shared); - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_modify() */ /*------------------------------------------------------------------------- - * Function: H5B2_iterate_size + * Function: H5B2_close * - * Purpose: Iterate over all the records in the B-tree, collecting - * storage info. + * Purpose: Close a v2 B-tree * - * Return: non-negative on success, negative on error + * Return: Non-negative on success/Negative on failure * - * Programmer: Vailin Choi - * June 19 2007 + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 15 2009 * *------------------------------------------------------------------------- */ herr_t -H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, hsize_t *btree_size) +H5B2_close(H5B2_t *bt2, hid_t dxpl_id) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - H5RC_t *bt2_shared = NULL; /* Pointer to ref-counter for shared B-tree info */ - hbool_t incr_rc = FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */ - H5B2_node_ptr_t root_ptr; /* Node pointer info for root node */ - unsigned depth; /* Current depth of the tree */ - herr_t ret_value = SUCCEED; + haddr_t bt2_addr = HADDR_UNDEF; /* Address of v2 B-tree (for deletion) */ + hbool_t pending_delete = FALSE; /* Whether the v2 B-tree is pending deletion */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5B2_iterate_size, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5B2_close) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); - HDassert(btree_size); + HDassert(bt2); + HDassert(bt2->f); + + /* Decrement file reference & check if this is the last open v2 B-tree using the shared B-tree header */ + if(0 == H5B2_hdr_fuse_decr(bt2->hdr)) { + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; + + /* Check for pending B-tree deletion */ + if(bt2->hdr->pending_delete) { + /* Set local info, so B-tree deletion can occur after decrementing the + * header's ref count + */ + pending_delete = TRUE; + bt2_addr = bt2->hdr->addr; + } /* end if */ + } /* end if */ - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + /* Decrement the reference count on the B-tree header */ + /* (don't put in H5B2_hdr_fuse_decr() as the B-tree header may be evicted + * immediately -QAK) + */ + if(H5B2_hdr_decr(bt2->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement reference count on shared v2 B-tree header") - /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */ - bt2_shared = bt2->shared; - H5RC_INC(bt2_shared); - incr_rc = TRUE; + /* Check for pending v2 B-tree deletion */ + if(pending_delete) { + H5B2_hdr_t *hdr; /* Another pointer to v2 B-tree header */ - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Sanity check */ + HDassert(H5F_addr_defined(bt2_addr)); - /* Add size of header to B-tree metadata total */ - *btree_size += H5B2_HEADER_SIZE(f); + /* Lock the v2 B-tree header into memory */ + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(bt2->f, dxpl_id, H5AC_BT2_HDR, bt2_addr, NULL, NULL, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header") - /* Make copy of the root node pointer */ - root_ptr = bt2->root; + /* Set the shared v2 B-tree header's file context for this operation */ + hdr->f = bt2->f; - /* Current depth of the tree */ - depth = shared->depth; + /* Delete v2 B-tree, starting with header (unprotects header) */ + if(H5B2_hdr_delete(hdr, dxpl_id) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree") + } /* end if */ - /* Release header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - bt2 = NULL; + /* Release the v2 B-tree wrapper */ + bt2 = H5FL_FREE(H5B2_t, bt2); - /* Iterate through records */ - if(root_ptr.node_nrec > 0) { - /* Check for root node being a leaf */ - if(depth == 0) - *btree_size += shared->node_size; - else - /* Iterate through nodes */ - if(H5B2_iterate_size_node(f, dxpl_id, bt2_shared, depth, &root_ptr, btree_size) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node iteration failed"); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5B2_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_delete + * + * Purpose: Delete an entire B-tree from a file. + * + * The 'OP' routine is called for each record and the + * OP_DATA pointer, to allow caller to perform an operation as + * each record is removed from the B-tree. + * + * If 'OP' is NULL, the records are just removed in the process + * of deleting the B-tree. + * + * Note: The records are _not_ guaranteed to be visited in order. + * + * Return: Non-negative on success, negative on failure. + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 9 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5B2_remove_t op, + void *op_data) +{ + H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5B2_delete, FAIL) + + /* Check arguments. */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + + /* Lock the v2 B-tree header into memory */ +#ifdef QAK +HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr); +#endif /* QAK */ + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, NULL, NULL, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header") + + /* Remember the callback & context for later */ + hdr->remove_op = op; + hdr->remove_op_data = op_data; + + /* Check for files using shared v2 B-tree header */ + if(hdr->file_rc) + hdr->pending_delete = TRUE; + else { + /* Set the shared v2 B-tree header's file context for this operation */ + hdr->f = f; + + /* Delete v2 B-tree now, starting with header (unprotects header) */ + if(H5B2_hdr_delete(hdr, dxpl_id) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree") + hdr = NULL; } /* end if */ done: - /* Check if we need to decrement the reference count for the B-tree's shared info */ - if(incr_rc) - H5RC_DEC(bt2_shared); + /* Unprotect the header, if an error occurred */ + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release v2 B-tree header") + FUNC_LEAVE_NOAPI(ret_value) -} /* H5B2_iterate_size() */ +} /* H5B2_delete() */ diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 5ca7ed8..6737076 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -69,15 +69,15 @@ /********************/ /* Metadata cache callbacks */ -static H5B2_t *H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata); -static herr_t H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_t *b, unsigned UNUSED * flags_ptr); -static herr_t H5B2_cache_hdr_clear(H5F_t *f, H5B2_t *b, hbool_t destroy); -static herr_t H5B2_cache_hdr_size(const H5F_t *f, const H5B2_t *bt, size_t *size_ptr); -static H5B2_internal_t *H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_shared); +static H5B2_hdr_t *H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata); +static herr_t H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_hdr_t *hdr, unsigned UNUSED * flags_ptr); +static herr_t H5B2_cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy); +static herr_t H5B2_cache_hdr_size(const H5F_t *f, const H5B2_hdr_t *hdr, size_t *size_ptr); +static H5B2_internal_t *H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *udata2); static herr_t H5B2_cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_internal_t *i, unsigned UNUSED * flags_ptr); static herr_t H5B2_cache_internal_clear(H5F_t *f, H5B2_internal_t *i, hbool_t destroy); static herr_t H5B2_cache_internal_size(const H5F_t *f, const H5B2_internal_t *i, size_t *size_ptr); -static H5B2_leaf_t *H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_shared); +static H5B2_leaf_t *H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_hdr); static herr_t H5B2_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_leaf_t *l, unsigned UNUSED * flags_ptr); static herr_t H5B2_cache_leaf_clear(H5F_t *f, H5B2_leaf_t *l, hbool_t destroy); static herr_t H5B2_cache_leaf_size(const H5F_t *f, const H5B2_leaf_t *l, size_t *size_ptr); @@ -138,7 +138,6 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{ * Purpose: Loads a B-tree header from the disk. * * Return: Success: Pointer to a new B-tree. - * * Failure: NULL * * Programmer: Quincey Koziol @@ -147,52 +146,49 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{ * *------------------------------------------------------------------------- */ -static H5B2_t * -H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void UNUSED *udata) +static H5B2_hdr_t * +H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2) { - const H5B2_class_t *type = (const H5B2_class_t *) _type; /* Type of B-tree */ - unsigned depth; /* Depth of B-tree */ - size_t node_size, rrec_size; /* Size info for B-tree */ - uint8_t split_percent, merge_percent; /* Split & merge %s for B-tree */ - H5B2_t *bt2 = NULL; /* B-tree info */ + H5B2_create_t cparam; /* B-tree creation parameters */ + H5B2_subid_t id; /* ID of B-tree class, as found in file */ + uint16_t depth; /* Depth of B-tree */ + H5B2_hdr_t *hdr = NULL; /* B-tree header */ size_t size; /* Header size */ uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ H5WB_t *wb = NULL; /* Wrapped buffer for header data */ uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */ - uint8_t *hdr; /* Pointer to header buffer */ + uint8_t *buf; /* Pointer to header buffer */ uint8_t *p; /* Pointer into raw data buffer */ - H5B2_t *ret_value; /* Return value */ + H5B2_hdr_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5B2_cache_hdr_load, NULL) /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(type); - /* Allocate space for the B-tree data structure */ - if(NULL == (bt2 = H5FL_MALLOC(H5B2_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t)); + /* Allocate new B-tree header and reset cache info */ + if(NULL == (hdr = H5B2_hdr_alloc(f))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "allocation failed for B-tree header") /* Wrap the local buffer for serialized header info */ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf)))) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't wrap buffer") /* Compute the size of the serialized B-tree header on disk */ - size = H5B2_HEADER_SIZE(f); + size = H5B2_HEADER_SIZE(hdr); /* Get a pointer to a buffer that's large enough for header */ - if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size))) + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer") /* Read header from disk */ - if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0) + if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header") /* Get temporary pointer to serialized header */ - p = hdr; + p = buf; /* Magic number */ if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) @@ -203,54 +199,60 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo if(*p++ != H5B2_HDR_VERSION) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header version") - /* B-tree type */ - if(*p++ != (uint8_t)type->id) - HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type") + /* B-tree class */ + id = *p++; + if(id >= H5B2_NUM_BTREE_ID) + HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "invalid B-tree type") /* Node size (in bytes) */ - UINT32DECODE(p, node_size); + UINT32DECODE(p, cparam.node_size); /* Raw key size (in bytes) */ - UINT16DECODE(p, rrec_size); + UINT16DECODE(p, cparam.rrec_size); /* Depth of tree */ UINT16DECODE(p, depth); /* Split & merge %s */ - split_percent = *p++; - merge_percent = *p++; + cparam.split_percent = *p++; + cparam.merge_percent = *p++; /* Root node pointer */ - H5F_addr_decode(f, (const uint8_t **)&p, &(bt2->root.addr)); - UINT16DECODE(p, bt2->root.node_nrec); - H5F_DECODE_LENGTH(f, p, bt2->root.all_nrec); + H5F_addr_decode(f, (const uint8_t **)&p, &(hdr->root.addr)); + UINT16DECODE(p, hdr->root.node_nrec); + H5F_DECODE_LENGTH(f, p, hdr->root.all_nrec); /* Metadata checksum */ UINT32DECODE(p, stored_chksum); /* Sanity check */ - HDassert((size_t)(p - hdr) == size); + HDassert((size_t)(p - buf) == size); /* Compute checksum on entire header */ - computed_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0); + computed_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0); /* Verify checksum */ if(stored_chksum != computed_chksum) HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 B-tree header") - /* Initialize shared B-tree info */ - if(H5B2_shared_init(f, bt2, type, depth, node_size, rrec_size, split_percent, merge_percent) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create shared B-tree info") + /* Initialize B-tree header info */ + cparam.cls = H5B2_client_class_g[id]; + if(H5B2_hdr_init(f, hdr, &cparam, depth) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't initialize B-tree header info") + + /* Set the B-tree header's address */ + hdr->addr = addr; /* Set return value */ - ret_value = bt2; + ret_value = hdr; done: /* Release resources */ if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") - if(!ret_value && bt2) - (void)H5B2_cache_hdr_dest(f, bt2); + if(!ret_value && hdr) + if(H5B2_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, NULL, "can't release v2 B-tree header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -266,17 +268,12 @@ done: * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu * Feb 1 2005 - * Changes: JRM -- 8/21/06 - * Added the flags_ptr parameter. This parameter exists to - * allow the flush routine to report to the cache if the - * entry is resized or renamed as a result of the flush. - * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. * *------------------------------------------------------------------------- */ static herr_t H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, - H5B2_t *bt2, unsigned UNUSED * flags_ptr) + H5B2_hdr_t *hdr, unsigned UNUSED * flags_ptr) { H5WB_t *wb = NULL; /* Wrapped buffer for header data */ uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */ @@ -287,32 +284,30 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, /* check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(bt2); + HDassert(hdr); - if (bt2->cache_info.is_dirty) { - H5B2_shared_t *shared; /* Shared B-tree information */ - uint8_t *hdr; /* Pointer to header buffer */ + if(hdr->cache_info.is_dirty) { + uint8_t *buf; /* Pointer to header buffer */ uint8_t *p; /* Pointer into raw data buffer */ size_t size; /* Header size on disk */ uint32_t metadata_chksum; /* Computed metadata checksum value */ - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Set the B-tree header's file context for this operation */ + hdr->f = f; /* Wrap the local buffer for serialized header info */ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf)))) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't wrap buffer") /* Compute the size of the serialized B-tree header on disk */ - size = H5B2_HEADER_SIZE(f); + size = H5B2_HEADER_SIZE(hdr); /* Get a pointer to a buffer that's large enough for header */ - if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size))) + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "can't get actual buffer") /* Get temporary pointer to serialized header */ - p = hdr; + p = buf; /* Magic number */ HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); @@ -322,44 +317,44 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, *p++ = H5B2_HDR_VERSION; /* B-tree type */ - *p++ = shared->type->id; + *p++ = hdr->cls->id; /* Node size (in bytes) */ - UINT32ENCODE(p, shared->node_size); + UINT32ENCODE(p, hdr->node_size); /* Raw key size (in bytes) */ - UINT16ENCODE(p, shared->rrec_size); + UINT16ENCODE(p, hdr->rrec_size); /* Depth of tree */ - UINT16ENCODE(p, shared->depth); + UINT16ENCODE(p, hdr->depth); /* Split & merge %s */ - H5_CHECK_OVERFLOW(shared->split_percent, /* From: */ unsigned, /* To: */ uint8_t); - *p++ = (uint8_t)shared->split_percent; - H5_CHECK_OVERFLOW(shared->merge_percent, /* From: */ unsigned, /* To: */ uint8_t); - *p++ = (uint8_t)shared->merge_percent; + H5_CHECK_OVERFLOW(hdr->split_percent, /* From: */ unsigned, /* To: */ uint8_t); + *p++ = (uint8_t)hdr->split_percent; + H5_CHECK_OVERFLOW(hdr->merge_percent, /* From: */ unsigned, /* To: */ uint8_t); + *p++ = (uint8_t)hdr->merge_percent; /* Root node pointer */ - H5F_addr_encode(f, &p, bt2->root.addr); - UINT16ENCODE(p, bt2->root.node_nrec); - H5F_ENCODE_LENGTH(f, p, bt2->root.all_nrec); + H5F_addr_encode(f, &p, hdr->root.addr); + UINT16ENCODE(p, hdr->root.node_nrec); + H5F_ENCODE_LENGTH(f, p, hdr->root.all_nrec); /* Compute metadata checksum */ - metadata_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0); + metadata_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0); /* Metadata checksum */ UINT32ENCODE(p, metadata_chksum); /* Write the B-tree header. */ - HDassert((size_t)(p - hdr) == size); - if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0) + HDassert((size_t)(p - buf) == size); + if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk") - bt2->cache_info.is_dirty = FALSE; + hdr->cache_info.is_dirty = FALSE; } /* end if */ if(destroy) - if(H5B2_cache_hdr_dest(f, bt2) < 0) + if(H5B2_cache_hdr_dest(f, hdr) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header") done: @@ -385,7 +380,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_cache_hdr_dest(H5F_t *f, H5B2_t *bt2) +H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr) { herr_t ret_value = SUCCEED; /* Return value */ @@ -394,25 +389,23 @@ H5B2_cache_hdr_dest(H5F_t *f, H5B2_t *bt2) /* * Check arguments. */ - HDassert(bt2); + HDassert(hdr); + HDassert(hdr->rc == 0); /* If we're going to free the space on disk, the address must be valid */ - HDassert(!bt2->cache_info.free_file_space_on_destroy || H5F_addr_defined(bt2->cache_info.addr)); + HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr)); /* Check for freeing file space for B-tree header */ - if(bt2->cache_info.free_file_space_on_destroy) { + if(hdr->cache_info.free_file_space_on_destroy) { /* Release the space on disk */ /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, bt2->cache_info.addr, (hsize_t)H5B2_HEADER_SIZE(f)) < 0) + if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)H5B2_HEADER_SIZE(hdr)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header") } /* end if */ - /* Decrement reference count on shared B-tree info */ - if(bt2->shared) - H5RC_DEC(bt2->shared); - - /* Free B-tree header info */ - (void)H5FL_FREE(H5B2_t, bt2); + /* Release B-tree header info */ + if(H5B2_hdr_free(hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header info") done: FUNC_LEAVE_NOAPI(ret_value) @@ -433,7 +426,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_cache_hdr_clear(H5F_t *f, H5B2_t *bt2, hbool_t destroy) +H5B2_cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy) { herr_t ret_value = SUCCEED; /* Return value */ @@ -442,13 +435,13 @@ H5B2_cache_hdr_clear(H5F_t *f, H5B2_t *bt2, hbool_t destroy) /* * Check arguments. */ - HDassert(bt2); + HDassert(hdr); /* Reset the dirty flag. */ - bt2->cache_info.is_dirty = FALSE; + hdr->cache_info.is_dirty = FALSE; if(destroy) - if(H5B2_cache_hdr_dest(f, bt2) < 0) + if(H5B2_cache_hdr_dest(f, hdr) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header") done: @@ -472,7 +465,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_cache_hdr_size(const H5F_t *f, const H5B2_t UNUSED *bt2, size_t *size_ptr) +H5B2_cache_hdr_size(const H5F_t UNUSED *f, const H5B2_hdr_t *hdr, size_t *size_ptr) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_hdr_size) @@ -481,7 +474,7 @@ H5B2_cache_hdr_size(const H5F_t *f, const H5B2_t UNUSED *bt2, size_t *size_ptr) HDassert(size_ptr); /* Set size value */ - *size_ptr = H5B2_HEADER_SIZE(f); + *size_ptr = H5B2_HEADER_SIZE(hdr); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5B2_cache_hdr_size() */ @@ -493,7 +486,6 @@ H5B2_cache_hdr_size(const H5F_t *f, const H5B2_t UNUSED *bt2, size_t *size_ptr) * Purpose: Loads a B-tree internal node from the disk. * * Return: Success: Pointer to a new B-tree internal node. - * * Failure: NULL * * Programmer: Quincey Koziol @@ -506,7 +498,6 @@ static H5B2_internal_t * H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata, void UNUSED *udata2) { const H5B2_int_load_ud1_t *udata = (const H5B2_int_load_ud1_t *)_udata; /* Pointer to user data */ - H5B2_shared_t *shared; /* Shared B-tree information */ H5B2_internal_t *internal = NULL; /* Internal node read */ uint8_t *p; /* Pointer into raw data buffer */ uint8_t *native; /* Pointer to native record info */ @@ -528,19 +519,21 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemset(&internal->cache_info, 0, sizeof(H5AC_info_t)); - /* Share common B-tree information */ - internal->shared = udata->bt2_shared; - H5RC_INC(internal->shared); + /* Set the B-tree header's file context for this operation */ + udata->hdr->f = f; + + /* Increment ref. count on B-tree header */ + if(H5B2_hdr_incr(udata->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header") - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); + /* Share B-tree information */ + internal->hdr = udata->hdr; /* Read header from disk */ - if(H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page)<0) + if(H5F_block_read(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0) HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree internal node") - p = shared->page; + p = udata->hdr->page; /* Magic number */ if(HDmemcmp(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC)) @@ -552,15 +545,15 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree internal node version") /* B-tree type */ - if(*p++ != (uint8_t)shared->type->id) + if(*p++ != (uint8_t)udata->hdr->cls->id) HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type") /* Allocate space for the native keys in memory */ - if((internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[udata->depth].nat_rec_fac)) == NULL) + if(NULL == (internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(udata->hdr->node_info[udata->depth].nat_rec_fac))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree internal native keys") /* Allocate space for the node pointers in memory */ - if((internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(shared->node_info[udata->depth].node_ptr_fac)) == NULL) + if(NULL == (internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(udata->hdr->node_info[udata->depth].node_ptr_fac))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree internal node pointers") /* Set the number of records in the leaf & it's depth */ @@ -571,22 +564,22 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda native = internal->int_native; for(u = 0; u < internal->nrec; u++) { /* Decode record */ - if((shared->type->decode)(f, p, native) < 0) + if((udata->hdr->cls->decode)(f, p, native) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode B-tree record") /* Move to next record */ - p += shared->rrec_size; - native += shared->type->nrec_size; + p += udata->hdr->rrec_size; + native += udata->hdr->cls->nrec_size; } /* end for */ /* Deserialize node pointers for internal node */ int_node_ptr = internal->node_ptrs; - for(u = 0; u < internal->nrec + 1; u++) { + for(u = 0; u < (unsigned)(internal->nrec + 1); u++) { /* Decode node pointer */ H5F_addr_decode(f, (const uint8_t **)&p, &(int_node_ptr->addr)); - UINT64DECODE_VAR(p, int_node_ptr->node_nrec, shared->max_nrec_size); + UINT64DECODE_VAR(p, int_node_ptr->node_nrec, udata->hdr->max_nrec_size); if(udata->depth > 1) - UINT64DECODE_VAR(p, int_node_ptr->all_nrec, shared->node_info[udata->depth - 1].cum_max_nrec_size) + UINT64DECODE_VAR(p, int_node_ptr->all_nrec, udata->hdr->node_info[udata->depth - 1].cum_max_nrec_size) else int_node_ptr->all_nrec = int_node_ptr->node_nrec; @@ -595,13 +588,13 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda } /* end for */ /* Compute checksum on internal node */ - computed_chksum = H5_checksum_metadata(shared->page, (size_t)(p - shared->page), 0); + computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - udata->hdr->page), 0); /* Metadata checksum */ UINT32DECODE(p, stored_chksum); /* Sanity check parsing */ - HDassert((size_t)(p - shared->page) <= shared->node_size); + HDassert((size_t)(p - udata->hdr->page) <= udata->hdr->node_size); /* Verify checksum */ if(stored_chksum != computed_chksum) @@ -627,11 +620,6 @@ done: * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu * Feb 3 2005 - * Changes: JRM -- 8/21/06 - * Added the flags_ptr parameter. This parameter exists to - * allow the flush routine to report to the cache if the - * entry is resized or renamed as a result of the flush. - * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. * *------------------------------------------------------------------------- */ @@ -646,20 +634,19 @@ H5B2_cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(internal); + HDassert(internal->hdr); if(internal->cache_info.is_dirty) { - H5B2_shared_t *shared; /* Shared B-tree information */ uint8_t *p; /* Pointer into raw data buffer */ uint8_t *native; /* Pointer to native record info */ H5B2_node_ptr_t *int_node_ptr; /* Pointer to node pointer info */ uint32_t metadata_chksum; /* Computed metadata checksum value */ unsigned u; /* Local index variable */ - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); + /* Set the B-tree header's file context for this operation */ + internal->hdr->f = f; - p = shared->page; + p = internal->hdr->page; /* Magic number */ HDmemcpy(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC); @@ -669,43 +656,43 @@ H5B2_cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr *p++ = H5B2_INT_VERSION; /* B-tree type */ - *p++ = shared->type->id; - HDassert((size_t)(p - shared->page) == (H5B2_INT_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM)); + *p++ = internal->hdr->cls->id; + HDassert((size_t)(p - internal->hdr->page) == (H5B2_INT_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM)); /* Serialize records for internal node */ native = internal->int_native; for(u = 0; u < internal->nrec; u++) { /* Encode record */ - if((shared->type->encode)(f, p, native) < 0) + if((internal->hdr->cls->encode)(f, p, native) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record") /* Move to next record */ - p += shared->rrec_size; - native += shared->type->nrec_size; + p += internal->hdr->rrec_size; + native += internal->hdr->cls->nrec_size; } /* end for */ /* Serialize node pointers for internal node */ int_node_ptr = internal->node_ptrs; - for(u = 0; u < internal->nrec + 1; u++) { + for(u = 0; u < (unsigned)(internal->nrec + 1); u++) { /* Encode node pointer */ H5F_addr_encode(f, &p, int_node_ptr->addr); - UINT64ENCODE_VAR(p, int_node_ptr->node_nrec, shared->max_nrec_size); + UINT64ENCODE_VAR(p, int_node_ptr->node_nrec, internal->hdr->max_nrec_size); if(internal->depth > 1) - UINT64ENCODE_VAR(p, int_node_ptr->all_nrec, shared->node_info[internal->depth - 1].cum_max_nrec_size); + UINT64ENCODE_VAR(p, int_node_ptr->all_nrec, internal->hdr->node_info[internal->depth - 1].cum_max_nrec_size); /* Move to next node pointer */ int_node_ptr++; } /* end for */ /* Compute metadata checksum */ - metadata_chksum = H5_checksum_metadata(shared->page, (size_t)(p - shared->page), 0); + metadata_chksum = H5_checksum_metadata(internal->hdr->page, (size_t)(p - internal->hdr->page), 0); /* Metadata checksum */ UINT32ENCODE(p, metadata_chksum); /* Write the B-tree internal node */ - HDassert((size_t)(p - shared->page) <= shared->node_size); - if(H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page) < 0) + HDassert((size_t)(p - internal->hdr->page) <= internal->hdr->node_size); + if(H5F_block_write(f, H5FD_MEM_BTREE, addr, internal->hdr->node_size, dxpl_id, internal->hdr->page) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree internal node to disk") internal->cache_info.is_dirty = FALSE; @@ -736,7 +723,6 @@ done: herr_t H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) { - H5B2_shared_t *shared; /* Shared B-tree information */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_internal_dest) @@ -744,37 +730,38 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) /* * Check arguments. */ + HDassert(f); HDassert(internal); + HDassert(internal->hdr); /* If we're going to free the space on disk, the address must be valid */ HDassert(!internal->cache_info.free_file_space_on_destroy || H5F_addr_defined(internal->cache_info.addr)); - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Check for freeing file space for B-tree internal node */ if(internal->cache_info.free_file_space_on_destroy) { /* Release the space on disk */ /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, internal->cache_info.addr, (hsize_t)shared->node_size) < 0) + if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, internal->cache_info.addr, (hsize_t)internal->hdr->node_size) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree internal node") } /* end if */ + /* Set the B-tree header's file context for this operation */ + internal->hdr->f = f; + /* Release internal node's native key buffer */ if(internal->int_native) - H5FL_FAC_FREE(shared->node_info[internal->depth].nat_rec_fac, internal->int_native); + H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].nat_rec_fac, internal->int_native); /* Release internal node's node pointer buffer */ if(internal->node_ptrs) - H5FL_FAC_FREE(shared->node_info[internal->depth].node_ptr_fac, internal->node_ptrs); + H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].node_ptr_fac, internal->node_ptrs); - /* Decrement reference count on shared B-tree info */ - if(internal->shared) - H5RC_DEC(internal->shared); + /* Decrement ref. count on B-tree header */ + if(H5B2_hdr_decr(internal->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") /* Free B-tree internal node info */ - (void)H5FL_FREE(H5B2_internal_t, internal); + internal = H5FL_FREE(H5B2_internal_t, internal); done: FUNC_LEAVE_NOAPI(ret_value) @@ -836,20 +823,15 @@ done: static herr_t H5B2_cache_internal_size(const H5F_t UNUSED *f, const H5B2_internal_t *internal, size_t *size_ptr) { - H5B2_shared_t *shared; /* Shared B-tree information */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_internal_size) /* check arguments */ HDassert(internal); + HDassert(internal->hdr); HDassert(size_ptr); - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Set size value */ - *size_ptr = shared->node_size; + *size_ptr = internal->hdr->node_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* H5B2_cache_internal_size() */ @@ -861,7 +843,6 @@ H5B2_cache_internal_size(const H5F_t UNUSED *f, const H5B2_internal_t *internal, * Purpose: Loads a B-tree leaf from the disk. * * Return: Success: Pointer to a new B-tree leaf node. - * * Failure: NULL * * Programmer: Quincey Koziol @@ -871,11 +852,10 @@ H5B2_cache_internal_size(const H5F_t UNUSED *f, const H5B2_internal_t *internal, *------------------------------------------------------------------------- */ static H5B2_leaf_t * -H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_bt2_shared) +H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_hdr) { - const unsigned *nrec = (const unsigned *)_nrec; - H5RC_t *bt2_shared = (H5RC_t *)_bt2_shared; /* Shared B-tree information */ - H5B2_shared_t *shared; /* Shared B-tree information */ + const uint16_t *nrec = (const uint16_t *)_nrec; + H5B2_hdr_t *hdr = (H5B2_hdr_t *)_hdr; /* B-tree header information */ H5B2_leaf_t *leaf = NULL; /* Pointer to lead node loaded */ uint8_t *p; /* Pointer into raw data buffer */ uint8_t *native; /* Pointer to native keys */ @@ -889,25 +869,28 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(bt2_shared); + HDassert(hdr); + /* Allocate new leaf node and reset cache info */ if(NULL == (leaf = H5FL_MALLOC(H5B2_leaf_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemset(&leaf->cache_info, 0, sizeof(H5AC_info_t)); - /* Share common B-tree information */ - leaf->shared = bt2_shared; - H5RC_INC(leaf->shared); + /* Set the B-tree header's file context for this operation */ + hdr->f = f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared); - HDassert(shared); + /* Increment ref. count on B-tree header */ + if(H5B2_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header") + + /* Share B-tree header information */ + leaf->hdr = hdr; /* Read header from disk */ - if(H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page) < 0) + if(H5F_block_read(f, H5FD_MEM_BTREE, addr, hdr->node_size, dxpl_id, hdr->page) < 0) HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree leaf node") - p = shared->page; + p = hdr->page; /* Magic number */ if(HDmemcmp(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC)) @@ -919,12 +902,12 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree leaf node version") /* B-tree type */ - if(*p++ != (uint8_t)shared->type->id) + if(*p++ != (uint8_t)hdr->cls->id) HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type") /* Allocate space for the native keys in memory */ - if((leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[0].nat_rec_fac)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree leaf native keys") + if(NULL == (leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[0].nat_rec_fac))) + HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree leaf native keys") /* Set the number of records in the leaf */ leaf->nrec = *nrec; @@ -933,22 +916,22 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v native = leaf->leaf_native; for(u = 0; u < leaf->nrec; u++) { /* Decode record */ - if((shared->type->decode)(f, p, native) < 0) + if((hdr->cls->decode)(f, p, native) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, NULL, "unable to decode B-tree record") /* Move to next record */ - p += shared->rrec_size; - native += shared->type->nrec_size; + p += hdr->rrec_size; + native += hdr->cls->nrec_size; } /* end for */ /* Compute checksum on internal node */ - computed_chksum = H5_checksum_metadata(shared->page, (size_t)(p - shared->page), 0); + computed_chksum = H5_checksum_metadata(hdr->page, (size_t)(p - hdr->page), 0); /* Metadata checksum */ UINT32DECODE(p, stored_chksum); /* Sanity check parsing */ - HDassert((size_t)(p - shared->page) <= shared->node_size); + HDassert((size_t)(p - hdr->page) <= hdr->node_size); /* Verify checksum */ if(stored_chksum != computed_chksum) @@ -959,7 +942,7 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v done: if(!ret_value && leaf) - (void)H5B2_cache_leaf_dest(f,leaf); + (void)H5B2_cache_leaf_dest(f, leaf); FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_cache_leaf_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -975,13 +958,6 @@ done: * koziol@ncsa.uiuc.edu * Feb 2 2005 * - * Changes: JRM -- 8/21/06 - * Added the flags_ptr parameter. This parameter exists to - * allow the flush routine to report to the cache if the - * entry is resized or renamed as a result of the flush. - * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. - * - * *------------------------------------------------------------------------- */ static herr_t @@ -995,19 +971,18 @@ H5B2_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5 HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(leaf); + HDassert(leaf->hdr); if(leaf->cache_info.is_dirty) { - H5B2_shared_t *shared; /* Shared B-tree information */ uint8_t *p; /* Pointer into raw data buffer */ uint8_t *native; /* Pointer to native keys */ uint32_t metadata_chksum; /* Computed metadata checksum value */ unsigned u; /* Local index variable */ - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared); - HDassert(shared); + /* Set the B-tree header's file context for this operation */ + leaf->hdr->f = f; - p = shared->page; + p = leaf->hdr->page; /* magic number */ HDmemcpy(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC); @@ -1017,30 +992,30 @@ H5B2_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5 *p++ = H5B2_LEAF_VERSION; /* b-tree type */ - *p++ = shared->type->id; - HDassert((size_t)(p - shared->page) == (H5B2_LEAF_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM)); + *p++ = leaf->hdr->cls->id; + HDassert((size_t)(p - leaf->hdr->page) == (H5B2_LEAF_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM)); /* Serialize records for leaf node */ native = leaf->leaf_native; for(u = 0; u < leaf->nrec; u++) { /* Encode record */ - if((shared->type->encode)(f, p, native) < 0) + if((leaf->hdr->cls->encode)(f, p, native) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record") /* Move to next record */ - p += shared->rrec_size; - native += shared->type->nrec_size; + p += leaf->hdr->rrec_size; + native += leaf->hdr->cls->nrec_size; } /* end for */ /* Compute metadata checksum */ - metadata_chksum = H5_checksum_metadata(shared->page, (size_t)(p - shared->page), 0); + metadata_chksum = H5_checksum_metadata(leaf->hdr->page, (size_t)(p - leaf->hdr->page), 0); /* Metadata checksum */ UINT32ENCODE(p, metadata_chksum); /* Write the B-tree leaf node */ - HDassert((size_t)(p - shared->page) <= shared->node_size); - if(H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->node_size, dxpl_id, shared->page) < 0) + HDassert((size_t)(p - leaf->hdr->page) <= leaf->hdr->node_size); + if(H5F_block_write(f, H5FD_MEM_BTREE, addr, leaf->hdr->node_size, dxpl_id, leaf->hdr->page) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree leaf node to disk") leaf->cache_info.is_dirty = FALSE; @@ -1071,7 +1046,6 @@ done: herr_t H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) { - H5B2_shared_t *shared; /* Shared B-tree information */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_leaf_dest) @@ -1079,33 +1053,34 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) /* * Check arguments. */ + HDassert(f); HDassert(leaf); + HDassert(leaf->hdr); /* If we're going to free the space on disk, the address must be valid */ HDassert(!leaf->cache_info.free_file_space_on_destroy || H5F_addr_defined(leaf->cache_info.addr)); - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared); - HDassert(shared); - /* Check for freeing file space for B-tree leaf node */ if(leaf->cache_info.free_file_space_on_destroy) { /* Release the space on disk */ /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, leaf->cache_info.addr, (hsize_t)shared->node_size) < 0) + if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, leaf->cache_info.addr, (hsize_t)leaf->hdr->node_size) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree leaf node") } /* end if */ + /* Set the B-tree header's file context for this operation */ + leaf->hdr->f = f; + /* Release leaf's native key buffer */ if(leaf->leaf_native) - H5FL_FAC_FREE(shared->node_info[0].nat_rec_fac, leaf->leaf_native); + H5FL_FAC_FREE(leaf->hdr->node_info[0].nat_rec_fac, leaf->leaf_native); - /* Decrement reference count on shared B-tree info */ - if(leaf->shared) - H5RC_DEC(leaf->shared); + /* Decrement ref. count on B-tree header */ + if(H5B2_hdr_decr(leaf->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") /* Free B-tree leaf node info */ - (void)H5FL_FREE(H5B2_leaf_t, leaf); + leaf = H5FL_FREE(H5B2_leaf_t, leaf); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1167,20 +1142,15 @@ done: static herr_t H5B2_cache_leaf_size(const H5F_t UNUSED *f, const H5B2_leaf_t *leaf, size_t *size_ptr) { - H5B2_shared_t *shared; /* Shared B-tree information */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_leaf_size) /* check arguments */ HDassert(leaf); + HDassert(leaf->hdr); HDassert(size_ptr); - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared); - HDassert(shared); - /* Set size value */ - *size_ptr = shared->node_size; + *size_ptr = leaf->hdr->node_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* H5B2_cache_leaf_size() */ diff --git a/src/H5B2dbg.c b/src/H5B2dbg.c index 836486e..17a64cd 100644 --- a/src/H5B2dbg.c +++ b/src/H5B2dbg.c @@ -90,10 +90,9 @@ herr_t H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, const H5B2_class_t *type) { - H5B2_t *bt2 = NULL; /* B-tree header info */ - H5B2_shared_t *shared; /* Shared B-tree information */ + H5B2_hdr_t *hdr = NULL; /* B-tree header info */ unsigned u; /* Local index variable */ - char temp_str[128]; /* Temporary string, for formatting */ + char temp_str[128]; /* Temporary string, for formatting */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_hdr_debug, FAIL) @@ -111,12 +110,11 @@ H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, /* * Load the B-tree header. */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree header") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Set file pointer for this B-tree operation */ + hdr->f = f; /* Print opening message */ HDfprintf(stream, "%*sv2 B-tree Header...\n", indent, ""); @@ -124,59 +122,51 @@ H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, /* * Print the values. */ - HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Tree type ID:", - (shared->type->id == H5B2_TEST_ID ? "H5B2_TEST_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_INDIR_ID ? "H5B2_FHEAP_HUGE_INDIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" : - (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" : - (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" : - (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" : - (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" : - (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" : - "Unknown!"))))))))))); + HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth, + "Tree type ID:", hdr->cls->name, (unsigned)hdr->cls->id); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of node:", - shared->node_size); + hdr->node_size); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of raw (disk) record:", - shared->rrec_size); + hdr->rrec_size); HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Dirty flag:", - bt2->cache_info.is_dirty ? "True" : "False"); + hdr->cache_info.is_dirty ? "True" : "False"); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Depth:", - shared->depth); + hdr->depth); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Number of records in tree:", - bt2->root.all_nrec); + hdr->root.all_nrec); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Number of records in root node:", - bt2->root.node_nrec); + hdr->root.node_nrec); HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of root node:", - bt2->root.addr); + hdr->root.addr); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Split percent:", - shared->split_percent); + hdr->split_percent); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Merge percent:", - shared->merge_percent); + hdr->merge_percent); /* Print relevant node info */ HDfprintf(stream, "%*sNode Info: (max_nrec/split_nrec/merge_nrec)\n", indent, ""); - for(u = 0; u < (shared->depth + 1); u++) { + for(u = 0; u < (unsigned)(hdr->depth + 1); u++) { sprintf(temp_str, "Depth %u:", u); HDfprintf(stream, "%*s%-*s (%u/%u/%u)\n", indent + 3, "", MAX(0, fwidth - 3), temp_str, - shared->node_info[u].max_nrec, shared->node_info[u].split_nrec, shared->node_info[u].merge_nrec); + hdr->node_info[u].max_nrec, hdr->node_info[u].split_nrec, hdr->node_info[u].merge_nrec); } /* end for */ done: - if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header") + if(hdr) { + hdr->f = NULL; + if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header") + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_hdr_debug() */ @@ -199,11 +189,10 @@ herr_t H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec, unsigned depth) { - H5B2_t *bt2 = NULL; - H5B2_internal_t *internal = NULL; - H5B2_shared_t *shared; /* Shared B-tree information */ - unsigned u; /* Local index variable */ - char temp_str[128]; /* Temporary string, for formatting */ + H5B2_hdr_t *hdr = NULL; /* B-tree header */ + H5B2_internal_t *internal = NULL; /* B-tree internal node */ + unsigned u; /* Local index variable */ + char temp_str[128]; /* Temporary string, for formatting */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_int_debug, FAIL) @@ -223,24 +212,18 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, /* * Load the B-tree header. */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, NULL, H5AC_READ))) + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, NULL, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree header") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Set file pointer for this B-tree operation */ + hdr->f = f; /* * Load the B-tree internal node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2->shared, addr, nrec, depth, H5AC_READ))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, addr, nrec, depth, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree internal node") - /* Release the B-tree header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header") - bt2 = NULL; - /* Print opening message */ if(internal->depth == 1) HDfprintf(stream, "%*sv2 B-tree Internal 'Leaf' Node...\n", indent, ""); @@ -250,25 +233,14 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, /* * Print the values. */ - HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Tree type ID:", - (shared->type->id == H5B2_TEST_ID ? "H5B2_TEST_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_INDIR_ID ? "H5B2_FHEAP_HUGE_INDIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" : - (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" : - (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" : - (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" : - (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" : - (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" : - "Unknown!"))))))))))); + HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth, + "Tree type ID:", hdr->cls->name, (unsigned)hdr->cls->id); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of node:", - shared->node_size); + hdr->node_size); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of raw (disk) record:", - shared->rrec_size); + hdr->rrec_size); HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Dirty flag:", internal->cache_info.is_dirty ? "True" : "False"); @@ -290,9 +262,9 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, sprintf(temp_str, "Record #%u:", u); HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), temp_str); - HDassert(H5B2_INT_NREC(internal, shared, u)); + HDassert(H5B2_INT_NREC(internal, hdr, u)); (void)(type->debug)(stream, f, dxpl_id, indent + 6, MAX (0, fwidth-6), - H5B2_INT_NREC(internal,shared,u), NULL); + H5B2_INT_NREC(internal, hdr, u), NULL); } /* end for */ /* Print final node pointer */ @@ -304,6 +276,11 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, internal->node_ptrs[u].addr); done: + if(hdr) { + hdr->f = NULL; + if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header") + } /* end if */ if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, addr, internal, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree internal node") @@ -328,12 +305,11 @@ herr_t H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec) { - H5B2_t *bt2 = NULL; - H5B2_leaf_t *leaf = NULL; - H5B2_shared_t *shared; /* Shared B-tree information */ - unsigned u; /* Local index variable */ - char temp_str[128]; /* Temporary string, for formatting */ - herr_t ret_value=SUCCEED; /* Return value */ + H5B2_hdr_t *hdr = NULL; /* B-tree header */ + H5B2_leaf_t *leaf = NULL; /* B-tree leaf node */ + unsigned u; /* Local index variable */ + char temp_str[128]; /* Temporary string, for formatting */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_leaf_debug, FAIL) @@ -352,49 +328,32 @@ H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, /* * Load the B-tree header. */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, NULL, H5AC_READ))) + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, type, NULL, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree header") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Set file pointer for this B-tree operation */ + hdr->f = f; /* * Load the B-tree leaf node */ - if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, addr, &nrec, bt2->shared, H5AC_READ))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, addr, &nrec, hdr, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree leaf node") - /* Release the B-tree header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header") - bt2 = NULL; - /* Print opening message */ HDfprintf(stream, "%*sv2 B-tree Leaf Node...\n", indent, ""); /* * Print the values. */ - HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Tree type ID:", - (shared->type->id == H5B2_TEST_ID ? "H5B2_TEST_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_INDIR_ID ? "H5B2_FHEAP_HUGE_INDIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_FILT_INDIR_ID ? "H5B2_FHEAP_HUGE_FILT_INDIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_DIR_ID ? "H5B2_FHEAP_HUGE_DIR_ID" : - (shared->type->id == H5B2_FHEAP_HUGE_FILT_DIR_ID ? "H5B2_FHEAP_HUGE_FILT_DIR_ID" : - (shared->type->id == H5B2_GRP_DENSE_NAME_ID ? "H5B2_GRP_DENSE_NAME_ID" : - (shared->type->id == H5B2_GRP_DENSE_CORDER_ID ? "H5B2_GRP_DENSE_CORDER_ID" : - (shared->type->id == H5B2_SOHM_INDEX_ID ? "H5B2_SOHM_INDEX_ID" : - (shared->type->id == H5B2_ATTR_DENSE_NAME_ID ? "H5B2_ATTR_DENSE_NAME_ID" : - (shared->type->id == H5B2_ATTR_DENSE_CORDER_ID ? "H5B2_ATTR_DENSE_CORDER_ID" : - "Unknown!"))))))))))); + HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth, + "Tree type ID:", hdr->cls->name, (unsigned)hdr->cls->id); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of node:", - shared->node_size); + hdr->node_size); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of raw (disk) record:", - shared->rrec_size); + hdr->rrec_size); HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Dirty flag:", leaf->cache_info.is_dirty ? "True" : "False"); @@ -408,12 +367,17 @@ H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, sprintf(temp_str, "Record #%u:", u); HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), temp_str); - HDassert(H5B2_LEAF_NREC(leaf, shared, u)); - (void)(type->debug)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6), - H5B2_LEAF_NREC(leaf,shared,u), NULL); + HDassert(H5B2_LEAF_NREC(leaf, hdr, u)); + (void)(type->debug)(stream, f, dxpl_id, indent + 6, MAX (0, fwidth-6), + H5B2_LEAF_NREC(leaf, hdr, u), NULL); } /* end for */ done: + if(hdr) { + hdr->f = NULL; + if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header") + } /* end if */ if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, addr, leaf, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree leaf node") diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c new file mode 100644 index 0000000..ec46729 --- /dev/null +++ b/src/H5B2hdr.c @@ -0,0 +1,597 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5B2int.c + * Feb 27 2006 + * Quincey Koziol <koziol@ncsa.uiuc.edu> + * + * Purpose: Internal routines for managing v2 B-trees. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5B2_PACKAGE /*suppress error about including H5B2pkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5B2pkg.h" /* v2 B-trees */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5Vprivate.h" /* Vectors and arrays */ + +/****************/ +/* Local Macros */ +/****************/ + +/* Number of records that fit into leaf node */ +#define H5B2_NUM_LEAF_REC(n, r) \ + (((n) - H5B2_LEAF_PREFIX_SIZE) / (r)) + +/* Uncomment this macro to enable extra sanity checking */ +/* #define H5B2_DEBUG */ + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5B2_hdr_t struct */ +H5FL_DEFINE_STATIC(H5B2_hdr_t); + +/* Declare a free list to manage B-tree node pages to/from disk */ +H5FL_BLK_DEFINE_STATIC(node_page); + +/* Declare a free list to manage the 'size_t' sequence information */ +H5FL_SEQ_DEFINE_STATIC(size_t); + +/* Declare a free list to manage the 'H5B2_node_info_t' sequence information */ +H5FL_SEQ_DEFINE(H5B2_node_info_t); + + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_init + * + * Purpose: Allocate & initialize B-tree header info + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 2 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_hdr_init(H5F_t *f, H5B2_hdr_t *hdr, const H5B2_create_t *cparam, + uint16_t depth) +{ + size_t sz_max_nrec; /* Temporary variable for range checking */ + unsigned u_max_nrec_size; /* Temporary variable for range checking */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_init) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(hdr); + HDassert(cparam); + HDassert(cparam->cls); + HDassert(cparam->node_size > 0); + HDassert(cparam->rrec_size > 0); + HDassert(cparam->merge_percent > 0 && cparam->merge_percent <= 100); + HDassert(cparam->split_percent > 0 && cparam->split_percent <= 100); + HDassert(cparam->merge_percent < (cparam->split_percent / 2)); + + /* Initialize basic information */ + hdr->f = f; + hdr->rc = 0; + hdr->pending_delete = FALSE; + + /* Assign dynamic information */ + hdr->depth = depth; + + /* Assign user's information */ + hdr->split_percent = cparam->split_percent; + hdr->merge_percent = cparam->merge_percent; + hdr->node_size = cparam->node_size; + hdr->rrec_size = cparam->rrec_size; + + /* Assign common type information */ + hdr->cls = cparam->cls; + + /* Allocate "page" for node I/O */ + if(NULL == (hdr->page = H5FL_BLK_MALLOC(node_page, hdr->node_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") +#ifdef H5_CLEAR_MEMORY +HDmemset(hdr->page, 0, hdr->node_size); +#endif /* H5_CLEAR_MEMORY */ + + /* Allocate array of node info structs */ + if(NULL == (hdr->node_info = H5FL_SEQ_MALLOC(H5B2_node_info_t, (size_t)(hdr->depth + 1)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Initialize leaf node info */ + sz_max_nrec = H5B2_NUM_LEAF_REC(hdr->node_size, hdr->rrec_size); + H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[0].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned) + hdr->node_info[0].split_nrec = (hdr->node_info[0].max_nrec * hdr->split_percent) / 100; + hdr->node_info[0].merge_nrec = (hdr->node_info[0].max_nrec * hdr->merge_percent) / 100; + hdr->node_info[0].cum_max_nrec = hdr->node_info[0].max_nrec; + hdr->node_info[0].cum_max_nrec_size = 0; + if(NULL == (hdr->node_info[0].nat_rec_fac = H5FL_fac_init(hdr->cls->nrec_size * hdr->node_info[0].max_nrec))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory") + hdr->node_info[0].node_ptr_fac = NULL; + + /* Allocate array of pointers to internal node native keys */ + /* (uses leaf # of records because its the largest) */ + if(NULL == (hdr->nat_off = H5FL_SEQ_MALLOC(size_t, (size_t)hdr->node_info[0].max_nrec))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Initialize offsets in native key block */ + /* (uses leaf # of records because its the largest) */ + for(u = 0; u < hdr->node_info[0].max_nrec; u++) + hdr->nat_off[u] = hdr->cls->nrec_size * u; + + /* Compute size to store # of records in each node */ + /* (uses leaf # of records because its the largest) */ + u_max_nrec_size = H5V_limit_enc_size((uint64_t)hdr->node_info[0].max_nrec); + H5_ASSIGN_OVERFLOW(/* To: */ hdr->max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t) + HDassert(hdr->max_nrec_size <= H5B2_SIZEOF_RECORDS_PER_NODE); + + /* Initialize internal node info */ + if(depth > 0) { + for(u = 1; u < (unsigned)(depth + 1); u++) { + sz_max_nrec = H5B2_NUM_INT_REC(hdr, u); + H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[u].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned) + HDassert(hdr->node_info[u].max_nrec <= hdr->node_info[u - 1].max_nrec); + + hdr->node_info[u].split_nrec = (hdr->node_info[u].max_nrec * hdr->split_percent) / 100; + hdr->node_info[u].merge_nrec = (hdr->node_info[u].max_nrec * hdr->merge_percent) / 100; + + hdr->node_info[u].cum_max_nrec = ((hdr->node_info[u].max_nrec + 1) * + hdr->node_info[u - 1].cum_max_nrec) + hdr->node_info[u].max_nrec; + u_max_nrec_size = H5V_limit_enc_size((uint64_t)hdr->node_info[u].cum_max_nrec); + H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[u].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t) + + if(NULL == (hdr->node_info[u].nat_rec_fac = H5FL_fac_init(hdr->cls->nrec_size * hdr->node_info[u].max_nrec))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory") + if(NULL == (hdr->node_info[u].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (hdr->node_info[u].max_nrec + 1)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create internal 'branch' node node pointer block factory") + } /* end for */ + } /* end if */ + +done: + if(ret_value < 0) + if(H5B2_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free shared v2 B-tree info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_hdr_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_alloc + * + * Purpose: Allocate B-tree header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 27 2009 + * + *------------------------------------------------------------------------- + */ +H5B2_hdr_t * +H5B2_hdr_alloc(H5F_t *f) +{ + H5B2_hdr_t *hdr = NULL; /* v2 B-tree header */ + H5B2_hdr_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_alloc) + + /* + * Check arguments. + */ + HDassert(f); + + /* Allocate space for the shared information */ + if(NULL == (hdr = H5FL_CALLOC(H5B2_hdr_t))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for B-tree header") + + /* Assign non-zero information */ + hdr->f = f; + hdr->sizeof_addr = H5F_SIZEOF_ADDR(f); + hdr->sizeof_size = H5F_SIZEOF_SIZE(f); + hdr->root.addr = HADDR_UNDEF; + + /* Set return value */ + 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() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_hdr_create + * + * Purpose: Create new fractal heap header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 21 2006 + * + *------------------------------------------------------------------------- + */ +haddr_t +H5B2_hdr_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam) +{ + H5B2_hdr_t *hdr = NULL; /* The new v2 B-tree header information */ + haddr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_create) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(cparam); + + /* Allocate v2 B-tree header */ + if(NULL == (hdr = H5B2_hdr_alloc(f))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed for B-tree header") + + /* Initialize shared B-tree info */ + if(H5B2_hdr_init(f, hdr, cparam, (uint16_t)0) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, HADDR_UNDEF, "can't create shared B-tree info") + + /* Allocate space for the header on disk */ + if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)H5B2_HEADER_SIZE(hdr)))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, HADDR_UNDEF, "file allocation failed for B-tree header") + + /* Cache the new B-tree node */ + if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, HADDR_UNDEF, "can't add B-tree header to cache") + + /* Set address of v2 B-tree header to return */ + ret_value = hdr->addr; + +done: + if(!H5F_addr_defined(ret_value) && hdr) + if(H5B2_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, HADDR_UNDEF, "unable to release v2 B-tree header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_hdr_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_incr + * + * Purpose: Increment reference count on B-tree header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 13 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_hdr_incr(H5B2_hdr_t *hdr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_incr) + + /* Sanity checks */ + HDassert(hdr); + HDassert(hdr->f); + + /* Mark header as un-evictable when a B-tree node is depending on it */ + if(hdr->rc == 0) + if(H5AC_pin_protected_entry(hdr->f, hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTPIN, FAIL, "unable to pin v2 B-tree header") + + /* Increment reference count on B-tree header */ + hdr->rc++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_incr_hdr() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_decr + * + * Purpose: Decrement reference count on B-tree header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 13 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_hdr_decr(H5B2_hdr_t *hdr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_decr) + + /* Sanity check */ + HDassert(hdr); + HDassert(hdr->f); + HDassert(hdr->rc > 0); + + /* Decrement reference count on B-tree header */ + hdr->rc--; + + /* Mark header as evictable again when no nodes depend on it */ + if(hdr->rc == 0) + if(H5AC_unpin_entry(hdr->f, hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin v2 B-tree header") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_hdr_decr() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_fuse_incr + * + * Purpose: Increment file reference count on shared v2 B-tree header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 27 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_hdr_fuse_incr(H5B2_hdr_t *hdr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_fuse_incr) + + /* Sanity check */ + HDassert(hdr); + + /* Increment file reference count on shared header */ + hdr->file_rc++; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B2_hdr_fuse_incr() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_fuse_decr + * + * Purpose: Decrement file reference count on shared v2 B-tree header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 27 2009 + * + *------------------------------------------------------------------------- + */ +size_t +H5B2_hdr_fuse_decr(H5B2_hdr_t *hdr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_fuse_decr) + + /* Sanity check */ + HDassert(hdr); + HDassert(hdr->file_rc); + + /* Decrement file reference count on shared header */ + hdr->file_rc--; + + FUNC_LEAVE_NOAPI(hdr->file_rc) +} /* end H5B2_hdr_fuse_decr() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_dirty + * + * Purpose: Mark B-tree header as dirty + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 13 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_hdr_dirty(H5B2_hdr_t *hdr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_dirty) + + /* Sanity check */ + HDassert(hdr); + HDassert(hdr->f); + + /* Mark B-tree header as dirty in cache */ + if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark v2 B-tree header as dirty") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_hdr_dirty() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_free + * + * Purpose: Free B-tree header info + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 2 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_hdr_free(H5B2_hdr_t *hdr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_free) + + /* Sanity check */ + HDassert(hdr); + + /* Free the B-tree node buffer */ + if(hdr->page) + (void)H5FL_BLK_FREE(node_page, hdr->page); + + /* Free the array of offsets into the native key block */ + if(hdr->nat_off) + hdr->nat_off = H5FL_SEQ_FREE(size_t, hdr->nat_off); + + /* Release the node info */ + if(hdr->node_info) { + unsigned u; /* Local index variable */ + + /* Destroy free list factories */ + for(u = 0; u < (unsigned)(hdr->depth + 1); u++) { + if(hdr->node_info[u].nat_rec_fac) + if(H5FL_fac_term(hdr->node_info[u].nat_rec_fac) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory") + if(hdr->node_info[u].node_ptr_fac) + if(H5FL_fac_term(hdr->node_info[u].node_ptr_fac) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory") + } /* end for */ + + /* Free the array of node info structs */ + hdr->node_info = H5FL_SEQ_FREE(H5B2_node_info_t, hdr->node_info); + } /* end if */ + + /* Free B-tree header info */ + (void)H5FL_FREE(H5B2_hdr_t, hdr); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_hdr_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_hdr_delete + * + * Purpose: Delete a v2 B-tree, starting with the header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 15 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id) +{ + unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting v2 B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5B2_hdr_delete, FAIL) + + /* Sanity check */ + HDassert(hdr); + +#ifndef NDEBUG +{ + unsigned hdr_status = 0; /* v2 B-tree header's status in the metadata cache */ + + /* Check the v2 B-tree header's status in the metadata cache */ + if(H5AC_get_entry_status(hdr->f, hdr->addr, &hdr_status) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to check metadata cache status for v2 B-tree header") + + /* Sanity checks on v2 B-tree header */ + HDassert(hdr_status & H5AC_ES__IN_CACHE); + HDassert(hdr_status & H5AC_ES__IS_PROTECTED); +} /* end block */ +#endif /* NDEBUG */ + + /* Delete all nodes in B-tree */ + if(H5F_addr_defined(hdr->root.addr)) + if(H5B2_delete_node(hdr, dxpl_id, hdr->depth, &hdr->root, hdr->remove_op, hdr->remove_op_data) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes") + + /* Indicate that the heap header should be deleted & file space freed */ + cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; + +done: + /* Unprotect the header with appropriate flags */ + if(hdr && 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) +} /* end H5B2_hdr_delete() */ + diff --git a/src/H5B2int.c b/src/H5B2int.c index 550a5b6..f7312a5 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -43,15 +43,6 @@ /* Local Macros */ /****************/ -/* Number of records that fit into internal node */ -/* (accounts for extra node pointer by counting it in with the prefix bytes) */ -#define H5B2_NUM_INT_REC(f, s, d) \ - (((s)->node_size - (H5B2_INT_PREFIX_SIZE + H5B2_INT_POINTER_SIZE(f, s, d))) / ((s)->rrec_size + H5B2_INT_POINTER_SIZE(f, s, d))) - -/* Number of records that fit into leaf node */ -#define H5B2_NUM_LEAF_REC(n, r) \ - (((n) - H5B2_LEAF_PREFIX_SIZE) / (r)) - /* Uncomment this macro to enable extra sanity checking */ /* #define H5B2_DEBUG */ @@ -70,30 +61,29 @@ /********************/ /* Helper functions */ -static herr_t H5B2_shared_free(void *_shared); -static herr_t H5B2_create_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +static herr_t H5B2_create_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *node_ptr, unsigned depth); -static herr_t H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, +static herr_t H5B2_split1(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx); -static herr_t H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, +static herr_t H5B2_redistribute2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_internal_t *internal, unsigned idx); -static herr_t H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, +static herr_t H5B2_redistribute3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx); -static herr_t H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth, +static herr_t H5B2_merge2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx); -static herr_t H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, +static herr_t H5B2_merge3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx); -static herr_t H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth, +static herr_t H5B2_swap_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx, void *swap_loc); #ifdef H5B2_DEBUG -static herr_t H5B2_assert_leaf(H5B2_shared_t *shared, H5B2_leaf_t *leaf); -static herr_t H5B2_assert_leaf2(H5B2_shared_t *shared, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2); -static herr_t H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal); -static herr_t H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal, H5B2_internal_t *internal2); +static herr_t H5B2_assert_leaf(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf); +static herr_t H5B2_assert_leaf2(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2); +static herr_t H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal); +static herr_t H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal, H5B2_internal_t *internal2); #endif /* H5B2_DEBUG */ /*********************/ @@ -116,194 +106,12 @@ H5FL_DEFINE(H5B2_leaf_t); /* Local Variables */ /*******************/ -/* Declare a free list to manage B-tree node pages to/from disk */ -H5FL_BLK_DEFINE_STATIC(node_page); - -/* Declare a free list to manage the 'size_t' sequence information */ -H5FL_SEQ_DEFINE_STATIC(size_t); - /* Declare a free list to manage the 'H5B2_node_info_t' sequence information */ -H5FL_SEQ_DEFINE_STATIC(H5B2_node_info_t); - -/* Declare a free list to manage the H5B2_shared_t struct */ -H5FL_DEFINE_STATIC(H5B2_shared_t); +H5FL_SEQ_EXTERN(H5B2_node_info_t); /*------------------------------------------------------------------------- - * Function: H5B2_shared_init - * - * Purpose: Allocate & initialize shared B-tree info - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 2 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5B2_shared_init (H5F_t *f, H5B2_t *bt2, const H5B2_class_t *type, - unsigned depth, size_t node_size, size_t rrec_size, - unsigned split_percent, unsigned merge_percent) -{ - H5B2_shared_t *shared = NULL; /* Shared B-tree information */ - size_t sz_max_nrec; /* Temporary variable for range checking */ - unsigned u_max_nrec_size; /* Temporary variable for range checking */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5B2_shared_init) - - /* Allocate space for the shared information */ - if(NULL == (shared = H5FL_CALLOC(H5B2_shared_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree shared information") - - /* Assign dynamic information */ - shared->depth = depth; - - /* Assign user's information */ - shared->split_percent = split_percent; - shared->merge_percent = merge_percent; - shared->node_size = node_size; - shared->rrec_size = rrec_size; - - /* Assign common type information */ - shared->type = type; - - /* Allocate "page" for node I/O */ - if((shared->page = H5FL_BLK_MALLOC(node_page, shared->node_size)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") -#ifdef H5_CLEAR_MEMORY -HDmemset(shared->page, 0, shared->node_size); -#endif /* H5_CLEAR_MEMORY */ - - /* Allocate array of node info structs */ - if((shared->node_info = H5FL_SEQ_MALLOC(H5B2_node_info_t, (size_t)(shared->depth + 1))) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Initialize leaf node info */ - sz_max_nrec = H5B2_NUM_LEAF_REC(shared->node_size, shared->rrec_size); - H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[0].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned) - shared->node_info[0].split_nrec = (shared->node_info[0].max_nrec * shared->split_percent) / 100; - shared->node_info[0].merge_nrec = (shared->node_info[0].max_nrec * shared->merge_percent) / 100; - shared->node_info[0].cum_max_nrec = shared->node_info[0].max_nrec; - shared->node_info[0].cum_max_nrec_size = 0; - if((shared->node_info[0].nat_rec_fac = H5FL_fac_init(type->nrec_size * shared->node_info[0].max_nrec)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory") - shared->node_info[0].node_ptr_fac = NULL; - - /* Allocate array of pointers to internal node native keys */ - /* (uses leaf # of records because its the largest) */ - if((shared->nat_off = H5FL_SEQ_MALLOC(size_t, (size_t)shared->node_info[0].max_nrec)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Initialize offsets in native key block */ - /* (uses leaf # of records because its the largest) */ - for(u = 0; u < shared->node_info[0].max_nrec; u++) - shared->nat_off[u] = type->nrec_size * u; - - /* Compute size to store # of records in each node */ - /* (uses leaf # of records because its the largest) */ - u_max_nrec_size = H5V_limit_enc_size((uint64_t)shared->node_info[0].max_nrec); - H5_ASSIGN_OVERFLOW(/* To: */ shared->max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t) - HDassert(shared->max_nrec_size <= H5B2_SIZEOF_RECORDS_PER_NODE); - - /* Initialize internal node info */ - if(depth > 0) { - for(u = 1; u < (depth + 1); u++) { - sz_max_nrec = H5B2_NUM_INT_REC(f, shared, u); - H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[u].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned) - HDassert(shared->node_info[u].max_nrec <= shared->node_info[u - 1].max_nrec); - - shared->node_info[u].split_nrec = (shared->node_info[u].max_nrec * shared->split_percent) / 100; - shared->node_info[u].merge_nrec = (shared->node_info[u].max_nrec * shared->merge_percent) / 100; - - shared->node_info[u].cum_max_nrec = ((shared->node_info[u].max_nrec + 1) * - shared->node_info[u - 1].cum_max_nrec) + shared->node_info[u].max_nrec; - u_max_nrec_size = H5V_limit_enc_size((uint64_t)shared->node_info[u].cum_max_nrec); - H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[u].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t) - - if((shared->node_info[u].nat_rec_fac = H5FL_fac_init(shared->type->nrec_size * shared->node_info[u].max_nrec)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory") - if((shared->node_info[u].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (shared->node_info[u].max_nrec + 1))) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create internal 'branch' node node pointer block factory") - } /* end for */ - } /* end if */ - - /* Make shared B-tree info reference counted */ - if(NULL == (bt2->shared = H5RC_create(shared, H5B2_shared_free))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info") - -done: - if(ret_value < 0) - if(shared) - H5B2_shared_free(shared); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5B2_shared_init() */ - - -/*------------------------------------------------------------------------- - * Function: H5B2_shared_free - * - * Purpose: Free shared B-tree info - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 2 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5B2_shared_free(void *_shared) -{ - H5B2_shared_t *shared = (H5B2_shared_t *)_shared; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT(H5B2_shared_free) - - /* Sanity check */ - HDassert(shared); - - /* Free the B-tree node buffer */ - if(shared->page) - (void)H5FL_BLK_FREE(node_page, shared->page); - - /* Free the array of offsets into the native key block */ - if(shared->nat_off) - shared->nat_off = H5FL_SEQ_FREE(size_t, shared->nat_off); - - /* Release the node info */ - if(shared->node_info) { - unsigned u; /* Local index variable */ - - /* Destroy free list factories */ - for(u = 0; u < (shared->depth + 1); u++) { - if(shared->node_info[u].nat_rec_fac) - if(H5FL_fac_term(shared->node_info[u].nat_rec_fac) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory") - if(shared->node_info[u].node_ptr_fac) - if(H5FL_fac_term(shared->node_info[u].node_ptr_fac) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory") - } /* end for */ - - /* Free the array of node info structs */ - shared->node_info = H5FL_SEQ_FREE(H5B2_node_info_t, shared->node_info); - } /* end if */ - - /* Free the shared B-tree info itself */ - shared = H5FL_FREE(H5B2_shared_t, shared); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5B2_shared_free() */ - - -/*------------------------------------------------------------------------- * Function: H5B2_locate_record * * Purpose: Performs a binary search to locate a record in a sorted @@ -345,7 +153,7 @@ H5B2_locate_record(const H5B2_class_t *type, unsigned nrec, size_t *rec_off, *idx = my_idx; - FUNC_LEAVE_NOAPI(cmp); + FUNC_LEAVE_NOAPI(cmp) } /* end H5B2_locate_record */ @@ -364,35 +172,30 @@ H5B2_locate_record(const H5B2_class_t *type, unsigned nrec, size_t *rec_off, *------------------------------------------------------------------------- */ static herr_t -H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, +H5B2_split1(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx) { const H5AC_class_t *child_class; /* Pointer to child node's class info */ haddr_t left_addr, right_addr; /* Addresses of left & right child nodes */ void *left_child, *right_child; /* Pointers to child nodes */ - unsigned *left_nrec, *right_nrec; /* Pointers to child # of records */ + uint16_t *left_nrec, *right_nrec; /* Pointers to child # of records */ uint8_t *left_native, *right_native;/* Pointers to childs' native records */ - H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */ - H5B2_shared_t *shared; /* B-tree's shared info */ - unsigned mid_record; /* Index of "middle" record in current node */ - unsigned old_node_nrec; /* Number of records in internal node split */ + H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */ + uint16_t mid_record; /* Index of "middle" record in current node */ + uint16_t old_node_nrec; /* Number of records in internal node split */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_split1) - HDassert(f); - HDassert(parent_cache_info_flags_ptr); + /* Check arguments. */ + HDassert(hdr); HDassert(internal); HDassert(internal_flags_ptr); - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Slide records in parent node up one space, to make room for promoted record */ if(idx < internal->nrec) { - HDmemmove(H5B2_INT_NREC(internal, shared, idx + 1), H5B2_INT_NREC(internal, shared, idx), shared->type->nrec_size * (internal->nrec - idx)); + HDmemmove(H5B2_INT_NREC(internal, hdr, idx + 1), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size * (internal->nrec - idx)); HDmemmove(&(internal->node_ptrs[idx + 2]), &(internal->node_ptrs[idx + 1]), sizeof(H5B2_node_ptr_t) * (internal->nrec - idx)); } /* end if */ @@ -402,7 +205,7 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ /* Create new internal node */ internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec = 0; - if(H5B2_create_internal(f, dxpl_id, internal->shared, &(internal->node_ptrs[idx + 1]), (depth - 1)) < 0) + if(H5B2_create_internal(hdr, dxpl_id, &(internal->node_ptrs[idx + 1]), (depth - 1)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new internal node") /* Setup information for unlocking child nodes */ @@ -411,9 +214,9 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ right_addr = internal->node_ptrs[idx + 1].addr; /* Protect both leafs */ - if(NULL == (left_int = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (left_int = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - if(NULL == (right_int = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (right_int = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* More setup for child nodes */ @@ -431,7 +234,7 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ /* Create new leaf node */ internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec = 0; - if(H5B2_create_leaf(f, dxpl_id, internal->shared, &(internal->node_ptrs[idx + 1])) < 0) + if(H5B2_create_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx + 1])) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new leaf node") /* Setup information for unlocking child nodes */ @@ -440,9 +243,9 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ right_addr = internal->node_ptrs[idx + 1].addr; /* Protect both leafs */ - if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* More setup for child nodes */ @@ -461,21 +264,21 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ mid_record = old_node_nrec / 2; /* Copy "upper half" of records to new child */ - HDmemcpy(H5B2_NAT_NREC(right_native, shared, 0), - H5B2_NAT_NREC(left_native, shared, mid_record + 1), - shared->type->nrec_size * (old_node_nrec - (mid_record + 1))); + HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), + H5B2_NAT_NREC(left_native, hdr, mid_record + (unsigned)1), + hdr->cls->nrec_size * (old_node_nrec - (mid_record + (unsigned)1))); /* Copy "upper half" of node pointers, if the node is an internal node */ if(depth > 1) - HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[mid_record + 1]), + HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[mid_record + (unsigned)1]), sizeof(H5B2_node_ptr_t) * (old_node_nrec - mid_record)); /* Copy "middle" record to internal node */ - HDmemcpy(H5B2_INT_NREC(internal, shared, idx), H5B2_NAT_NREC(left_native, shared, mid_record), shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, mid_record), hdr->cls->nrec_size); /* Update record counts in child nodes */ internal->node_ptrs[idx].node_nrec = *left_nrec = mid_record; - internal->node_ptrs[idx + 1].node_nrec = *right_nrec = old_node_nrec - (mid_record + 1); + internal->node_ptrs[idx + 1].node_nrec = *right_nrec = old_node_nrec - (mid_record + (unsigned)1); /* Determine total number of records in new child nodes */ if(depth > 1) { @@ -485,11 +288,11 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ /* Compute total of all records in each child node */ new_left_all_nrec = internal->node_ptrs[idx].node_nrec; - for(u = 0; u < (*left_nrec + 1); u++) + for(u = 0; u < (*left_nrec + (unsigned)1); u++) new_left_all_nrec += left_node_ptrs[u].all_nrec; new_right_all_nrec = internal->node_ptrs[idx + 1].node_nrec; - for(u = 0; u < (*right_nrec + 1); u++) + for(u = 0; u < (*right_nrec + (unsigned)1); u++) new_right_all_nrec += right_node_ptrs[u].all_nrec; internal->node_ptrs[idx].all_nrec = new_left_all_nrec; @@ -509,29 +312,30 @@ H5B2_split1(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ /* Update grandparent info */ curr_node_ptr->node_nrec++; - /* Mark grandparent as dirty */ - *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG; + /* Mark grandparent as dirty, if given */ + if(parent_cache_info_flags_ptr) + *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG; #ifdef H5B2_DEBUG - H5B2_assert_internal((hsize_t)0,shared,internal); + H5B2_assert_internal((hsize_t)0, hdr, internal); if(depth > 1) { - H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, shared, left_child, right_child); - H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, shared, right_child, left_child); + H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, left_child, right_child); + H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, left_child); } /* end if */ else { - H5B2_assert_leaf2(shared, left_child, right_child); - H5B2_assert_leaf(shared, right_child); + H5B2_assert_leaf2(hdr, left_child, right_child); + H5B2_assert_leaf(hdr, right_child); } /* end else */ #endif /* H5B2_DEBUG */ /* Release child nodes (marked as dirty) */ - if(H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree leaf node") - if(H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree leaf node") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_split1 */ @@ -541,7 +345,6 @@ done: * Purpose: Split the root node * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Quincey Koziol @@ -551,10 +354,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_split_root(H5F_t *f, hid_t dxpl_id, H5B2_t *bt2, unsigned *bt2_flags_ptr) +H5B2_split_root(H5B2_hdr_t *hdr, hid_t dxpl_id) { H5B2_internal_t *new_root; /* Pointer to new root node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ unsigned new_root_flags = H5AC__NO_FLAGS_SET; /* Cache flags for new root node */ H5B2_node_ptr_t old_root_ptr; /* Old node pointer to root node in B-tree */ size_t sz_max_nrec; /* Temporary variable for range checking */ @@ -563,61 +365,56 @@ H5B2_split_root(H5F_t *f, hid_t dxpl_id, H5B2_t *bt2, unsigned *bt2_flags_ptr) FUNC_ENTER_NOAPI_NOINIT(H5B2_split_root) - HDassert(f); - HDassert(bt2); - HDassert(bt2_flags_ptr); - - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); - HDassert(shared); + /* Check arguments. */ + HDassert(hdr); /* Update depth of B-tree */ - shared->depth++; + hdr->depth++; /* Re-allocate array of node info structs */ - if((shared->node_info = H5FL_SEQ_REALLOC(H5B2_node_info_t, shared->node_info, (size_t)(shared->depth + 1))) == NULL) + if(NULL == (hdr->node_info = H5FL_SEQ_REALLOC(H5B2_node_info_t, hdr->node_info, (size_t)(hdr->depth + 1)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Update node info for new depth of tree */ - sz_max_nrec = H5B2_NUM_INT_REC(f, shared, shared->depth); - H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[shared->depth].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned) - shared->node_info[shared->depth].split_nrec = (shared->node_info[shared->depth].max_nrec * shared->split_percent) / 100; - shared->node_info[shared->depth].merge_nrec = (shared->node_info[shared->depth].max_nrec * shared->merge_percent) / 100; - shared->node_info[shared->depth].cum_max_nrec = ((shared->node_info[shared->depth].max_nrec + 1) * - shared->node_info[shared->depth - 1].cum_max_nrec) + shared->node_info[shared->depth].max_nrec; - u_max_nrec_size = H5V_limit_enc_size((uint64_t)shared->node_info[shared->depth].cum_max_nrec); - H5_ASSIGN_OVERFLOW(/* To: */ shared->node_info[shared->depth].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t) - if((shared->node_info[shared->depth].nat_rec_fac = H5FL_fac_init(shared->type->nrec_size * shared->node_info[shared->depth].max_nrec)) == NULL) + sz_max_nrec = H5B2_NUM_INT_REC(hdr, hdr->depth); + H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[hdr->depth].max_nrec, /* From: */ sz_max_nrec, /* From: */ size_t, /* To: */ unsigned) + hdr->node_info[hdr->depth].split_nrec = (hdr->node_info[hdr->depth].max_nrec * hdr->split_percent) / 100; + hdr->node_info[hdr->depth].merge_nrec = (hdr->node_info[hdr->depth].max_nrec * hdr->merge_percent) / 100; + hdr->node_info[hdr->depth].cum_max_nrec = ((hdr->node_info[hdr->depth].max_nrec + 1) * + hdr->node_info[hdr->depth - 1].cum_max_nrec) + hdr->node_info[hdr->depth].max_nrec; + u_max_nrec_size = H5V_limit_enc_size((uint64_t)hdr->node_info[hdr->depth].cum_max_nrec); + H5_ASSIGN_OVERFLOW(/* To: */ hdr->node_info[hdr->depth].cum_max_nrec_size, /* From: */ u_max_nrec_size, /* From: */ unsigned, /* To: */ uint8_t) + if(NULL == (hdr->node_info[hdr->depth].nat_rec_fac = H5FL_fac_init(hdr->cls->nrec_size * hdr->node_info[hdr->depth].max_nrec))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create node native key block factory") - if((shared->node_info[shared->depth].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (shared->node_info[shared->depth].max_nrec + 1))) == NULL) + if(NULL == (hdr->node_info[hdr->depth].node_ptr_fac = H5FL_fac_init(sizeof(H5B2_node_ptr_t) * (hdr->node_info[hdr->depth].max_nrec + 1)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create internal 'branch' node node pointer block factory") /* Keep old root node pointer info */ - old_root_ptr = bt2->root; + old_root_ptr = hdr->root; /* Create new internal node to use as root */ - bt2->root.node_nrec = 0; - if(H5B2_create_internal(f, dxpl_id, bt2->shared, &(bt2->root), shared->depth) < 0) + hdr->root.node_nrec = 0; + if(H5B2_create_internal(hdr, dxpl_id, &(hdr->root), hdr->depth) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new internal node") /* Protect new root node */ - if(NULL == (new_root = H5B2_protect_internal(f, dxpl_id, bt2->shared, bt2->root.addr, bt2->root.node_nrec, shared->depth, H5AC_WRITE))) + if(NULL == (new_root = H5B2_protect_internal(hdr, dxpl_id, hdr->root.addr, hdr->root.node_nrec, hdr->depth, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Set first node pointer in root node to old root node pointer info */ new_root->node_ptrs[0] = old_root_ptr; /* Split original root node */ - if(H5B2_split1(f, dxpl_id, shared->depth, &(bt2->root), bt2_flags_ptr, new_root, &new_root_flags, 0) < 0) + if(H5B2_split1(hdr, dxpl_id, hdr->depth, &(hdr->root), NULL, new_root, &new_root_flags, 0) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split old root node") /* Release new root node (marked as dirty) */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, bt2->root.addr, new_root, new_root_flags) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, hdr->root.addr, new_root, new_root_flags) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree internal node") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5B2_split_root */ +} /* end H5B2_split_root() */ /*------------------------------------------------------------------------- @@ -626,7 +423,6 @@ done: * Purpose: Redistribute records between two nodes * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Quincey Koziol @@ -636,27 +432,24 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *internal, unsigned idx) +H5B2_redistribute2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, + H5B2_internal_t *internal, unsigned idx) { const H5AC_class_t *child_class; /* Pointer to child node's class info */ haddr_t left_addr, right_addr; /* Addresses of left & right child nodes */ void *left_child, *right_child; /* Pointers to child nodes */ - unsigned *left_nrec, *right_nrec; /* Pointers to child # of records */ + uint16_t *left_nrec, *right_nrec; /* Pointers to child # of records */ uint8_t *left_native, *right_native; /* Pointers to childs' native records */ - H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */ - H5B2_shared_t *shared; /* B-tree's shared info */ - hssize_t left_moved_nrec=0, right_moved_nrec=0; /* Number of records moved, for internal redistrib */ - herr_t ret_value=SUCCEED; /* Return value */ + H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */ + hssize_t left_moved_nrec = 0, right_moved_nrec = 0; /* Number of records moved, for internal redistrib */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_redistribute2) - HDassert(f); + /* Check arguments. */ + HDassert(hdr); HDassert(internal); - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Check for the kind of B-tree node to redistribute */ if(depth > 1) { H5B2_internal_t *left_internal; /* Pointer to left internal node */ @@ -665,12 +458,12 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_INT; left_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock left & right B-tree child nodes */ - if (NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if (NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* More setup for child nodes */ @@ -690,12 +483,12 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_LEAF; left_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock left & right B-tree child nodes */ - if (NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if (NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* More setup for child nodes */ @@ -708,14 +501,14 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int } /* end else */ #ifdef H5B2_DEBUG - H5B2_assert_internal((hsize_t)0,shared,internal); - if(depth>1) { - H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,left_child,right_child); - H5B2_assert_internal2(internal->node_ptrs[idx+1].all_nrec,shared,right_child,left_child); + H5B2_assert_internal((hsize_t)0, hdr, internal); + if(depth > 1) { + H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, left_child, right_child); + H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, left_child); } /* end if */ else { - H5B2_assert_leaf2(shared,left_child,right_child); - H5B2_assert_leaf(shared,right_child); + H5B2_assert_leaf2(hdr, left_child, right_child); + H5B2_assert_leaf(hdr, right_child); } /* end else */ #endif /* H5B2_DEBUG */ @@ -723,24 +516,24 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int if(*left_nrec < *right_nrec) { /* Moving record from right node to left */ - unsigned new_right_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for right child */ - unsigned move_nrec = *right_nrec - new_right_nrec; /* Number of records to move from right node to left */ + uint16_t new_right_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for right child */ + uint16_t move_nrec = *right_nrec - new_right_nrec; /* Number of records to move from right node to left */ /* Copy record from parent node down into left child */ - HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* See if we need to move records from right node */ - if(move_nrec>1) - HDmemcpy(H5B2_NAT_NREC(left_native,shared,(*left_nrec+1)),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(move_nrec-1)); + if(move_nrec > 1) + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, (*left_nrec + 1)), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (move_nrec - 1)); /* Move record from right node into parent node */ - HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(right_native,shared,(move_nrec-1)),shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), hdr->cls->nrec_size); /* Slide records in right node down */ - HDmemmove(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(right_native,shared,move_nrec),shared->type->nrec_size*new_right_nrec); + HDmemmove(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(right_native, hdr, move_nrec), hdr->cls->nrec_size * new_right_nrec); /* Handle node pointers, if we have an internal node */ - if(depth>1) { + if(depth > 1) { hsize_t moved_nrec = move_nrec; /* Total number of records moved, for internal redistrib */ unsigned u; /* Local index variable */ @@ -754,7 +547,7 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * move_nrec); /* Slide node pointers in right node down */ - HDmemmove(&(right_node_ptrs[0]), &(right_node_ptrs[move_nrec]), sizeof(H5B2_node_ptr_t) * (new_right_nrec + 1)); + HDmemmove(&(right_node_ptrs[0]), &(right_node_ptrs[move_nrec]), sizeof(H5B2_node_ptr_t) * (new_right_nrec + (unsigned)1)); } /* end if */ /* Update number of records in child nodes */ @@ -764,37 +557,37 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int else { /* Moving record from left node to right */ - unsigned new_left_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for left child */ - unsigned move_nrec = *left_nrec - new_left_nrec; /* Number of records to move from left node to right */ + uint16_t new_left_nrec = (*left_nrec + *right_nrec) / 2; /* New number of records for left child */ + uint16_t move_nrec = *left_nrec - new_left_nrec; /* Number of records to move from left node to right */ /* Slide records in right node up */ - HDmemmove(H5B2_NAT_NREC(right_native,shared,move_nrec), - H5B2_NAT_NREC(right_native,shared,0), - shared->type->nrec_size*(*right_nrec)); + HDmemmove(H5B2_NAT_NREC(right_native, hdr, move_nrec), + H5B2_NAT_NREC(right_native, hdr, 0), + hdr->cls->nrec_size * (*right_nrec)); /* Copy record from parent node down into right child */ - HDmemcpy(H5B2_NAT_NREC(right_native,shared,(move_nrec-1)),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* See if we need to move records from left node */ - if(move_nrec>1) - HDmemcpy(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(left_native,shared,((*left_nrec-move_nrec)+1)),shared->type->nrec_size*(move_nrec-1)); + if(move_nrec > 1) + HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, ((*left_nrec - move_nrec) + 1)), hdr->cls->nrec_size * (move_nrec - 1)); /* Move record from left node into parent node */ - HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(left_native,shared,(*left_nrec-move_nrec)),shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, (*left_nrec - move_nrec)), hdr->cls->nrec_size); /* Handle node pointers, if we have an internal node */ - if(depth>1) { - hsize_t moved_nrec=move_nrec; /* Total number of records moved, for internal redistrib */ + if(depth > 1) { + hsize_t moved_nrec = move_nrec; /* Total number of records moved, for internal redistrib */ unsigned u; /* Local index variable */ /* Slide node pointers in right node up */ - HDmemmove(&(right_node_ptrs[move_nrec]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1)); + HDmemmove(&(right_node_ptrs[move_nrec]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1)); /* Copy node pointers from left node to right */ - HDmemcpy(&(right_node_ptrs[0]),&(left_node_ptrs[new_left_nrec+1]),sizeof(H5B2_node_ptr_t)*move_nrec); + HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * move_nrec); /* Count the number of records being moved */ - for(u=0; u<move_nrec; u++) + for(u = 0; u < move_nrec; u++) moved_nrec += right_node_ptrs[u].all_nrec; left_moved_nrec -= (hssize_t)moved_nrec; H5_ASSIGN_OVERFLOW(/* To: */ right_moved_nrec, /* From: */ moved_nrec, /* From: */ hsize_t, /* To: */ hssize_t) @@ -807,38 +600,38 @@ H5B2_redistribute2(H5F_t *f, hid_t dxpl_id, unsigned depth, H5B2_internal_t *int /* Update # of records in child nodes */ internal->node_ptrs[idx].node_nrec = *left_nrec; - internal->node_ptrs[idx+1].node_nrec = *right_nrec; + internal->node_ptrs[idx + 1].node_nrec = *right_nrec; /* Update total # of records in child B-trees */ - if(depth>1) { + if(depth > 1) { internal->node_ptrs[idx].all_nrec += left_moved_nrec; - internal->node_ptrs[idx+1].all_nrec += right_moved_nrec; + internal->node_ptrs[idx + 1].all_nrec += right_moved_nrec; } /* end if */ else { internal->node_ptrs[idx].all_nrec = internal->node_ptrs[idx].node_nrec; - internal->node_ptrs[idx+1].all_nrec = internal->node_ptrs[idx+1].node_nrec; + internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec; } /* end else */ #ifdef H5B2_DEBUG - H5B2_assert_internal((hsize_t)0,shared,internal); - if(depth>1) { - H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,left_child,right_child); - H5B2_assert_internal2(internal->node_ptrs[idx+1].all_nrec,shared,right_child,left_child); + H5B2_assert_internal((hsize_t)0, hdr, internal); + if(depth > 1) { + H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, left_child, right_child); + H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, left_child); } /* end if */ else { - H5B2_assert_leaf2(shared,left_child,right_child); - H5B2_assert_leaf(shared,right_child); + H5B2_assert_leaf2(hdr, left_child, right_child); + H5B2_assert_leaf(hdr, right_child); } /* end else */ #endif /* H5B2_DEBUG */ /* Release child nodes (marked as dirty) */ - if (H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") - if (H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_redistribute2 */ @@ -848,7 +641,6 @@ done: * Purpose: Redistribute records between three nodes * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Quincey Koziol @@ -858,7 +650,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, +H5B2_redistribute3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx) { const H5AC_class_t *child_class; /* Pointer to child node's class info */ @@ -866,27 +658,23 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, haddr_t middle_addr; /* Address of middle child node */ void *left_child, *right_child; /* Pointers to child nodes */ void *middle_child; /* Pointers to middle child node */ - unsigned *left_nrec, *right_nrec; /* Pointers to child # of records */ - unsigned *middle_nrec; /* Pointers to middle child # of records */ + uint16_t *left_nrec, *right_nrec; /* Pointers to child # of records */ + uint16_t *middle_nrec; /* Pointers to middle child # of records */ uint8_t *left_native, *right_native; /* Pointers to childs' native records */ uint8_t *middle_native; /* Pointers to middle child's native records */ - H5B2_shared_t *shared; /* B-tree's shared info */ - H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */ - H5B2_node_ptr_t *middle_node_ptrs=NULL;/* Pointers to childs' node pointer info */ - hssize_t left_moved_nrec=0, right_moved_nrec=0; /* Number of records moved, for internal split */ - hssize_t middle_moved_nrec=0; /* Number of records moved, for internal split */ - herr_t ret_value=SUCCEED; /* Return value */ + H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL; /* Pointers to childs' node pointer info */ + H5B2_node_ptr_t *middle_node_ptrs = NULL; /* Pointers to childs' node pointer info */ + hssize_t left_moved_nrec = 0, right_moved_nrec = 0; /* Number of records moved, for internal split */ + hssize_t middle_moved_nrec = 0; /* Number of records moved, for internal split */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_redistribute3) - HDassert(f); + /* Check arguments. */ + HDassert(hdr); HDassert(internal); HDassert(internal_flags_ptr); - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Check for the kind of B-tree node to redistribute */ if(depth > 1) { H5B2_internal_t *left_internal; /* Pointer to left internal node */ @@ -895,16 +683,16 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_INT; - left_addr = internal->node_ptrs[idx-1].addr; + left_addr = internal->node_ptrs[idx - 1].addr; middle_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock B-tree child nodes */ - if (NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx-1].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx - 1].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - if (NULL == (middle_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (middle_internal = H5B2_protect_internal(hdr, dxpl_id, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - if (NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* More setup for child nodes */ @@ -928,16 +716,16 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_LEAF; - left_addr = internal->node_ptrs[idx-1].addr; + left_addr = internal->node_ptrs[idx - 1].addr; middle_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock B-tree child nodes */ - if (NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx-1].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx - 1].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if (NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if (NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* More setup for child nodes */ @@ -956,10 +744,10 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, { /* Compute new # of records in each node */ unsigned total_nrec = *left_nrec + *middle_nrec + *right_nrec + 2; - unsigned new_middle_nrec = (total_nrec - 2) / 3; - unsigned new_left_nrec = ((total_nrec - 2) - new_middle_nrec) / 2; - unsigned new_right_nrec = (total_nrec - 2) - (new_left_nrec + new_middle_nrec); - unsigned curr_middle_nrec = *middle_nrec; + uint16_t new_middle_nrec = (total_nrec - 2) / 3; + uint16_t new_left_nrec = ((total_nrec - 2) - new_middle_nrec) / 2; + uint16_t new_right_nrec = (total_nrec - 2) - (new_left_nrec + new_middle_nrec); + uint16_t curr_middle_nrec = *middle_nrec; /* Sanity check rounding */ HDassert(new_middle_nrec <= new_left_nrec); @@ -967,42 +755,42 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Move records into left node */ if(new_left_nrec > *left_nrec) { - unsigned moved_middle_nrec = 0; /* Number of records moved into left node */ + uint16_t moved_middle_nrec = 0; /* Number of records moved into left node */ /* Move left parent record down to left node */ - HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx-1),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); /* Move records from middle node into left node */ if((new_left_nrec - 1) > *left_nrec) { - moved_middle_nrec = new_left_nrec-(*left_nrec + 1); - HDmemcpy(H5B2_NAT_NREC(left_native, shared, *left_nrec + 1),H5B2_NAT_NREC(middle_native, shared, 0), shared->type->nrec_size * moved_middle_nrec); + moved_middle_nrec = new_left_nrec - (*left_nrec + 1); + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * moved_middle_nrec); } /* end if */ /* Move record from middle node up to parent node */ - HDmemcpy(H5B2_INT_NREC(internal,shared,idx-1),H5B2_NAT_NREC(middle_native,shared,moved_middle_nrec),shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, moved_middle_nrec), hdr->cls->nrec_size); moved_middle_nrec++; /* Slide records in middle node down */ - HDmemmove(H5B2_NAT_NREC(middle_native,shared,0),H5B2_NAT_NREC(middle_native,shared,moved_middle_nrec),shared->type->nrec_size*(*middle_nrec-moved_middle_nrec)); + HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, moved_middle_nrec), hdr->cls->nrec_size * (*middle_nrec - moved_middle_nrec)); /* Move node pointers also if this is an internal node */ - if(depth>1) { + if(depth > 1) { hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */ unsigned move_nptrs; /* Number of node pointers to move */ unsigned u; /* Local index variable */ /* Move middle node pointers into left node */ move_nptrs = new_left_nrec - *left_nrec; - HDmemcpy(&(left_node_ptrs[*left_nrec+1]),&(middle_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*move_nptrs); + HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t)*move_nptrs); /* Count the number of records being moved into the left node */ - for(u=0, moved_nrec=0; u<move_nptrs; u++) + for(u = 0, moved_nrec = 0; u < move_nptrs; u++) moved_nrec += middle_node_ptrs[u].all_nrec; - left_moved_nrec = moved_nrec+move_nptrs; - middle_moved_nrec -= moved_nrec+move_nptrs; + left_moved_nrec = moved_nrec + move_nptrs; + middle_moved_nrec -= moved_nrec + move_nptrs; /* Slide the node pointers in middle node down */ - HDmemmove(&(middle_node_ptrs[0]),&(middle_node_ptrs[move_nptrs]),sizeof(H5B2_node_ptr_t)*((*middle_nrec-move_nptrs)+1)); + HDmemmove(&(middle_node_ptrs[0]), &(middle_node_ptrs[move_nptrs]), sizeof(H5B2_node_ptr_t) * ((*middle_nrec - move_nptrs) + 1)); } /* end if */ /* Update the current number of records in middle node */ @@ -1010,38 +798,38 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, } /* end if */ /* Move records into right node */ - if(new_right_nrec>*right_nrec) { - unsigned right_nrec_move = new_right_nrec-*right_nrec; /* Number of records to move out of right node */ + if(new_right_nrec > *right_nrec) { + unsigned right_nrec_move = new_right_nrec - *right_nrec; /* Number of records to move out of right node */ /* Slide records in right node up */ - HDmemmove(H5B2_NAT_NREC(right_native,shared,right_nrec_move),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(*right_nrec)); + HDmemmove(H5B2_NAT_NREC(right_native, hdr, right_nrec_move), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); /* Move right parent record down to right node */ - HDmemcpy(H5B2_NAT_NREC(right_native,shared,right_nrec_move-1),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Move records from middle node into right node */ - if(right_nrec_move>1) - HDmemcpy(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(middle_native,shared,((curr_middle_nrec-right_nrec_move)+1)),shared->type->nrec_size*(right_nrec_move-1)); + if(right_nrec_move > 1) + HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, ((curr_middle_nrec - right_nrec_move) + 1)), hdr->cls->nrec_size * (right_nrec_move - 1)); /* Move record from middle node up to parent node */ - HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(middle_native,shared,(curr_middle_nrec-right_nrec_move)),shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(middle_native, hdr, (curr_middle_nrec - right_nrec_move)), hdr->cls->nrec_size); /* Move node pointers also if this is an internal node */ - if(depth>1) { + if(depth > 1) { hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */ unsigned u; /* Local index variable */ /* Slide the node pointers in right node up */ - HDmemmove(&(right_node_ptrs[right_nrec_move]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1)); + HDmemmove(&(right_node_ptrs[right_nrec_move]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1)); /* Move middle node pointers into right node */ - HDmemcpy(&(right_node_ptrs[0]),&(middle_node_ptrs[(curr_middle_nrec-right_nrec_move)+1]),sizeof(H5B2_node_ptr_t)*right_nrec_move); + HDmemcpy(&(right_node_ptrs[0]), &(middle_node_ptrs[(curr_middle_nrec - right_nrec_move) + 1]), sizeof(H5B2_node_ptr_t) * right_nrec_move); /* Count the number of records being moved into the right node */ - for(u=0, moved_nrec=0; u<right_nrec_move; u++) + for(u = 0, moved_nrec = 0; u < right_nrec_move; u++) moved_nrec += right_node_ptrs[u].all_nrec; - right_moved_nrec = moved_nrec+right_nrec_move; - middle_moved_nrec -= moved_nrec+right_nrec_move; + right_moved_nrec = moved_nrec + right_nrec_move; + middle_moved_nrec -= moved_nrec + right_nrec_move; } /* end if */ /* Update the current number of records in middle node */ @@ -1049,38 +837,38 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, } /* end if */ /* Move records out of left node */ - if(new_left_nrec<*left_nrec) { - unsigned left_nrec_move = *left_nrec-new_left_nrec; /* Number of records to move out of left node */ + if(new_left_nrec < *left_nrec) { + unsigned left_nrec_move = *left_nrec - new_left_nrec; /* Number of records to move out of left node */ /* Slide middle records up */ - HDmemmove(H5B2_NAT_NREC(middle_native,shared,left_nrec_move),H5B2_NAT_NREC(middle_native,shared,0),shared->type->nrec_size*curr_middle_nrec); + HDmemmove(H5B2_NAT_NREC(middle_native, hdr, left_nrec_move), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * curr_middle_nrec); /* Move left parent record down to middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native,shared,left_nrec_move-1),H5B2_INT_NREC(internal,shared,idx-1),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, left_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); /* Move left records to middle node */ - if(left_nrec_move>1) - HDmemmove(H5B2_NAT_NREC(middle_native,shared,0),H5B2_NAT_NREC(left_native,shared,new_left_nrec+1),shared->type->nrec_size*(left_nrec_move-1)); + if(left_nrec_move > 1) + HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, new_left_nrec + 1), hdr->cls->nrec_size * (left_nrec_move - 1)); /* Move left parent record up from left node */ - HDmemcpy(H5B2_INT_NREC(internal,shared,idx-1),H5B2_NAT_NREC(left_native,shared,new_left_nrec),shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(left_native, hdr, new_left_nrec), hdr->cls->nrec_size); /* Move node pointers also if this is an internal node */ - if(depth>1) { + if(depth > 1) { hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */ unsigned u; /* Local index variable */ /* Slide the node pointers in middle node up */ - HDmemmove(&(middle_node_ptrs[left_nrec_move]),&(middle_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(curr_middle_nrec+1)); + HDmemmove(&(middle_node_ptrs[left_nrec_move]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (curr_middle_nrec + 1)); /* Move left node pointers into middle node */ - HDmemcpy(&(middle_node_ptrs[0]),&(left_node_ptrs[new_left_nrec+1]),sizeof(H5B2_node_ptr_t)*left_nrec_move); + HDmemcpy(&(middle_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * left_nrec_move); /* Count the number of records being moved into the left node */ - for(u=0, moved_nrec=0; u<left_nrec_move; u++) + for(u = 0, moved_nrec = 0; u < left_nrec_move; u++) moved_nrec += middle_node_ptrs[u].all_nrec; - left_moved_nrec -= moved_nrec+left_nrec_move; - middle_moved_nrec += moved_nrec+left_nrec_move; + left_moved_nrec -= moved_nrec + left_nrec_move; + middle_moved_nrec += moved_nrec + left_nrec_move; } /* end if */ /* Update the current number of records in middle node */ @@ -1088,37 +876,37 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, } /* end if */ /* Move records out of right node */ - if(new_right_nrec<*right_nrec) { - unsigned right_nrec_move = *right_nrec-new_right_nrec; /* Number of records to move out of right node */ + if(new_right_nrec < *right_nrec) { + unsigned right_nrec_move = *right_nrec - new_right_nrec; /* Number of records to move out of right node */ /* Move right parent record down to middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native,shared,curr_middle_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, curr_middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Move right records to middle node */ - HDmemmove(H5B2_NAT_NREC(middle_native,shared,(curr_middle_nrec+1)),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(right_nrec_move-1)); + HDmemmove(H5B2_NAT_NREC(middle_native, hdr, (curr_middle_nrec + 1)), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (right_nrec_move - 1)); /* Move right parent record up from right node */ - HDmemcpy(H5B2_INT_NREC(internal,shared,idx),H5B2_NAT_NREC(right_native,shared,right_nrec_move-1),shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), hdr->cls->nrec_size); /* Slide right records down */ - HDmemmove(H5B2_NAT_NREC(right_native,shared,0),H5B2_NAT_NREC(right_native,shared,right_nrec_move),shared->type->nrec_size*new_right_nrec); + HDmemmove(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(right_native, hdr, right_nrec_move), hdr->cls->nrec_size * new_right_nrec); /* Move node pointers also if this is an internal node */ - if(depth>1) { + if(depth > 1) { hsize_t moved_nrec; /* Total number of records moved, for internal redistrib */ unsigned u; /* Local index variable */ /* Move right node pointers into middle node */ - HDmemcpy(&(middle_node_ptrs[curr_middle_nrec+1]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*right_nrec_move); + HDmemcpy(&(middle_node_ptrs[curr_middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * right_nrec_move); /* Count the number of records being moved into the right node */ - for(u=0, moved_nrec=0; u<right_nrec_move; u++) + for(u = 0, moved_nrec = 0; u < right_nrec_move; u++) moved_nrec += right_node_ptrs[u].all_nrec; - right_moved_nrec -= moved_nrec+right_nrec_move; - middle_moved_nrec += moved_nrec+right_nrec_move; + right_moved_nrec -= moved_nrec + right_nrec_move; + middle_moved_nrec += moved_nrec + right_nrec_move; /* Slide the node pointers in right node down */ - HDmemmove(&(right_node_ptrs[0]),&(right_node_ptrs[right_nrec_move]),sizeof(H5B2_node_ptr_t)*(new_right_nrec+1)); + HDmemmove(&(right_node_ptrs[0]), &(right_node_ptrs[right_nrec_move]), sizeof(H5B2_node_ptr_t) * (new_right_nrec + 1)); } /* end if */ } /* end if */ @@ -1129,20 +917,20 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, } /* end block */ /* Update # of records in child nodes */ - internal->node_ptrs[idx-1].node_nrec = *left_nrec; + internal->node_ptrs[idx - 1].node_nrec = *left_nrec; internal->node_ptrs[idx].node_nrec = *middle_nrec; - internal->node_ptrs[idx+1].node_nrec = *right_nrec; + internal->node_ptrs[idx + 1].node_nrec = *right_nrec; /* Update total # of records in child B-trees */ - if(depth>1) { - internal->node_ptrs[idx-1].all_nrec += left_moved_nrec; + if(depth > 1) { + internal->node_ptrs[idx - 1].all_nrec += left_moved_nrec; internal->node_ptrs[idx].all_nrec += middle_moved_nrec; - internal->node_ptrs[idx+1].all_nrec += right_moved_nrec; + internal->node_ptrs[idx + 1].all_nrec += right_moved_nrec; } /* end if */ else { - internal->node_ptrs[idx-1].all_nrec = internal->node_ptrs[idx-1].node_nrec; + internal->node_ptrs[idx - 1].all_nrec = internal->node_ptrs[idx - 1].node_nrec; internal->node_ptrs[idx].all_nrec = internal->node_ptrs[idx].node_nrec; - internal->node_ptrs[idx+1].all_nrec = internal->node_ptrs[idx+1].node_nrec; + internal->node_ptrs[idx + 1].all_nrec = internal->node_ptrs[idx + 1].node_nrec; } /* end else */ /* Mark parent as dirty */ @@ -1152,67 +940,67 @@ H5B2_redistribute3(H5F_t *f, hid_t dxpl_id, unsigned depth, { unsigned u; - HDfprintf(stderr,"%s: Internal records:\n",FUNC); - for(u=0; u<internal->nrec; u++) { - HDfprintf(stderr,"%s: u=%u\n",FUNC,u); - (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_INT_NREC(internal,shared,u),NULL); + HDfprintf(stderr, "%s: Internal records:\n", FUNC); + for(u = 0; u < internal->nrec; u++) { + HDfprintf(stderr, "%s: u = %u\n", FUNC, u); + (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_INT_NREC(internal, hdr, u), NULL); } /* end for */ - HDfprintf(stderr,"%s: Left Child records:\n",FUNC); - for(u=0; u<*left_nrec; u++) { - HDfprintf(stderr,"%s: u=%u\n",FUNC,u); - (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_NAT_NREC(left_native,shared,u),NULL); + HDfprintf(stderr, "%s: Left Child records:\n", FUNC); + for(u = 0; u < *left_nrec; u++) { + HDfprintf(stderr, "%s: u = %u\n", FUNC, u); + (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_NAT_NREC(left_native, hdr, u), NULL); } /* end for */ - HDfprintf(stderr,"%s: Middle Child records:\n",FUNC); - for(u=0; u<*middle_nrec; u++) { - HDfprintf(stderr,"%s: u=%u\n",FUNC,u); - (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_NAT_NREC(middle_native,shared,u),NULL); + HDfprintf(stderr, "%s: Middle Child records:\n", FUNC); + for(u = 0; u < *middle_nrec; u++) { + HDfprintf(stderr, "%s: u = %u\n", FUNC, u); + (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_NAT_NREC(middle_native, hdr, u), NULL); } /* end for */ - HDfprintf(stderr,"%s: Right Child records:\n",FUNC); - for(u=0; u<*right_nrec; u++) { - HDfprintf(stderr,"%s: u=%u\n",FUNC,u); - (shared->type->debug)(stderr,f,dxpl_id,3,4,H5B2_NAT_NREC(right_native,shared,u),NULL); + HDfprintf(stderr, "%s: Right Child records:\n", FUNC); + for(u = 0; u < *right_nrec; u++) { + HDfprintf(stderr, "%s: u = %u\n", FUNC, u); + (hdr->cls->debug)(stderr, hdr->f, dxpl_id, 3, 4, H5B2_NAT_NREC(right_native, hdr, u), NULL); } /* end for */ - for(u=0; u<internal->nrec+1; u++) - HDfprintf(stderr,"%s: internal->node_ptrs[%u]=(%Hu/%u/%a)\n",FUNC,u,internal->node_ptrs[u].all_nrec,internal->node_ptrs[u].node_nrec,internal->node_ptrs[u].addr); - if(depth>1) { - for(u=0; u<*left_nrec+1; u++) - HDfprintf(stderr,"%s: left_node_ptr[%u]=(%Hu/%u/%a)\n",FUNC,u,left_node_ptrs[u].all_nrec,left_node_ptrs[u].node_nrec,left_node_ptrs[u].addr); - for(u=0; u<*middle_nrec+1; u++) - HDfprintf(stderr,"%s: middle_node_ptr[%u]=(%Hu/%u/%a)\n",FUNC,u,middle_node_ptrs[u].all_nrec,middle_node_ptrs[u].node_nrec,middle_node_ptrs[u].addr); - for(u=0; u<*right_nrec+1; u++) - HDfprintf(stderr,"%s: right_node_ptr[%u]=(%Hu/%u/%a)\n",FUNC,u,right_node_ptrs[u].all_nrec,right_node_ptrs[u].node_nrec,right_node_ptrs[u].addr); + for(u = 0; u < internal->nrec + 1; u++) + HDfprintf(stderr, "%s: internal->node_ptrs[%u] = (%Hu/%u/%a)\n", FUNC, u, internal->node_ptrs[u].all_nrec, internal->node_ptrs[u].node_nrec, internal->node_ptrs[u].addr); + if(depth > 1) { + for(u = 0; u < *left_nrec + 1; u++) + HDfprintf(stderr, "%s: left_node_ptr[%u] = (%Hu/%u/%a)\n", FUNC, u, left_node_ptrs[u].all_nrec, left_node_ptrs[u].node_nrec, left_node_ptrs[u].addr); + for(u = 0; u < *middle_nrec + 1; u++) + HDfprintf(stderr, "%s: middle_node_ptr[%u] = (%Hu/%u/%a)\n", FUNC, u, middle_node_ptrs[u].all_nrec, middle_node_ptrs[u].node_nrec, middle_node_ptrs[u].addr); + for(u = 0; u < *right_nrec + 1; u++) + HDfprintf(stderr, "%s: right_node_ptr[%u] = (%Hu/%u/%a)\n", FUNC, u, right_node_ptrs[u].all_nrec, right_node_ptrs[u].node_nrec, right_node_ptrs[u].addr); } /* end if */ } #endif /* QAK */ #ifdef H5B2_DEBUG - H5B2_assert_internal((hsize_t)0,shared,internal); - if(depth>1) { - H5B2_assert_internal2(internal->node_ptrs[idx-1].all_nrec,shared,left_child,middle_child); - H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,middle_child,left_child); - H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec,shared,middle_child,right_child); - H5B2_assert_internal2(internal->node_ptrs[idx+1].all_nrec,shared,right_child,middle_child); + H5B2_assert_internal((hsize_t)0, hdr, internal); + if(depth > 1) { + H5B2_assert_internal2(internal->node_ptrs[idx - 1].all_nrec, hdr, left_child, middle_child); + H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, middle_child, left_child); + H5B2_assert_internal2(internal->node_ptrs[idx].all_nrec, hdr, middle_child, right_child); + H5B2_assert_internal2(internal->node_ptrs[idx + 1].all_nrec, hdr, right_child, middle_child); } /* end if */ else { - H5B2_assert_leaf2(shared,left_child,middle_child); - H5B2_assert_leaf2(shared,middle_child,right_child); - H5B2_assert_leaf(shared,right_child); + H5B2_assert_leaf2(hdr, left_child, middle_child); + H5B2_assert_leaf2(hdr, middle_child, right_child); + H5B2_assert_leaf(hdr, right_child); } /* end else */ #endif /* H5B2_DEBUG */ /* Unlock child nodes (marked as dirty) */ - if (H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") - if (H5AC_unprotect(f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") - if (H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_redistribute3 */ @@ -1232,31 +1020,26 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth, +H5B2_merge2(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx) { const H5AC_class_t *child_class; /* Pointer to child node's class info */ haddr_t left_addr, right_addr; /* Addresses of left & right child nodes */ void *left_child, *right_child; /* Pointers to left & right child nodes */ - unsigned *left_nrec, *right_nrec; /* Pointers to left & right child # of records */ + uint16_t *left_nrec, *right_nrec; /* Pointers to left & right child # of records */ uint8_t *left_native, *right_native; /* Pointers to left & right children's native records */ - H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */ - H5B2_shared_t *shared; /* B-tree's shared info */ - herr_t ret_value=SUCCEED; /* Return value */ + H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_merge2) - HDassert(f); + /* Check arguments. */ + HDassert(hdr); HDassert(curr_node_ptr); - HDassert(parent_cache_info_flags_ptr); HDassert(internal); HDassert(internal_flags_ptr); - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Check for the kind of B-tree node to split */ if(depth > 1) { H5B2_internal_t *left_internal; /* Pointer to left internal node */ @@ -1265,12 +1048,12 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_INT; left_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock left & right B-tree child nodes */ - if(NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - if(NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* More setup for accessing child node information */ @@ -1290,12 +1073,12 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_LEAF; left_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock left & right B-tree child nodes */ - if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* More setup for accessing child node information */ @@ -1310,14 +1093,14 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Redistribute records into left node */ { /* Copy record from parent node to proper location */ - HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Copy records from right node to left node */ - HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec+1),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(*right_nrec)); + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); /* Copy node pointers from right node into left node */ - if(depth>1) - HDmemcpy(&(left_node_ptrs[*left_nrec+1]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1)); + if(depth > 1) + HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1)); /* Update # of records in left node */ *left_nrec += *right_nrec + 1; @@ -1327,12 +1110,12 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth, internal->node_ptrs[idx].node_nrec = *left_nrec; /* Update total # of records in child B-trees */ - internal->node_ptrs[idx].all_nrec += internal->node_ptrs[idx+1].all_nrec + 1; + internal->node_ptrs[idx].all_nrec += internal->node_ptrs[idx + 1].all_nrec + 1; /* Slide records in parent node down, to eliminate demoted record */ - if((idx+1) < internal->nrec) { - HDmemmove(H5B2_INT_NREC(internal,shared,idx),H5B2_INT_NREC(internal,shared,idx+1),shared->type->nrec_size*(internal->nrec-(idx+1))); - HDmemmove(&(internal->node_ptrs[idx+1]),&(internal->node_ptrs[idx+2]),sizeof(H5B2_node_ptr_t)*(internal->nrec-(idx+1))); + if((idx + 1) < internal->nrec) { + HDmemmove(H5B2_INT_NREC(internal, hdr, idx), H5B2_INT_NREC(internal, hdr, idx + 1), hdr->cls->nrec_size * (internal->nrec - (idx + 1))); + HDmemmove(&(internal->node_ptrs[idx + 1]), &(internal->node_ptrs[idx + 2]), sizeof(H5B2_node_ptr_t) * (internal->nrec - (idx + 1))); } /* end if */ /* Update # of records in parent node */ @@ -1344,28 +1127,29 @@ H5B2_merge2(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Update grandparent info */ curr_node_ptr->node_nrec--; - /* Mark grandparent as dirty */ - *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG; + /* Mark grandparent as dirty, if given */ + if(parent_cache_info_flags_ptr) + *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG; #ifdef H5B2_DEBUG - H5B2_assert_internal((hsize_t)0,shared,internal); - if(depth>1) - H5B2_assert_internal(internal->node_ptrs[idx].all_nrec,shared,left_child); + H5B2_assert_internal((hsize_t)0, hdr, internal); + if(depth > 1) + H5B2_assert_internal(internal->node_ptrs[idx].all_nrec, hdr, left_child); else - H5B2_assert_leaf(shared,left_child); + H5B2_assert_leaf(hdr, left_child); #endif /* H5B2_DEBUG */ /* Unlock left node (marked as dirty) */ - if(H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") /* Delete right node & remove from cache (marked as dirty) */ - if(H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") done: - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5B2_merge2 */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_merge2() */ /*------------------------------------------------------------------------- @@ -1384,7 +1168,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, +H5B2_merge3(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, unsigned *parent_cache_info_flags_ptr, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx) { @@ -1393,28 +1177,23 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, haddr_t middle_addr; /* Address of middle child node */ void *left_child, *right_child; /* Pointers to left & right child nodes */ void *middle_child; /* Pointer to middle child node */ - unsigned *left_nrec, *right_nrec; /* Pointers to left & right child # of records */ - unsigned *middle_nrec; /* Pointer to middle child # of records */ + uint16_t *left_nrec, *right_nrec; /* Pointers to left & right child # of records */ + uint16_t *middle_nrec; /* Pointer to middle child # of records */ uint8_t *left_native, *right_native; /* Pointers to left & right children's native records */ uint8_t *middle_native; /* Pointer to middle child's native records */ - H5B2_node_ptr_t *left_node_ptrs=NULL, *right_node_ptrs=NULL;/* Pointers to childs' node pointer info */ - H5B2_node_ptr_t *middle_node_ptrs=NULL;/* Pointer to child's node pointer info */ - H5B2_shared_t *shared; /* B-tree's shared info */ + H5B2_node_ptr_t *left_node_ptrs = NULL, *right_node_ptrs = NULL;/* Pointers to childs' node pointer info */ + H5B2_node_ptr_t *middle_node_ptrs = NULL;/* Pointer to child's node pointer info */ hsize_t middle_moved_nrec; /* Number of records moved, for internal split */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_merge3) - HDassert(f); + /* Check arguments. */ + HDassert(hdr); HDassert(curr_node_ptr); - HDassert(parent_cache_info_flags_ptr); HDassert(internal); HDassert(internal_flags_ptr); - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Check for the kind of B-tree node to split */ if(depth > 1) { H5B2_internal_t *left_internal; /* Pointer to left internal node */ @@ -1423,16 +1202,16 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_INT; - left_addr = internal->node_ptrs[idx-1].addr; + left_addr = internal->node_ptrs[idx - 1].addr; middle_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock B-tree child nodes */ - if (NULL == (left_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, left_addr, internal->node_ptrs[idx-1].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (left_internal = H5B2_protect_internal(hdr, dxpl_id, left_addr, internal->node_ptrs[idx - 1].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - if (NULL == (middle_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (middle_internal = H5B2_protect_internal(hdr, dxpl_id, middle_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - if (NULL == (right_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, right_addr, internal->node_ptrs[idx+1].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (right_internal = H5B2_protect_internal(hdr, dxpl_id, right_addr, internal->node_ptrs[idx + 1].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* More setup for accessing child node information */ @@ -1456,16 +1235,16 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Setup information for unlocking child nodes */ child_class = H5AC_BT2_LEAF; - left_addr = internal->node_ptrs[idx-1].addr; + left_addr = internal->node_ptrs[idx - 1].addr; middle_addr = internal->node_ptrs[idx].addr; - right_addr = internal->node_ptrs[idx+1].addr; + right_addr = internal->node_ptrs[idx + 1].addr; /* Lock B-tree child nodes */ - if (NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx-1].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (left_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, left_addr, &(internal->node_ptrs[idx - 1].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if (NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (middle_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, middle_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - if (NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx+1].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (right_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, right_addr, &(internal->node_ptrs[idx + 1].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* More setup for accessing child node information */ @@ -1489,30 +1268,30 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, middle_moved_nrec = middle_nrec_move; /* Copy record from parent node to proper location in left node */ - HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec),H5B2_INT_NREC(internal,shared,idx-1),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); /* Copy records from middle node to left node */ - HDmemcpy(H5B2_NAT_NREC(left_native,shared,*left_nrec+1),H5B2_NAT_NREC(middle_native,shared,0),shared->type->nrec_size*(middle_nrec_move-1)); + HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * (middle_nrec_move - 1)); /* Copy record from middle node to proper location in parent node */ - HDmemcpy(H5B2_INT_NREC(internal,shared,idx-1),H5B2_NAT_NREC(middle_native,shared,(middle_nrec_move-1)),shared->type->nrec_size); + HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, (middle_nrec_move - 1)), hdr->cls->nrec_size); /* Slide records in middle node down */ - HDmemmove(H5B2_NAT_NREC(middle_native,shared,0),H5B2_NAT_NREC(middle_native,shared,middle_nrec_move),shared->type->nrec_size*(*middle_nrec-middle_nrec_move)); + HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, middle_nrec_move), hdr->cls->nrec_size * (*middle_nrec - middle_nrec_move)); /* Move node pointers also if this is an internal node */ - if(depth>1) { + if(depth > 1) { unsigned u; /* Local index variable */ /* Copy node pointers from middle node into left node */ - HDmemcpy(&(left_node_ptrs[*left_nrec+1]),&(middle_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*middle_nrec_move); + HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * middle_nrec_move); /* Count the number of records being moved into the left node */ - for(u=0; u<middle_nrec_move; u++) + for(u = 0; u < middle_nrec_move; u++) middle_moved_nrec += middle_node_ptrs[u].all_nrec; /* Slide the node pointers in right node down */ - HDmemmove(&(middle_node_ptrs[0]),&(middle_node_ptrs[middle_nrec_move]),sizeof(H5B2_node_ptr_t)*((*middle_nrec+1)-middle_nrec_move)); + HDmemmove(&(middle_node_ptrs[0]), &(middle_node_ptrs[middle_nrec_move]), sizeof(H5B2_node_ptr_t) * ((*middle_nrec + 1) - middle_nrec_move)); } /* end if */ /* Update # of records in left & middle nodes */ @@ -1523,32 +1302,32 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Redistribute records into middle node */ { /* Copy record from parent node to proper location in middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native,shared,*middle_nrec),H5B2_INT_NREC(internal,shared,idx),shared->type->nrec_size); + HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Copy records from right node to middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native,shared,*middle_nrec+1),H5B2_NAT_NREC(right_native,shared,0),shared->type->nrec_size*(*right_nrec)); + HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); /* Move node pointers also if this is an internal node */ - if(depth>1) + if(depth > 1) /* Copy node pointers from middle node into left node */ - HDmemcpy(&(middle_node_ptrs[*middle_nrec+1]),&(right_node_ptrs[0]),sizeof(H5B2_node_ptr_t)*(*right_nrec+1)); + HDmemcpy(&(middle_node_ptrs[*middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (*right_nrec + 1)); /* Update # of records in middle node */ *middle_nrec += *right_nrec + 1; } /* end block */ /* Update # of records in child nodes */ - internal->node_ptrs[idx-1].node_nrec = *left_nrec; + internal->node_ptrs[idx - 1].node_nrec = *left_nrec; internal->node_ptrs[idx].node_nrec = *middle_nrec; /* Update total # of records in child B-trees */ - internal->node_ptrs[idx-1].all_nrec += middle_moved_nrec; - internal->node_ptrs[idx].all_nrec += (internal->node_ptrs[idx+1].all_nrec + 1) - middle_moved_nrec; + internal->node_ptrs[idx - 1].all_nrec += middle_moved_nrec; + internal->node_ptrs[idx].all_nrec += (internal->node_ptrs[idx + 1].all_nrec + 1) - middle_moved_nrec; /* Slide records in parent node down, to eliminate demoted record */ - if((idx+1) < internal->nrec) { - HDmemmove(H5B2_INT_NREC(internal,shared,idx),H5B2_INT_NREC(internal,shared,idx+1),shared->type->nrec_size*(internal->nrec-(idx+1))); - HDmemmove(&(internal->node_ptrs[idx+1]),&(internal->node_ptrs[idx+2]),sizeof(H5B2_node_ptr_t)*(internal->nrec-(idx+1))); + if((idx + 1) < internal->nrec) { + HDmemmove(H5B2_INT_NREC(internal, hdr, idx), H5B2_INT_NREC(internal, hdr, idx + 1), hdr->cls->nrec_size * (internal->nrec - (idx + 1))); + HDmemmove(&(internal->node_ptrs[idx + 1]), &(internal->node_ptrs[idx + 2]), sizeof(H5B2_node_ptr_t) * (internal->nrec - (idx + 1))); } /* end if */ /* Update # of records in parent node */ @@ -1560,34 +1339,35 @@ H5B2_merge3(H5F_t *f, hid_t dxpl_id, unsigned depth, /* Update grandparent info */ curr_node_ptr->node_nrec--; - /* Mark grandparent as dirty */ - *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG; + /* Mark grandparent as dirty, if given */ + if(parent_cache_info_flags_ptr) + *parent_cache_info_flags_ptr |= H5AC__DIRTIED_FLAG; #ifdef H5B2_DEBUG - H5B2_assert_internal((hsize_t)0,shared,internal); - if(depth>1) { - H5B2_assert_internal2(internal->node_ptrs[idx-1].all_nrec,shared,left_child,middle_child); - H5B2_assert_internal(internal->node_ptrs[idx].all_nrec,shared,middle_child); + H5B2_assert_internal((hsize_t)0, hdr, internal); + if(depth > 1) { + H5B2_assert_internal2(internal->node_ptrs[idx - 1].all_nrec, hdr, left_child, middle_child); + H5B2_assert_internal(internal->node_ptrs[idx].all_nrec, hdr, middle_child); } /* end if */ else { - H5B2_assert_leaf2(shared,left_child,middle_child); - H5B2_assert_leaf(shared,middle_child); + H5B2_assert_leaf2(hdr, left_child, middle_child); + H5B2_assert_leaf(hdr, middle_child); } /* end else */ #endif /* H5B2_DEBUG */ /* Unlock left & middle nodes (marked as dirty) */ - if (H5AC_unprotect(f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, left_addr, left_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") - if (H5AC_unprotect(f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, middle_addr, middle_child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") /* Delete right node & remove from cache (marked as dirty) */ - if(H5AC_unprotect(f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") done: - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5B2_merge3 */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_merge3() */ /*------------------------------------------------------------------------- @@ -1606,7 +1386,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth, +H5B2_swap_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx, void *swap_loc) { @@ -1614,20 +1394,16 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth, haddr_t child_addr; /* Address of child node */ void *child; /* Pointer to child node */ uint8_t *child_native; /* Pointer to child's native records */ - H5B2_shared_t *shared; /* B-tree's shared info */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_swap_leaf) - HDassert(f); + /* Check arguments. */ + HDassert(hdr); HDassert(internal); HDassert(internal_flags_ptr); HDassert(idx <= internal->nrec); - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); - /* Check for the kind of B-tree node to swap */ if(depth > 1) { H5B2_internal_t *child_internal; /* Pointer to internal node */ @@ -1637,7 +1413,7 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth, child_addr = internal->node_ptrs[idx].addr; /* Lock B-tree child nodes */ - if(NULL == (child_internal = H5B2_protect_internal(f, dxpl_id, internal->shared, child_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) + if(NULL == (child_internal = H5B2_protect_internal(hdr, dxpl_id, child_addr, internal->node_ptrs[idx].node_nrec, (depth - 1), H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* More setup for accessing child node information */ @@ -1652,7 +1428,7 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth, child_addr = internal->node_ptrs[idx].addr; /* Lock B-tree child node */ - if (NULL == (child_leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, child_class, child_addr, &(internal->node_ptrs[idx].node_nrec), internal->shared, H5AC_WRITE))) + if(NULL == (child_leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, child_class, child_addr, &(internal->node_ptrs[idx].node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* More setup for accessing child node information */ @@ -1661,27 +1437,27 @@ H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth, } /* end else */ /* Swap records (use disk page as temporary buffer) */ - HDmemcpy(shared->page, H5B2_NAT_NREC(child_native,shared,0), shared->type->nrec_size); - HDmemcpy(H5B2_NAT_NREC(child_native,shared,0), swap_loc, shared->type->nrec_size); - HDmemcpy(swap_loc, shared->page, shared->type->nrec_size); + HDmemcpy(hdr->page, H5B2_NAT_NREC(child_native, hdr, 0), hdr->cls->nrec_size); + HDmemcpy(H5B2_NAT_NREC(child_native, hdr, 0), swap_loc, hdr->cls->nrec_size); + HDmemcpy(swap_loc, hdr->page, hdr->cls->nrec_size); /* Mark parent as dirty */ *internal_flags_ptr |= H5AC__DIRTIED_FLAG; #ifdef H5B2_DEBUG - H5B2_assert_internal((hsize_t)0,shared,internal); - if(depth>1) - H5B2_assert_internal(internal->node_ptrs[idx].all_nrec,shared,child); + H5B2_assert_internal((hsize_t)0, hdr, internal); + if(depth > 1) + H5B2_assert_internal(internal->node_ptrs[idx].all_nrec, hdr, child); else - H5B2_assert_leaf(shared,child); + H5B2_assert_leaf(hdr, child); #endif /* H5B2_DEBUG */ /* Unlock child node */ - if (H5AC_unprotect(f, dxpl_id, child_class, child_addr, child, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, child_class, child_addr, child, H5AC__DIRTIED_FLAG) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_swap_leaf */ @@ -1699,11 +1475,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - H5B2_node_ptr_t *curr_node_ptr, void *udata) +H5B2_insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, + void *udata) { H5B2_leaf_t *leaf; /* Pointer to leaf node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ int cmp; /* Comparison value of records */ unsigned idx; /* Location of record which matches key */ herr_t ret_value = SUCCEED; @@ -1711,21 +1486,16 @@ H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, FUNC_ENTER_NOAPI_NOINIT(H5B2_insert_leaf) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); /* Lock current B-tree node */ - if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_WRITE))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Must have a leaf node with enough space to insert a record now */ - HDassert(curr_node_ptr->node_nrec < shared->node_info[0].max_nrec); + HDassert(curr_node_ptr->node_nrec < hdr->node_info[0].max_nrec); /* Sanity check number of records */ HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec); @@ -1736,18 +1506,18 @@ H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, idx = 0; else { /* Find correct location to insert this record */ - if((cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx)) == 0) + if((cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx)) == 0) HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree") if(cmp > 0) idx++; /* Make room for new record */ if(idx < leaf->nrec) - HDmemmove(H5B2_LEAF_NREC(leaf, shared, idx + 1), H5B2_LEAF_NREC(leaf, shared, idx), shared->type->nrec_size * (leaf->nrec-idx)); + HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx + 1), H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size * (leaf->nrec - idx)); } /* end else */ /* Make callback to store record in native form */ - if((shared->type->store)(H5B2_LEAF_NREC(leaf, shared, idx), udata) < 0) + if((hdr->cls->store)(H5B2_LEAF_NREC(leaf, hdr, idx), udata) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into leaf node") /* Update record count for node pointer to current node */ @@ -1759,7 +1529,7 @@ H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, done: /* Release the B-tree leaf node (marked as dirty) */ - if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__DIRTIED_FLAG) < 0) + if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__DIRTIED_FLAG) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -1780,34 +1550,27 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - unsigned depth, unsigned *parent_cache_info_flags_ptr, - H5B2_node_ptr_t *curr_node_ptr, void *udata) +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) { H5B2_internal_t *internal; /* Pointer to internal node */ unsigned internal_flags = H5AC__NO_FLAGS_SET; - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ unsigned idx; /* Location of record which matches key */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_insert_internal) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(depth > 0); - HDassert(parent_cache_info_flags_ptr); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); /* Lock current B-tree node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Split or redistribute child node pointers, if necessary */ { int cmp; /* Comparison value of records */ @@ -1815,7 +1578,7 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, size_t split_nrec; /* Number of records to split node at */ /* Locate node pointer for child */ - if((cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx)) == 0) + if((cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx)) == 0) HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree") if(cmp > 0) idx++; @@ -1829,29 +1592,29 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, retries = 2; /* Determine the correct number of records to split child node at */ - split_nrec = shared->node_info[depth - 1].split_nrec; + split_nrec = hdr->node_info[depth - 1].split_nrec; /* Preemptively split/redistribute a node we will enter */ while(internal->node_ptrs[idx].node_nrec == split_nrec) { /* Attempt to redistribute records among children */ if(idx == 0) { /* Left-most child */ - if(retries > 0 && (internal->node_ptrs[idx+1].node_nrec < split_nrec)) { - if(H5B2_redistribute2(f, dxpl_id, depth, internal, idx) < 0) + if(retries > 0 && (internal->node_ptrs[idx + 1].node_nrec < split_nrec)) { + if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_split1(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_split1(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node") } /* end else */ } /* end if */ else if(idx == internal->nrec) { /* Right-most child */ if(retries > 0 && (internal->node_ptrs[idx - 1].node_nrec < split_nrec)) { - if(H5B2_redistribute2(f, dxpl_id, depth, internal, (idx - 1)) < 0) + if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, (idx - 1)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_split1(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_split1(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node") } /* end else */ @@ -1859,11 +1622,11 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, else { /* Middle child */ if(retries > 0 && ((internal->node_ptrs[idx + 1].node_nrec < split_nrec) || (internal->node_ptrs[idx - 1].node_nrec < split_nrec))) { - if(H5B2_redistribute3(f, dxpl_id, depth, internal, &internal_flags, idx) < 0) + if(H5B2_redistribute3(hdr, dxpl_id, depth, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_split1(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_split1(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node") } /* end else */ @@ -1871,7 +1634,7 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Locate node pointer for child (after split/redistribute) */ /* Actually, this can be easily updated (for 2-node redistrib.) and shouldn't require re-searching */ - if((cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx)) == 0) + if((cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx)) == 0) HGOTO_ERROR(H5E_BTREE, H5E_EXISTS, FAIL, "record is already in B-tree") if(cmp > 0) idx++; @@ -1883,11 +1646,11 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Attempt to insert node */ if(depth > 1) { - if(H5B2_insert_internal(f, dxpl_id, bt2_shared, (depth - 1), &internal_flags, &internal->node_ptrs[idx], udata) < 0) + if(H5B2_insert_internal(hdr, dxpl_id, (depth - 1), &internal_flags, &internal->node_ptrs[idx], udata) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node") } /* end if */ else { - if(H5B2_insert_leaf(f, dxpl_id, bt2_shared, &internal->node_ptrs[idx], udata) < 0) + if(H5B2_insert_leaf(hdr, dxpl_id, &internal->node_ptrs[idx], udata) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node") } /* end else */ @@ -1899,7 +1662,7 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, done: /* Release the B-tree internal node */ - if (internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, internal_flags) < 0) + if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, internal_flags) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -1921,56 +1684,53 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_create_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, H5B2_node_ptr_t *node_ptr) +H5B2_create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *node_ptr) { H5B2_leaf_t *leaf = NULL; /* Pointer to new leaf node created */ - H5B2_shared_t *shared; /* Shared B-tree information */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_create_leaf) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(node_ptr); /* Allocate memory for leaf information */ if(NULL == (leaf = H5FL_MALLOC(H5B2_leaf_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf info") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf info") /* Set metadata cache info */ HDmemset(&leaf->cache_info, 0, sizeof(H5AC_info_t)); - /* Share common B-tree information */ - leaf->shared = bt2_shared; - H5RC_INC(leaf->shared); + /* Increment ref. count on B-tree header */ + if(H5B2_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, FAIL, "can't increment ref. count on B-tree header") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared); - HDassert(shared); + /* Share B-tree header information */ + leaf->hdr = hdr; /* Allocate space for the native keys in memory */ - if((leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[0].nat_rec_fac)) == NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf native keys") + if(NULL == (leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[0].nat_rec_fac))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf native keys") #ifdef H5_CLEAR_MEMORY -HDmemset(leaf->leaf_native, 0, shared->type->nrec_size * shared->node_info[0].max_nrec); +HDmemset(leaf->leaf_native, 0, hdr->cls->nrec_size * hdr->node_info[0].max_nrec); #endif /* H5_CLEAR_MEMORY */ /* Set number of records */ leaf->nrec = 0; /* Allocate space on disk for the leaf */ - if(HADDR_UNDEF == (node_ptr->addr=H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->node_size))) + if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(hdr->f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)hdr->node_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree leaf node") /* Cache the new B-tree node */ - if(H5AC_set(f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(hdr->f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree leaf to cache") done: if(ret_value < 0) { if(leaf) - (void)H5B2_cache_leaf_dest(f,leaf); + (void)H5B2_cache_leaf_dest(hdr->f, leaf); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -1992,18 +1752,16 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_create_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - H5B2_node_ptr_t *node_ptr, unsigned depth) +H5B2_create_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *node_ptr, + unsigned depth) { - H5B2_internal_t *internal=NULL; /* Pointer to new internal node created */ - H5B2_shared_t *shared; /* Shared B-tree information */ + H5B2_internal_t *internal = NULL; /* Pointer to new internal node created */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_create_internal) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(node_ptr); HDassert(depth > 0); @@ -2014,26 +1772,25 @@ H5B2_create_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Set metadata cache info */ HDmemset(&internal->cache_info, 0, sizeof(H5AC_info_t)); - /* Share common B-tree information */ - internal->shared = bt2_shared; - H5RC_INC(internal->shared); + /* Increment ref. count on B-tree header */ + if(H5B2_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, FAIL, "can't increment ref. count on B-tree header") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); - HDassert(shared); + /* Share B-tree header information */ + internal->hdr = hdr; /* Allocate space for the native keys in memory */ - if((internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[depth].nat_rec_fac)) == NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys") + if(NULL == (internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].nat_rec_fac))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys") #ifdef H5_CLEAR_MEMORY -HDmemset(internal->int_native, 0, shared->type->nrec_size * shared->node_info[depth].max_nrec); +HDmemset(internal->int_native, 0, hdr->cls->nrec_size * hdr->node_info[depth].max_nrec); #endif /* H5_CLEAR_MEMORY */ /* Allocate space for the node pointers in memory */ - if((internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(shared->node_info[depth].node_ptr_fac)) == NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers") + if(NULL == (internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].node_ptr_fac))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers") #ifdef H5_CLEAR_MEMORY -HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (shared->node_info[depth].max_nrec + 1)); +HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (hdr->node_info[depth].max_nrec + 1)); #endif /* H5_CLEAR_MEMORY */ /* Set number of records & depth of the node */ @@ -2041,17 +1798,17 @@ HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (shared->node_info[de internal->depth = depth; /* Allocate space on disk for the internal node */ - if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->node_size))) + if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(hdr->f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)hdr->node_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree internal node") /* Cache the new B-tree node */ - if(H5AC_set(f, dxpl_id, H5AC_BT2_INT, node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(hdr->f, dxpl_id, H5AC_BT2_INT, node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree internal node to cache") done: if(ret_value < 0) { if(internal) - (void)H5B2_cache_internal_dest(f,internal); + (void)H5B2_cache_internal_dest(hdr->f, internal); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -2072,7 +1829,7 @@ done: *------------------------------------------------------------------------- */ H5B2_internal_t * -H5B2_protect_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, haddr_t addr, +H5B2_protect_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, haddr_t addr, unsigned nrec, unsigned depth, H5AC_protect_t rw) { H5B2_int_load_ud1_t udata; /* User data to pass through to cache 'load' callback */ @@ -2081,18 +1838,17 @@ H5B2_protect_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, haddr_t addr, FUNC_ENTER_NOAPI_NOINIT(H5B2_protect_internal) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(H5F_addr_defined(addr)); HDassert(depth > 0); /* Set up user data for callback */ - udata.bt2_shared = bt2_shared; + udata.hdr = hdr; udata.nrec = nrec; udata.depth = depth; /* Protect the internal node */ - if(NULL == (ret_value = (H5B2_internal_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_INT, addr, &udata, NULL, rw))) + if(NULL == (ret_value = (H5B2_internal_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_INT, addr, &udata, NULL, rw))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree internal node") done: @@ -2118,10 +1874,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, +H5B2_iterate_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, const H5B2_node_ptr_t *curr_node, H5B2_operator_t op, void *op_data) { - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ const H5AC_class_t *curr_node_class = NULL; /* Pointer to current node's class info */ void *node = NULL; /* Pointers to current node */ uint8_t *node_native; /* Pointers to node's native records */ @@ -2133,21 +1888,16 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, FUNC_ENTER_NOAPI_NOINIT(H5B2_iterate_node) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(curr_node); HDassert(op); - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Protect current node & set up variables */ if(depth > 0) { H5B2_internal_t *internal; /* Pointer to internal node */ /* Lock the current B-tree node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Set up information about current node */ @@ -2156,8 +1906,8 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, node_native = internal->int_native; /* Allocate space for the node pointers in memory */ - if((node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(shared->node_info[depth].node_ptr_fac)) == NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers") + if(NULL == (node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].node_ptr_fac))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers") /* Copy the node pointers */ HDmemcpy(node_ptrs, internal->node_ptrs, (sizeof(H5B2_node_ptr_t) * (curr_node->node_nrec + 1))); @@ -2166,7 +1916,7 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, H5B2_leaf_t *leaf; /* Pointer to leaf node */ /* Lock the current B-tree node */ - if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), bt2_shared, H5AC_READ))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), hdr, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* Set up information about current node */ @@ -2176,14 +1926,14 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, } /* end else */ /* Allocate space for the native keys in memory */ - if((native = (uint8_t *)H5FL_FAC_MALLOC(shared->node_info[depth].nat_rec_fac)) == NULL) + if(NULL == (native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].nat_rec_fac))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys") /* Copy the native keys */ - HDmemcpy(native, node_native, (shared->type->nrec_size * curr_node->node_nrec)); + HDmemcpy(native, node_native, (hdr->cls->nrec_size * curr_node->node_nrec)); /* Unlock the node */ - if(H5AC_unprotect(f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") node = NULL; @@ -2191,29 +1941,29 @@ H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, for(u = 0; u < curr_node->node_nrec && !ret_value; u++) { /* Descend into child node, if current node is an internal node */ if(depth > 0) { - if((ret_value = H5B2_iterate_node(f, dxpl_id, bt2_shared, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0) + if((ret_value = H5B2_iterate_node(hdr, dxpl_id, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0) HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed"); } /* end if */ /* Make callback for current record */ if(!ret_value) { - if((ret_value = (op)(H5B2_NAT_NREC(native, shared, u), op_data)) < 0) + if((ret_value = (op)(H5B2_NAT_NREC(native, hdr, u), op_data)) < 0) HERROR(H5E_BTREE, H5E_CANTLIST, "iterator function failed"); } /* end if */ } /* end for */ /* Descend into last child node, if current node is an internal node */ if(!ret_value && depth > 0) { - if((ret_value = H5B2_iterate_node(f, dxpl_id, bt2_shared, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0) + if((ret_value = H5B2_iterate_node(hdr, dxpl_id, (depth - 1), &(node_ptrs[u]), op, op_data)) < 0) HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed"); } /* end if */ done: /* Release the node pointers & native records, if they were copied */ if(node_ptrs) - H5FL_FAC_FREE(shared->node_info[depth].node_ptr_fac, node_ptrs); + H5FL_FAC_FREE(hdr->node_info[depth].node_ptr_fac, node_ptrs); if(native) - H5FL_FAC_FREE(shared->node_info[depth].nat_rec_fac, native); + H5FL_FAC_FREE(hdr->node_info[depth].nat_rec_fac, native); FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_iterate_node() */ @@ -2233,45 +1983,38 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op, - void *op_data) +H5B2_remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, + void *udata, H5B2_remove_t op, void *op_data) { H5B2_leaf_t *leaf; /* Pointer to leaf node */ haddr_t leaf_addr = HADDR_UNDEF; /* Leaf address on disk */ unsigned leaf_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting leaf node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ unsigned idx; /* Location of record which matches key */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_leaf) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); /* Lock current B-tree node */ leaf_addr = curr_node_ptr->addr; - if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_WRITE))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Sanity check number of records */ HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec); HDassert(leaf->nrec == curr_node_ptr->node_nrec); /* Find correct location to remove this record */ - if(H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx) != 0) + if(H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx) != 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree") /* Make 'remove' callback if there is one */ if(op) - if((op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) + if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record into leaf node") /* Update number of records in node */ @@ -2283,7 +2026,7 @@ H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, if(leaf->nrec > 0) { /* Pack record out of leaf */ if(idx < leaf->nrec) - HDmemmove(H5B2_LEAF_NREC(leaf, shared, idx), H5B2_LEAF_NREC(leaf, shared, (idx + 1)), shared->type->nrec_size * (leaf->nrec-idx)); + HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx), H5B2_LEAF_NREC(leaf, hdr, (idx + 1)), hdr->cls->nrec_size * (leaf->nrec - idx)); } /* end if */ else { /* Let the cache know that the object is deleted */ @@ -2298,7 +2041,7 @@ H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, done: /* Release the B-tree leaf node */ - if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0) + if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -2319,11 +2062,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - hbool_t *depth_decreased, void *swap_loc, unsigned depth, - H5AC_info_t *parent_cache_info, unsigned *parent_cache_info_flags_ptr, - H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op, - void *op_data) +H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased, + void *swap_loc, unsigned depth, H5AC_info_t *parent_cache_info, + unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr, + void *udata, H5B2_remove_t op, void *op_data) { H5AC_info_t *new_cache_info; /* Pointer to new cache info */ unsigned *new_cache_info_flags_ptr = NULL; @@ -2331,7 +2073,6 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, H5B2_internal_t *internal; /* Pointer to internal node */ unsigned internal_flags = H5AC__NO_FLAGS_SET; haddr_t internal_addr; /* Address of internal node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ size_t merge_nrec; /* Number of records to merge node at */ hbool_t collapsed_root = FALSE; /* Whether the root was collapsed */ herr_t ret_value = SUCCEED; @@ -2339,25 +2080,19 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_internal) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(depth > 0); HDassert(parent_cache_info); - HDassert(parent_cache_info_flags_ptr); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); /* Lock current B-tree node */ internal_addr = curr_node_ptr->addr; - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Determine the correct number of records to merge at */ - merge_nrec = shared->node_info[depth - 1].merge_nrec; + merge_nrec = hdr->node_info[depth - 1].merge_nrec; /* Check for needing to collapse the root node */ /* (The root node is the only internal node allowed to have 1 record) */ @@ -2365,7 +2100,7 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, ((internal->node_ptrs[0].node_nrec + internal->node_ptrs[1].node_nrec) <= ((merge_nrec * 2) + 1))) { /* Merge children of root node */ - if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, 0) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") @@ -2397,7 +2132,7 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, if(swap_loc) idx = 0; else { - cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); if(cmp >= 0) idx++; } /* end else */ @@ -2421,22 +2156,22 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, */ if(idx == 0) { /* Left-most child */ if(retries > 0 && (internal->node_ptrs[idx + 1].node_nrec > merge_nrec)) { - if(H5B2_redistribute2(f, dxpl_id, depth, internal, idx) < 0) + if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") } /* end else */ } /* end if */ else if(idx == internal->nrec) { /* Right-most child */ if(retries > 0 && (internal->node_ptrs[idx - 1].node_nrec > merge_nrec)) { - if(H5B2_redistribute2(f, dxpl_id, depth, internal, (idx - 1)) < 0) + if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, (idx - 1)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, (idx - 1)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") } /* end else */ @@ -2444,11 +2179,11 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, else { /* Middle child */ if(retries > 0 && ((internal->node_ptrs[idx + 1].node_nrec > merge_nrec) || (internal->node_ptrs[idx - 1].node_nrec > merge_nrec))) { - if(H5B2_redistribute3(f, dxpl_id, depth, internal, &internal_flags, idx) < 0) + if(H5B2_redistribute3(hdr, dxpl_id, depth, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_merge3(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge3(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") } /* end else */ @@ -2459,7 +2194,7 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, idx = 0; else { /* Actually, this can be easily updated (for 2-node redistrib.) and shouldn't require re-searching */ - cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); if(cmp >= 0) idx++; } /* end else */ @@ -2470,11 +2205,11 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Handle deleting a record from an internal node */ if(!swap_loc && cmp == 0) - swap_loc = H5B2_INT_NREC(internal, shared, idx - 1); + swap_loc = H5B2_INT_NREC(internal, hdr, idx - 1); /* Swap record to delete with record from leaf, if we are the last internal node */ if(swap_loc && depth == 1) - if(H5B2_swap_leaf(f, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0) + if(H5B2_swap_leaf(hdr, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSWAP, FAIL, "Can't swap records in B-tree") /* Set pointers for advancing to child node */ @@ -2485,12 +2220,12 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Attempt to remove record from child node */ if(depth > 1) { - if(H5B2_remove_internal(f, dxpl_id, bt2_shared, depth_decreased, swap_loc, depth - 1, + if(H5B2_remove_internal(hdr, dxpl_id, depth_decreased, swap_loc, depth - 1, new_cache_info, new_cache_info_flags_ptr, new_node_ptr, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node") } /* end if */ else { - if(H5B2_remove_leaf(f, dxpl_id, bt2_shared, new_node_ptr, udata, op, op_data) < 0) + if(H5B2_remove_leaf(hdr, dxpl_id, new_node_ptr, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node") } /* end else */ @@ -2502,12 +2237,12 @@ H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, internal_flags |= H5AC__DIRTIED_FLAG; #ifdef H5B2_DEBUG - H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec-1) : new_node_ptr->all_nrec),shared,internal); + H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec - 1) : new_node_ptr->all_nrec), hdr, internal); #endif /* H5B2_DEBUG */ done: /* Release the B-tree internal node */ - if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0) + if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -2529,33 +2264,27 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, unsigned idx, H5B2_remove_t op, void *op_data) { H5B2_leaf_t *leaf; /* Pointer to leaf node */ haddr_t leaf_addr = HADDR_UNDEF; /* Leaf address on disk */ unsigned leaf_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting leaf node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_leaf_by_idx) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); /* Lock B-tree leaf node */ leaf_addr = curr_node_ptr->addr; - if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_WRITE))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, &(curr_node_ptr->node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Sanity check number of records */ HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec); HDassert(leaf->nrec == curr_node_ptr->node_nrec); @@ -2563,7 +2292,7 @@ H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Make 'remove' callback if there is one */ if(op) - if((op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) + if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record into leaf node") /* Update number of records in node */ @@ -2575,7 +2304,7 @@ H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, if(leaf->nrec > 0) { /* Pack record out of leaf */ if(idx < leaf->nrec) - HDmemmove(H5B2_LEAF_NREC(leaf, shared, idx), H5B2_LEAF_NREC(leaf, shared, (idx + 1)), shared->type->nrec_size * (leaf->nrec-idx)); + HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx), H5B2_LEAF_NREC(leaf, hdr, (idx + 1)), hdr->cls->nrec_size * (leaf->nrec - idx)); } /* end if */ else { /* Let the cache know that the object is deleted */ @@ -2590,7 +2319,7 @@ H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, done: /* Release the B-tree leaf node */ - if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0) + if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, leaf_addr, leaf, leaf_flags) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -2612,7 +2341,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased, void *swap_loc, unsigned depth, H5AC_info_t *parent_cache_info, unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr, hsize_t n, H5B2_remove_t op, @@ -2624,7 +2353,6 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, H5B2_internal_t *internal; /* Pointer to internal node */ unsigned internal_flags = H5AC__NO_FLAGS_SET; haddr_t internal_addr; /* Address of internal node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ size_t merge_nrec; /* Number of records to merge node at */ hbool_t collapsed_root = FALSE; /* Whether the root was collapsed */ herr_t ret_value = SUCCEED; @@ -2632,36 +2360,30 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, FUNC_ENTER_NOAPI_NOINIT(H5B2_remove_internal_by_idx) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(depth > 0); HDassert(parent_cache_info); - HDassert(parent_cache_info_flags_ptr); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); /* Lock current B-tree node */ internal_addr = curr_node_ptr->addr; - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, internal_addr, curr_node_ptr->node_nrec, depth, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") HDassert(internal->nrec == curr_node_ptr->node_nrec); - - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - HDassert(depth == shared->depth || internal->nrec > 1); + HDassert(depth == hdr->depth || internal->nrec > 1); /* Determine the correct number of records to merge at */ - merge_nrec = shared->node_info[depth - 1].merge_nrec; + merge_nrec = hdr->node_info[depth - 1].merge_nrec; /* Check for needing to collapse the root node */ /* (The root node is the only internal node allowed to have 1 record) */ if(internal->nrec == 1 && ((internal->node_ptrs[0].node_nrec + internal->node_ptrs[1].node_nrec) <= ((merge_nrec * 2) + 1))) { - HDassert(depth == shared->depth); + HDassert(depth == hdr->depth); /* Merge children of root node */ - if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, 0) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") @@ -2740,22 +2462,22 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, */ if(idx == 0) { /* Left-most child */ if(retries > 0 && (internal->node_ptrs[idx + 1].node_nrec > merge_nrec)) { - if(H5B2_redistribute2(f, dxpl_id, depth, internal, idx) < 0) + if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") } /* end else */ } /* end if */ else if(idx == internal->nrec) { /* Right-most child */ if(retries > 0 && (internal->node_ptrs[idx - 1].node_nrec > merge_nrec)) { - if(H5B2_redistribute2(f, dxpl_id, depth, internal, (idx - 1)) < 0) + if(H5B2_redistribute2(hdr, dxpl_id, depth, internal, (idx - 1)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_merge2(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge2(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, (idx - 1)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") } /* end else */ @@ -2763,11 +2485,11 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, else { /* Middle child */ if(retries > 0 && ((internal->node_ptrs[idx + 1].node_nrec > merge_nrec) || (internal->node_ptrs[idx - 1].node_nrec > merge_nrec))) { - if(H5B2_redistribute3(f, dxpl_id, depth, internal, &internal_flags, idx) < 0) + if(H5B2_redistribute3(hdr, dxpl_id, depth, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTREDISTRIBUTE, FAIL, "unable to redistribute child node records") } /* end if */ else { - if(H5B2_merge3(f, dxpl_id, depth, curr_node_ptr, + if(H5B2_merge3(hdr, dxpl_id, depth, curr_node_ptr, parent_cache_info_flags_ptr, internal, &internal_flags, idx) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to merge child node") } /* end else */ @@ -2818,11 +2540,11 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Handle deleting a record from an internal node */ if(!swap_loc && found) - swap_loc = H5B2_INT_NREC(internal, shared, idx - 1); + swap_loc = H5B2_INT_NREC(internal, hdr, idx - 1); /* Swap record to delete with record from leaf, if we are the last internal node */ if(swap_loc && depth == 1) - if(H5B2_swap_leaf(f, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0) + if(H5B2_swap_leaf(hdr, dxpl_id, depth, internal, &internal_flags, idx, swap_loc) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSWAP, FAIL, "can't swap records in B-tree") /* Set pointers for advancing to child node */ @@ -2833,12 +2555,12 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Attempt to remove record from child node */ if(depth > 1) { - if(H5B2_remove_internal_by_idx(f, dxpl_id, bt2_shared, depth_decreased, swap_loc, depth - 1, + if(H5B2_remove_internal_by_idx(hdr, dxpl_id, depth_decreased, swap_loc, depth - 1, new_cache_info, new_cache_info_flags_ptr, new_node_ptr, n, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node") } /* end if */ else { - if(H5B2_remove_leaf_by_idx(f, dxpl_id, bt2_shared, new_node_ptr, (unsigned)n, op, op_data) < 0) + if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, new_node_ptr, (unsigned)n, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node") } /* end else */ @@ -2850,12 +2572,12 @@ H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, internal_flags |= H5AC__DIRTIED_FLAG; #ifdef H5B2_DEBUG - H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec-1) : new_node_ptr->all_nrec),shared,internal); + H5B2_assert_internal((!collapsed_root ? (curr_node_ptr->all_nrec - 1) : new_node_ptr->all_nrec), hdr, internal); #endif /* H5B2_DEBUG */ done: /* Release the B-tree internal node */ - if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0) + if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, internal_addr, internal, internal_flags) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -2889,36 +2611,29 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc, - H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data) +H5B2_neighbor_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, + void *neighbor_loc, H5B2_compare_t comp, void *udata, H5B2_found_t op, + void *op_data) { H5B2_leaf_t *leaf; /* Pointer to leaf node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ unsigned idx; /* Location of record which matches key */ - int cmp=0; /* Comparison value of records */ + int cmp = 0; /* Comparison value of records */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_neighbor_leaf) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); HDassert(op); /* Lock current B-tree node */ - if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), bt2_shared, H5AC_READ))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, &(curr_node_ptr->node_nrec), hdr, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - - /* Locate node pointer for child */ - cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx); if(cmp > 0) idx++; else @@ -2928,19 +2643,19 @@ H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, /* Set the neighbor location, if appropriate */ if(comp == H5B2_COMPARE_LESS) { if(idx > 0) - neighbor_loc = H5B2_LEAF_NREC(leaf,shared,idx-1); + neighbor_loc = H5B2_LEAF_NREC(leaf, hdr, idx - 1); } /* end if */ else { HDassert(comp == H5B2_COMPARE_GREATER); if(idx < leaf->nrec) - neighbor_loc = H5B2_LEAF_NREC(leaf,shared,idx); + neighbor_loc = H5B2_LEAF_NREC(leaf, hdr, idx); } /* end else */ /* Make callback if neighbor record has been found */ if(neighbor_loc) { /* Make callback for current record */ - if ((op)(neighbor_loc, op_data) < 0) + if((op)(neighbor_loc, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree neighbor operation") } /* end if */ else @@ -2948,7 +2663,7 @@ H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, done: /* Release the B-tree internal node */ - if (leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree leaf node") FUNC_LEAVE_NOAPI(ret_value) @@ -2982,64 +2697,58 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_neighbor_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - unsigned depth, H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc, - H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data) +H5B2_neighbor_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, + H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc, H5B2_compare_t comp, + void *udata, H5B2_found_t op, void *op_data) { H5B2_internal_t *internal; /* Pointer to internal node */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ unsigned idx; /* Location of record which matches key */ - int cmp=0; /* Comparison value of records */ + int cmp = 0; /* Comparison value of records */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_neighbor_internal) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); - HDassert(depth>0); + HDassert(hdr); + HDassert(depth > 0); HDassert(curr_node_ptr); HDassert(H5F_addr_defined(curr_node_ptr->addr)); HDassert(op); /* Lock current B-tree node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_READ))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr->addr, curr_node_ptr->node_nrec, depth, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Locate node pointer for child */ - cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); if(cmp > 0) idx++; /* Set the neighbor location, if appropriate */ if(comp == H5B2_COMPARE_LESS) { if(idx > 0) - neighbor_loc = H5B2_INT_NREC(internal,shared,idx-1); + neighbor_loc = H5B2_INT_NREC(internal, hdr, idx - 1); } /* end if */ else { HDassert(comp == H5B2_COMPARE_GREATER); if(idx < internal->nrec) - neighbor_loc = H5B2_INT_NREC(internal,shared,idx); + neighbor_loc = H5B2_INT_NREC(internal, hdr, idx); } /* end else */ /* Attempt to find neighboring record */ - if(depth>1) { - if(H5B2_neighbor_internal(f, dxpl_id, bt2_shared, depth-1, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0) + if(depth > 1) { + if(H5B2_neighbor_internal(hdr, dxpl_id, depth - 1, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree internal node") } /* end if */ else { - if(H5B2_neighbor_leaf(f, dxpl_id, bt2_shared, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0) + if(H5B2_neighbor_leaf(hdr, dxpl_id, &internal->node_ptrs[idx], neighbor_loc, comp, udata, op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree leaf node") } /* end else */ done: /* Release the B-tree internal node */ - if (internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -3061,32 +2770,26 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, +H5B2_delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, const H5B2_node_ptr_t *curr_node, H5B2_remove_t op, void *op_data) { - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - const H5AC_class_t *curr_node_class=NULL; /* Pointer to current node's class info */ - void *node=NULL; /* Pointers to current node */ + const H5AC_class_t *curr_node_class = NULL; /* Pointer to current node's class info */ + void *node = NULL; /* Pointers to current node */ uint8_t *native; /* Pointers to node's native records */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B2_delete_node) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(curr_node); - /* Get the pointer to the shared B-tree info */ - shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - - if(depth>0) { + if(depth > 0) { H5B2_internal_t *internal; /* Pointer to internal node */ unsigned u; /* Local index */ /* Lock the current B-tree node */ - if (NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node->addr, curr_node->node_nrec, depth, H5AC_WRITE))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node->addr, curr_node->node_nrec, depth, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Set up information about current node */ @@ -3095,15 +2798,15 @@ H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, native = internal->int_native; /* Descend into children */ - for(u=0; u<internal->nrec+1; u++) - if(H5B2_delete_node(f, dxpl_id, bt2_shared, depth-1, &(internal->node_ptrs[u]), op, op_data) < 0) + for(u = 0; u < internal->nrec + 1; u++) + if(H5B2_delete_node(hdr, dxpl_id, depth - 1, &(internal->node_ptrs[u]), op, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node descent failed") } /* end if */ else { H5B2_leaf_t *leaf; /* Pointer to leaf node */ /* Lock the current B-tree node */ - if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), bt2_shared, H5AC_WRITE))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node->addr, &(curr_node->node_nrec), hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree leaf node") /* Set up information about current node */ @@ -3119,14 +2822,14 @@ H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, /* Iterate through records in this node */ for(u = 0; u < curr_node->node_nrec; u++) { /* Make callback for each record */ - if((op)(H5B2_NAT_NREC(native, shared, u), op_data) < 0) + if((op)(H5B2_NAT_NREC(native, hdr, u), op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "iterator function failed") } /* end for */ } /* end if */ done: /* Unlock & delete current node */ - if(node && H5AC_unprotect(f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + if(node && H5AC_unprotect(hdr->f, dxpl_id, curr_node_class, curr_node->addr, node, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") FUNC_LEAVE_NOAPI(ret_value) @@ -3134,7 +2837,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5B2_iterate_size_node + * Function: H5B2_node_size * * Purpose: Iterate over all the records from a B-tree node, collecting * btree storage info. @@ -3147,28 +2850,22 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_iterate_size_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned depth, +H5B2_node_size(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, const H5B2_node_ptr_t *curr_node, hsize_t *btree_size) { - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ H5B2_internal_t *internal = NULL; /* Pointer to internal node */ herr_t ret_value = SUCCEED; /* Iterator return value */ - FUNC_ENTER_NOAPI(H5B2_iterate_size_node, FAIL) + FUNC_ENTER_NOAPI(H5B2_node_size, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(bt2_shared); + HDassert(hdr); HDassert(curr_node); HDassert(btree_size); HDassert(depth > 0); - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); - /* Lock the current B-tree node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node->addr, curr_node->node_nrec, depth, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Recursively descend into child nodes, if we are above the "twig" level in the B-tree */ @@ -3177,21 +2874,21 @@ H5B2_iterate_size_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, unsigned dep /* Descend into children */ for(u = 0; u < internal->nrec + 1; u++) - if(H5B2_iterate_size_node(f, dxpl_id, bt2_shared, (depth - 1), &(internal->node_ptrs[u]), btree_size) < 0) + if(H5B2_node_size(hdr, dxpl_id, (depth - 1), &(internal->node_ptrs[u]), btree_size) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node iteration failed") } /* end if */ else /* depth is 1: count all the leaf nodes from this node */ - *btree_size += (internal->nrec + 1) * shared->node_size; + *btree_size += (internal->nrec + 1) * hdr->node_size; /* Count this node */ - *btree_size += shared->node_size; + *btree_size += hdr->node_size; done: - if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node->addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node->addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") FUNC_LEAVE_NOAPI(ret_value) -} /* H5B2_iterate_size_node() */ +} /* H5B2_node_size() */ #ifdef H5B2_DEBUG @@ -3209,10 +2906,10 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_assert_leaf(H5B2_shared_t *shared, H5B2_leaf_t *leaf) +H5B2_assert_leaf(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf) { /* General sanity checking on node */ - HDassert(leaf->nrec<=shared->node_info->split_nrec); + HDassert(leaf->nrec <= hdr->node_info->split_nrec); return(0); } /* end H5B2_assert_leaf() */ @@ -3232,10 +2929,10 @@ H5B2_assert_leaf(H5B2_shared_t *shared, H5B2_leaf_t *leaf) *------------------------------------------------------------------------- */ static herr_t -H5B2_assert_leaf2(H5B2_shared_t *shared, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2) +H5B2_assert_leaf2(H5B2_hdr_t *hdr, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2) { /* General sanity checking on node */ - HDassert(leaf->nrec<=shared->node_info->split_nrec); + HDassert(leaf->nrec <= hdr->node_info->split_nrec); return(0); } /* end H5B2_assert_leaf() */ @@ -3255,27 +2952,27 @@ H5B2_assert_leaf2(H5B2_shared_t *shared, H5B2_leaf_t *leaf, H5B2_leaf_t *leaf2) *------------------------------------------------------------------------- */ static herr_t -H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal) +H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal) { hsize_t tot_all_nrec; /* Total number of records at or below this node */ - unsigned u,v; /* Local index variables */ + unsigned u, v; /* Local index variables */ /* General sanity checking on node */ - HDassert(internal->nrec<=shared->node_info->split_nrec); + HDassert(internal->nrec <= hdr->node_info->split_nrec); /* Sanity checking on node pointers */ - tot_all_nrec=internal->nrec; - for(u=0; u<internal->nrec+1; u++) { + tot_all_nrec = internal->nrec; + for(u = 0; u < internal->nrec + 1; u++) { tot_all_nrec += internal->node_ptrs[u].all_nrec; HDassert(H5F_addr_defined(internal->node_ptrs[u].addr)); - HDassert(internal->node_ptrs[u].addr>0); - for(v=0; v<u; v++) - HDassert(internal->node_ptrs[u].addr!=internal->node_ptrs[v].addr); + HDassert(internal->node_ptrs[u].addr > 0); + for(v = 0; v < u; v++) + HDassert(internal->node_ptrs[u].addr != internal->node_ptrs[v].addr); } /* end for */ /* Sanity check all_nrec total in parent */ - if(parent_all_nrec>0) + if(parent_all_nrec > 0) HDassert(tot_all_nrec == parent_all_nrec); return(0); @@ -3296,29 +2993,29 @@ H5B2_assert_internal(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_intern *------------------------------------------------------------------------- */ static herr_t -H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_shared_t *shared, H5B2_internal_t *internal, H5B2_internal_t *internal2) +H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_hdr_t *hdr, H5B2_internal_t *internal, H5B2_internal_t *internal2) { hsize_t tot_all_nrec; /* Total number of records at or below this node */ - unsigned u,v; /* Local index variables */ + unsigned u, v; /* Local index variables */ /* General sanity checking on node */ - HDassert(internal->nrec<=shared->node_info->split_nrec); + HDassert(internal->nrec <= hdr->node_info->split_nrec); /* Sanity checking on node pointers */ - tot_all_nrec=internal->nrec; - for(u=0; u<internal->nrec+1; u++) { + tot_all_nrec =internal->nrec; + for(u =0; u < internal->nrec + 1; u++) { tot_all_nrec += internal->node_ptrs[u].all_nrec; HDassert(H5F_addr_defined(internal->node_ptrs[u].addr)); - HDassert(internal->node_ptrs[u].addr>0); - for(v=0; v<u; v++) - HDassert(internal->node_ptrs[u].addr!=internal->node_ptrs[v].addr); - for(v=0; v<internal2->nrec+1; v++) - HDassert(internal->node_ptrs[u].addr!=internal2->node_ptrs[v].addr); + HDassert(internal->node_ptrs[u].addr > 0); + for(v = 0; v < u; v++) + HDassert(internal->node_ptrs[u].addr != internal->node_ptrs[v].addr); + for(v = 0; v < internal2->nrec + 1; v++) + HDassert(internal->node_ptrs[u].addr != internal2->node_ptrs[v].addr); } /* end for */ /* Sanity check all_nrec total in parent */ - if(parent_all_nrec>0) + if(parent_all_nrec > 0) HDassert(tot_all_nrec == parent_all_nrec); return(0); diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index c5af54f..8b68d1e 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -34,24 +34,28 @@ /* Other private headers needed by this file */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5RCprivate.h" /* Reference counted object functions */ + /**************************/ /* Package Private Macros */ /**************************/ /* Size of storage for number of records per node (on disk) */ -#define H5B2_SIZEOF_RECORDS_PER_NODE 2 +#define H5B2_SIZEOF_RECORDS_PER_NODE (unsigned)2 /* Size of a "tree pointer" (on disk) */ /* (essentially, the largest internal pointer allowed) */ -#define H5B2_TREE_POINTER_SIZE(f) (H5F_SIZEOF_ADDR(f)+H5B2_SIZEOF_RECORDS_PER_NODE+H5F_SIZEOF_SIZE(f)) +#define H5B2_TREE_POINTER_SIZE(h) ( \ + (h)->sizeof_addr + \ + H5B2_SIZEOF_RECORDS_PER_NODE + \ + (h)->sizeof_size \ + ) /* Size of a internal node pointer (on disk) */ -#define H5B2_INT_POINTER_SIZE(f, s, d) ( \ - H5F_SIZEOF_ADDR(f) /* Address of child node */ \ - + (s)->max_nrec_size /* # of records in child node */ \ - + (s)->node_info[(d) - 1].cum_max_nrec_size /* Total # of records in child & below */ \ +#define H5B2_INT_POINTER_SIZE(h, d) ( \ + (h)->sizeof_addr /* Address of child node */ \ + + (h)->max_nrec_size /* # of records in child node */ \ + + (h)->node_info[(d) - 1].cum_max_nrec_size /* Total # of records in child & below */ \ ) /* Size of checksum information (on disk) */ @@ -59,24 +63,24 @@ /* Format overhead for all v2 B-tree metadata in the file */ #define H5B2_METADATA_PREFIX_SIZE ( \ - H5_SIZEOF_MAGIC /* Signature */ \ - + 1 /* Version */ \ - + 1 /* Tree type */ \ - + H5B2_SIZEOF_CHKSUM /* Metadata checksum */ \ + (unsigned)H5_SIZEOF_MAGIC /* Signature */ \ + + (unsigned)1 /* Version */ \ + + (unsigned)1 /* Tree type */ \ + + (unsigned)H5B2_SIZEOF_CHKSUM /* Metadata checksum */ \ ) /* Size of the v2 B-tree header on disk */ -#define H5B2_HEADER_SIZE(f) ( \ +#define H5B2_HEADER_SIZE(h) ( \ /* General metadata fields */ \ H5B2_METADATA_PREFIX_SIZE \ \ /* Header specific fields */ \ - + 4 /* Node size, in bytes */ \ - + 2 /* Record size, in bytes */ \ - + 2 /* Depth of tree */ \ - + 1 /* Split % of full (as integer, ie. "98" means 98%) */ \ - + 1 /* Merge % of full (as integer, ie. "98" means 98%) */ \ - + H5B2_TREE_POINTER_SIZE(f) /* Node pointer to root node in tree */ \ + + (unsigned)4 /* Node size, in bytes */ \ + + (unsigned)2 /* Record size, in bytes */ \ + + (unsigned)2 /* Depth of tree */ \ + + (unsigned)1 /* Split % of full (as integer, ie. "98" means 98%) */ \ + + (unsigned)1 /* Merge % of full (as integer, ie. "98" means 98%) */ \ + + H5B2_TREE_POINTER_SIZE(h) /* Node pointer to root node in tree */ \ ) /* Size of the v2 B-tree internal node prefix */ @@ -98,13 +102,18 @@ ) /* Macro to retrieve pointer to i'th native record for native record buffer */ -#define H5B2_NAT_NREC(b, shared, idx) ((b) + (shared)->nat_off[(idx)]) +#define H5B2_NAT_NREC(b, hdr, idx) ((b) + (hdr)->nat_off[(idx)]) /* Macro to retrieve pointer to i'th native record for internal node */ -#define H5B2_INT_NREC(i, shared, idx) H5B2_NAT_NREC((i)->int_native, (shared), (idx)) +#define H5B2_INT_NREC(i, hdr, idx) H5B2_NAT_NREC((i)->int_native, (hdr), (idx)) /* Macro to retrieve pointer to i'th native record for leaf node */ -#define H5B2_LEAF_NREC(l, shared, idx) H5B2_NAT_NREC((l)->leaf_native, (shared), (idx)) +#define H5B2_LEAF_NREC(l, hdr, idx) H5B2_NAT_NREC((l)->leaf_native, (hdr), (idx)) + +/* Number of records that fit into internal node */ +/* (accounts for extra node pointer by counting it in with the prefix bytes) */ +#define H5B2_NUM_INT_REC(h, d) \ + (((h)->node_size - (H5B2_INT_PREFIX_SIZE + H5B2_INT_POINTER_SIZE(h, d))) / ((h)->rrec_size + H5B2_INT_POINTER_SIZE(h, d))) /****************************/ @@ -114,7 +123,7 @@ /* A "node pointer" to another B-tree node */ typedef struct { haddr_t addr; /* Address of other node */ - unsigned node_nrec; /* Number of records used in node pointed to */ + uint16_t node_nrec; /* Number of records used in node pointed to */ hsize_t all_nrec; /* Number of records in node pointed to and all it's children */ } H5B2_node_ptr_t; @@ -129,38 +138,41 @@ typedef struct { H5FL_fac_head_t *node_ptr_fac; /* Factory for node pointer blocks */ } H5B2_node_info_t; -/* Each B-tree has certain information that can be shared across all - * the instances of nodes in that B-tree. - */ -typedef struct H5B2_shared_t { - /* Shared internal data structures */ - const H5B2_class_t *type; /* Type of tree */ - uint8_t *page; /* Common disk page for I/O */ - size_t *nat_off; /* Array of offsets of native records */ - H5B2_node_info_t *node_info; /* Table of node info structs for current depth of B-tree */ +/* The B-tree header information */ +typedef struct H5B2_hdr_t { + /* Information for H5AC cache functions, _must_ be first field in structure */ + H5AC_info_t cache_info; + + /* Internal B-tree information (stored) */ + H5B2_node_ptr_t root; /* Node pointer to root node in B-tree */ /* Information set by user (stored) */ - unsigned split_percent; /* Percent full at which to split the node, when inserting */ - unsigned merge_percent; /* Percent full at which to merge the node, when deleting */ - size_t node_size; /* Size of B-tree nodes, in bytes */ - size_t rrec_size; /* Size of "raw" (on disk) record, in bytes */ + uint8_t split_percent; /* Percent full at which to split the node, when inserting */ + uint8_t merge_percent; /* Percent full at which to merge the node, when deleting */ + uint32_t node_size; /* Size of B-tree nodes, in bytes */ + uint32_t rrec_size; /* Size of "raw" (on disk) record, in bytes */ /* Dynamic information (stored) */ - unsigned depth; /* B-tree's overall depth */ + uint16_t depth; /* B-tree's overall depth */ - /* Derived information from user's information */ + /* Derived information from user's information (not stored) */ uint8_t max_nrec_size; /* Size to store max. # of records in any node (in bytes) */ -} H5B2_shared_t; - -/* The B-tree information */ -typedef struct H5B2_t { - /* Information for H5AC cache functions, _must_ be first field in structure */ - H5AC_info_t cache_info; - /* Internal B-tree information */ - H5B2_node_ptr_t root; /* Node pointer to root node in B-tree */ - H5RC_t *shared; /* Ref-counted shared info */ -} H5B2_t; + /* Shared internal data structures (not stored) */ + H5F_t *f; /* Pointer to the file that the B-tree is in */ + haddr_t addr; /* Address of B-tree header in the file */ + size_t rc; /* Reference count of nodes using this header */ + size_t file_rc; /* Reference count of files using this header */ + hbool_t pending_delete; /* B-tree is pending deletion */ + uint8_t sizeof_size; /* Size of file sizes */ + uint8_t sizeof_addr; /* Size of file addresses */ + H5B2_remove_t remove_op; /* Callback operator for deleting B-tree */ + void *remove_op_data;/* B-tree deletion callback's context */ + const H5B2_class_t *cls; /* Class of B-tree client */ + uint8_t *page; /* Common disk page for I/O */ + size_t *nat_off; /* Array of offsets of native records */ + H5B2_node_info_t *node_info; /* Table of node info structs for current depth of B-tree */ +} H5B2_hdr_t; /* B-tree leaf node information */ typedef struct H5B2_leaf_t { @@ -168,9 +180,9 @@ typedef struct H5B2_leaf_t { H5AC_info_t cache_info; /* Internal B-tree information */ - H5RC_t *shared; /* Ref-counted shared info */ + H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */ uint8_t *leaf_native; /* Pointer to native records */ - unsigned nrec; /* Number of records in node */ + uint16_t nrec; /* Number of records in node */ } H5B2_leaf_t; /* B-tree internal node information */ @@ -179,18 +191,24 @@ typedef struct H5B2_internal_t { H5AC_info_t cache_info; /* Internal B-tree information */ - H5RC_t *shared; /* Ref-counted shared info */ + H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */ uint8_t *int_native; /* Pointer to native records */ H5B2_node_ptr_t *node_ptrs; /* Pointer to node pointers */ - unsigned nrec; /* Number of records in node */ - unsigned depth; /* Depth of this node in the B-tree */ + uint16_t nrec; /* Number of records in node */ + uint16_t depth; /* Depth of this node in the B-tree */ } H5B2_internal_t; +/* v2 B-tree */ +struct H5B2_t { + H5B2_hdr_t *hdr; /* Pointer to internal v2 B-tree header info */ + H5F_t *f; /* Pointer to file for v2 B-tree */ +}; + /* User data for metadata cache 'load' callback */ typedef struct { - H5RC_t *bt2_shared; /* Ref counter for shared B-tree info */ - unsigned nrec; /* Number of records in node to load */ - unsigned depth; /* Depth of node to load */ + H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */ + uint16_t nrec; /* Number of records in node to load */ + uint16_t depth; /* Depth of node to load */ } H5B2_int_load_ud1_t; #ifdef H5B2_TESTING @@ -215,9 +233,6 @@ H5_DLLVAR const H5AC_class_t H5AC_BT2_INT[1]; /* H5B2 leaf node inherits cache-like properties from H5AC */ H5_DLLVAR const H5AC_class_t H5AC_BT2_LEAF[1]; -/* Declare a free list to manage the H5B2_t struct */ -H5FL_EXTERN(H5B2_t); - /* Declare a free list to manage the H5B2_internal_t struct */ H5FL_EXTERN(H5B2_internal_t); @@ -229,74 +244,82 @@ H5FL_EXTERN(H5B2_leaf_t); H5_DLLVAR const H5B2_class_t H5B2_TEST[1]; #endif /* H5B2_TESTING */ +/* Array of v2 B-tree client ID -> client class mappings */ +extern const H5B2_class_t *const H5B2_client_class_g[]; + /******************************/ /* Package Private Prototypes */ /******************************/ -/* Routines for managing shared B-tree info */ -H5_DLL herr_t H5B2_shared_init(H5F_t *f, H5B2_t *bt2, const H5B2_class_t *type, - unsigned depth, size_t node_size, size_t rrec_size, - unsigned split_percent, unsigned merge_percent); +/* Routines for managing B-tree header info */ +H5_DLL H5B2_hdr_t *H5B2_hdr_alloc(H5F_t *f); +H5_DLL haddr_t H5B2_hdr_create(H5F_t *f, hid_t dxpl_id, + const H5B2_create_t *cparam); +H5_DLL herr_t H5B2_hdr_init(H5F_t *f, H5B2_hdr_t *hdr, + const H5B2_create_t *cparam, uint16_t depth); +H5_DLL herr_t H5B2_hdr_incr(H5B2_hdr_t *hdr); +H5_DLL herr_t H5B2_hdr_decr(H5B2_hdr_t *hdr); +H5_DLL herr_t H5B2_hdr_fuse_incr(H5B2_hdr_t *hdr); +H5_DLL size_t H5B2_hdr_fuse_decr(H5B2_hdr_t *hdr); +H5_DLL herr_t H5B2_hdr_dirty(H5B2_hdr_t *hdr); +H5_DLL herr_t H5B2_hdr_free(H5B2_hdr_t *hdr); +H5_DLL herr_t H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id); /* Routines for operating on internal nodes */ -H5_DLL H5B2_internal_t *H5B2_protect_internal(H5F_t *f, hid_t dxpl_id, - H5RC_t *bt2_shared, haddr_t addr, unsigned nrec, unsigned depth, - H5AC_protect_t rw); +H5_DLL H5B2_internal_t *H5B2_protect_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, + haddr_t addr, unsigned nrec, unsigned depth, H5AC_protect_t rw); /* Routines for allocating nodes */ -H5_DLL herr_t H5B2_split_root(H5F_t *f, hid_t dxpl_id, H5B2_t *bt2, - unsigned *bt2_flags_ptr); -H5_DLL herr_t H5B2_create_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +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, H5B2_node_ptr_t *node_ptr); /* Routines for inserting records */ -H5_DLL herr_t H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +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(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +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 */ -H5_DLL herr_t H5B2_iterate_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - unsigned depth, const H5B2_node_ptr_t *curr_node, H5B2_operator_t op, - void *op_data); -H5_DLL herr_t H5B2_iterate_size_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5_DLL herr_t H5B2_iterate_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, + const H5B2_node_ptr_t *curr_node, H5B2_operator_t op, void *op_data); +H5_DLL herr_t H5B2_node_size(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, const H5B2_node_ptr_t *curr_node, hsize_t *op_data); /* Routines for locating records */ H5_DLL int H5B2_locate_record(const H5B2_class_t *type, unsigned nrec, size_t *rec_off, const uint8_t *native, const void *udata, unsigned *idx); -H5_DLL herr_t H5B2_neighbor_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5_DLL herr_t H5B2_neighbor_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc, H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data); -H5_DLL herr_t H5B2_neighbor_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5_DLL herr_t H5B2_neighbor_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, void *neighbor_loc, H5B2_compare_t comp, void *udata, H5B2_found_t op, void *op_data); /* Routines for removing records */ -H5_DLL herr_t H5B2_remove_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5_DLL herr_t H5B2_remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased, void *swap_loc, unsigned depth, H5AC_info_t *parent_cache_info, hbool_t * parent_cache_info_dirtied_ptr, H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op, void *op_data); -H5_DLL herr_t H5B2_remove_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5_DLL herr_t H5B2_remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, void *udata, H5B2_remove_t op, void *op_data); -H5_DLL herr_t H5B2_remove_internal_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5_DLL herr_t H5B2_remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased, void *swap_loc, unsigned depth, H5AC_info_t *parent_cache_info, hbool_t * parent_cache_info_dirtied_ptr, H5B2_node_ptr_t *curr_node_ptr, hsize_t idx, H5B2_remove_t op, void *op_data); -H5_DLL herr_t H5B2_remove_leaf_by_idx(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, +H5_DLL herr_t H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr, unsigned idx, H5B2_remove_t op, void *op_data); /* Routines for deleting nodes */ -H5_DLL herr_t H5B2_delete_node(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared, - unsigned depth, const H5B2_node_ptr_t *curr_node, H5B2_remove_t op, - void *op_data); +H5_DLL herr_t H5B2_delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, + const H5B2_node_ptr_t *curr_node, H5B2_remove_t op, void *op_data); /* Metadata cache callbacks */ -H5_DLL herr_t H5B2_cache_hdr_dest(H5F_t *f, H5B2_t *b); +H5_DLL herr_t H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *b); H5_DLL herr_t H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *l); H5_DLL herr_t H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *i); @@ -312,13 +335,10 @@ H5_DLL herr_t H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, /* Testing routines */ #ifdef H5B2_TESTING -H5_DLL herr_t H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, - const H5B2_class_t *type, haddr_t addr, haddr_t *root_addr); -H5_DLL int H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, - const H5B2_class_t *type, haddr_t addr, void *udata); -H5_DLL herr_t H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, - const H5B2_class_t *type, haddr_t addr, void *udata, - H5B2_node_info_test_t *ninfo); +H5_DLL herr_t H5B2_get_root_addr_test(H5B2_t *bt2, haddr_t *root_addr); +H5_DLL int H5B2_get_node_depth_test(H5B2_t *bt2, hid_t dxpl_id, void *udata); +H5_DLL herr_t H5B2_get_node_info_test(H5B2_t *bt2, hid_t dxpl_id, + void *udata, H5B2_node_info_test_t *ninfo); #endif /* H5B2_TESTING */ #endif /* _H5B2pkg_H */ diff --git a/src/H5B2private.h b/src/H5B2private.h index 0a516d2..cfdf868 100644 --- a/src/H5B2private.h +++ b/src/H5B2private.h @@ -82,6 +82,7 @@ typedef enum H5B2_compare_t { typedef struct H5B2_class_t H5B2_class_t; struct H5B2_class_t { H5B2_subid_t id; /* ID of B-tree class, as found in file */ + const char *name; /* Name of B-tree class, for debugging */ size_t nrec_size; /* Size of native (memory) record */ /* Store record from application to B-tree 'native' form */ @@ -100,52 +101,60 @@ struct H5B2_class_t { const void *udata); }; +/* v2 B-tree creation parameters */ +typedef struct H5B2_create_t { + const H5B2_class_t *cls; /* v2 B-tree client class */ + uint32_t node_size; /* Size of each node (in bytes) */ + uint32_t rrec_size; /* Size of raw record (in bytes) */ + uint8_t split_percent; /* % full to split nodes */ + uint8_t merge_percent; /* % full to merge nodes */ +} H5B2_create_t; + /* v2 B-tree metadata statistics info */ typedef struct H5B2_stat_t { unsigned depth; /* Depth of B-tree */ hsize_t nrecords; /* Number of records */ } H5B2_stat_t; +/* v2 B-tree info (forward decl - defined in H5B2pkg.h) */ +typedef struct H5B2_t H5B2_t; + + /*****************************/ /* Library-private Variables */ /*****************************/ + /***************************************/ /* Library-private Function Prototypes */ /***************************************/ -H5_DLL herr_t H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - size_t node_size, size_t rrec_size, - unsigned split_percent, unsigned merge_percent, - haddr_t *addr_p); -H5_DLL herr_t H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, void *udata); -H5_DLL herr_t H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5B2_operator_t op, void *op_data); -H5_DLL herr_t H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, hsize_t *op_data); -H5_DLL htri_t H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, void *udata, H5B2_found_t op, void *op_data); -H5_DLL herr_t H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_found_t op, - void *op_data); -H5_DLL herr_t H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5B2_compare_t comp, void *udata, H5B2_found_t op, - void *op_data); -H5_DLL herr_t H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, void *udata, H5B2_modify_t op, void *op_data); -H5_DLL herr_t H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, void *udata, H5B2_remove_t op, void *op_data); -H5_DLL herr_t H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_remove_t op, +H5_DLL H5B2_t *H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam); +H5_DLL H5B2_t *H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr); +H5_DLL herr_t H5B2_get_addr(const H5B2_t *bt2, haddr_t *addr/*out*/); +H5_DLL herr_t H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata); +H5_DLL herr_t H5B2_iterate(H5B2_t *bt2, hid_t dxpl_id, H5B2_operator_t op, void *op_data); -H5_DLL herr_t H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, hsize_t *nrec); -H5_DLL herr_t H5B2_delete(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5B2_remove_t op, void *op_data); +H5_DLL htri_t H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, + H5B2_found_t op, void *op_data); +H5_DLL herr_t H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, + hsize_t idx, H5B2_found_t op, void *op_data); +H5_DLL herr_t H5B2_neighbor(H5B2_t *bt2, hid_t dxpl_id, H5B2_compare_t range, + void *udata, H5B2_found_t op, void *op_data); +H5_DLL herr_t H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, + H5B2_modify_t op, void *op_data); +H5_DLL herr_t H5B2_remove(H5B2_t *b2, hid_t dxpl_id, void *udata, + H5B2_remove_t op, void *op_data); +H5_DLL herr_t H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, + H5_iter_order_t order, hsize_t idx, H5B2_remove_t op, void *op_data); +H5_DLL herr_t H5B2_get_nrec(const H5B2_t *bt2, hsize_t *nrec); +H5_DLL herr_t H5B2_size(H5B2_t *bt2, hid_t dxpl_id, + hsize_t *btree_size); +H5_DLL herr_t H5B2_close(H5B2_t *bt2, hid_t dxpl_id); +H5_DLL herr_t H5B2_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr, + H5B2_remove_t op, void *op_data); /* Statistics routines */ -H5_DLL herr_t H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5B2_stat_t *info); +H5_DLL herr_t H5B2_stat_info(H5B2_t *bt2, H5B2_stat_t *info); #endif /* _H5B2private_H */ diff --git a/src/H5B2stat.c b/src/H5B2stat.c index 899bb8a..0ee404e 100644 --- a/src/H5B2stat.c +++ b/src/H5B2stat.c @@ -26,6 +26,7 @@ #define H5B2_PACKAGE /*suppress error about including H5B2pkg */ + /***********/ /* Headers */ /***********/ @@ -33,6 +34,7 @@ #include "H5B2pkg.h" /* v2 B-trees */ #include "H5Eprivate.h" /* Error handling */ + /****************/ /* Local Macros */ /****************/ @@ -74,7 +76,6 @@ * Purpose: Retrieve metadata statistics for a v2 B-tree * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol @@ -83,37 +84,75 @@ *------------------------------------------------------------------------- */ herr_t -H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5B2_stat_t *info) +H5B2_stat_info(H5B2_t *bt2, H5B2_stat_t *info) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ - FUNC_ENTER_NOAPI_NOINIT(H5B2_stat_info) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_stat_info) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); HDassert(info); - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get pointer to reference counted shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Get information about the B-tree */ - info->depth = shared->depth; - info->nrecords = bt2->root.all_nrec; + info->depth = hdr->depth; + info->nrecords = hdr->root.all_nrec; -done: - /* Release B-tree header node */ - if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5B2_stat_info() */ + +/*------------------------------------------------------------------------- + * Function: H5B2_size + * + * Purpose: Iterate over all the records in the B-tree, collecting + * storage info. + * + * Return: non-negative on success, negative on error + * + * Programmer: Vailin Choi + * June 19 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_size(H5B2_t *bt2, hid_t dxpl_id, hsize_t *btree_size) +{ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5B2_size, FAIL) + + /* Check arguments. */ + HDassert(bt2); + HDassert(btree_size); + + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; + + /* Get the v2 B-tree header */ + hdr = bt2->hdr; + + /* Add size of header to B-tree metadata total */ + *btree_size += H5B2_HEADER_SIZE(hdr); + + /* Iterate through records */ + if(hdr->root.node_nrec > 0) { + /* Check for root node being a leaf */ + if(hdr->depth == 0) + *btree_size += hdr->node_size; + else + /* Iterate through nodes */ + if(H5B2_node_size(hdr, dxpl_id, hdr->depth, &hdr->root, btree_size) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node iteration failed") + } /* end if */ + +done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5B2_stat_info() */ +} /* H5B2_size() */ diff --git a/src/H5B2test.c b/src/H5B2test.c index 3fa5d27..863c886 100644 --- a/src/H5B2test.c +++ b/src/H5B2test.c @@ -20,6 +20,7 @@ * */ + /****************/ /* Module Setup */ /****************/ @@ -27,6 +28,7 @@ #define H5B2_PACKAGE /*suppress error about including H5B2pkg */ #define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/ + /***********/ /* Headers */ /***********/ @@ -34,6 +36,7 @@ #include "H5B2pkg.h" /* v2 B-trees */ #include "H5Eprivate.h" /* Error handling */ + /****************/ /* Local Macros */ /****************/ @@ -52,6 +55,7 @@ /********************/ /* Local Prototypes */ /********************/ + static herr_t H5B2_test_store(void *nrecord, const void *udata); static herr_t H5B2_test_compare(const void *rec1, const void *rec2); static herr_t H5B2_test_encode(const H5F_t *f, uint8_t *raw, @@ -61,11 +65,14 @@ static herr_t H5B2_test_decode(const H5F_t *f, const uint8_t *raw, static herr_t H5B2_test_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, int indent, int fwidth, const void *record, const void *_udata); + /*********************/ /* Package Variables */ /*********************/ + const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */ H5B2_TEST_ID, /* Type of B-tree */ + "H5B2_TEST_ID", /* Name of B-tree class */ sizeof(hsize_t), /* Size of native record */ H5B2_test_store, /* Record storage callback */ H5B2_test_compare, /* Record comparison callback */ @@ -74,6 +81,7 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */ H5B2_test_debug /* Record debugging callback */ }}; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -83,6 +91,7 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */ /* Local Variables */ /*******************/ + /*------------------------------------------------------------------------- * Function: H5B2_test_store @@ -128,7 +137,7 @@ H5B2_test_compare(const void *rec1, const void *rec2) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_test_compare) - FUNC_LEAVE_NOAPI((herr_t)(*(const hssize_t *)rec1-*(const hssize_t *)rec2)) + FUNC_LEAVE_NOAPI((herr_t)(*(const hssize_t *)rec1 - *(const hssize_t *)rec2)) } /* H5B2_test_compare() */ @@ -218,7 +227,6 @@ H5B2_test_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, * Purpose: Retrieve the root node's address * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol @@ -227,33 +235,18 @@ H5B2_test_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, *------------------------------------------------------------------------- */ herr_t -H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, haddr_t *root_addr) +H5B2_get_root_addr_test(H5B2_t *bt2, haddr_t *root_addr) { - H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5B2_get_root_addr_test) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_get_root_addr_test) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); HDassert(root_addr); - /* Look up the B-tree header */ - if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") - /* Get B-tree root addr */ - *root_addr = bt2->root.addr; + *root_addr = bt2->hdr->root.addr; -done: - /* Release B-tree header node */ - if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5B2_get_root_addr_test() */ @@ -271,13 +264,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - void *udata, H5B2_node_info_test_t *ninfo) +H5B2_get_node_info_test(H5B2_t *bt2, hid_t dxpl_id, void *udata, + H5B2_node_info_test_t *ninfo) { - H5B2_t *bt2=NULL; /* Pointer to the B-tree header */ - H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */ - H5B2_shared_t *shared; /* Pointer to B-tree's shared information */ - hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */ unsigned depth; /* Current depth of the tree */ int cmp; /* Comparison value of records */ @@ -287,36 +277,22 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr FUNC_ENTER_NOAPI(H5B2_get_node_info_test, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); - - /* Look up the B-tree header */ - if (NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") + HDassert(bt2); - /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */ - bt2_shared=bt2->shared; - H5RC_INC(bt2_shared); - incr_rc=TRUE; + /* Set the shared v2 B-tree header's file context for this operation */ + bt2->hdr->f = bt2->f; - /* Get the pointer to the shared B-tree info */ - shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared); - HDassert(shared); + /* Get the v2 B-tree header */ + hdr = bt2->hdr; /* Make copy of the root node pointer to start search with */ - curr_node_ptr = bt2->root; + curr_node_ptr = hdr->root; /* Current depth of the tree */ - depth = shared->depth; - - /* Release header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - bt2 = NULL; + depth = hdr->depth; /* Check for empty tree */ - if(curr_node_ptr.node_nrec==0) + if(0 == curr_node_ptr.node_nrec) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records") /* Walk down B-tree to find record or leaf node where record is located */ @@ -326,11 +302,11 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */ /* Lock B-tree current node */ - if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ))) + if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Locate node pointer for child */ - cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx); if(cmp > 0) idx++; @@ -339,7 +315,7 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr next_node_ptr = internal->node_ptrs[idx]; /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Set pointer to next node to load */ @@ -347,7 +323,7 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr } /* end if */ else { /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Fill in information about the node */ @@ -366,14 +342,14 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */ /* Lock B-tree leaf node */ - if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ))) + if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node") /* Locate record */ - cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx); + cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx); /* Unlock current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Indicate the depth that the record was found */ @@ -386,10 +362,6 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr ninfo->nrec = curr_node_ptr.node_nrec; done: - /* Check if we need to decrement the reference count for the B-tree's shared info */ - if(incr_rc) - H5RC_DEC(bt2_shared); - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_get_node_info_test() */ @@ -411,8 +383,7 @@ done: *------------------------------------------------------------------------- */ int -H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - void *udata) +H5B2_get_node_depth_test(H5B2_t *bt2, hid_t dxpl_id, void *udata) { H5B2_node_info_test_t ninfo; /* Node information */ int ret_value; /* Return information */ @@ -420,12 +391,10 @@ H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, hadd FUNC_ENTER_NOAPI(H5B2_get_node_depth_test, FAIL) /* Check arguments. */ - HDassert(f); - HDassert(type); - HDassert(H5F_addr_defined(addr)); + HDassert(bt2); /* Get information abou the node */ - if(H5B2_get_node_info_test(f, dxpl_id, type, addr, udata, &ninfo) < 0) + if(H5B2_get_node_info_test(bt2, dxpl_id, udata, &ninfo) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "error looking up node info") /* Set return value */ diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index 9676ab2..2c13677 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -1043,7 +1043,7 @@ H5D_btree_idx_iterate_cb(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5D_chunk_rec_t chunk_rec; /* Generic chunk record for callback */ int ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_iterate_cb) + FUNC_ENTER_NOAPI_NOINIT_NOERR(H5D_btree_idx_iterate_cb) /* Sanity check for memcpy() */ HDcompile_assert(offsetof(H5D_chunk_rec_t, nbytes) == offsetof(H5D_btree_key_t, nbytes)); @@ -1085,7 +1085,7 @@ H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info, H5D_btree_it_ud_t udata; /* User data for B-tree iterator callback */ int ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_iterate) + FUNC_ENTER_NOAPI_NOINIT_NOERR(H5D_btree_idx_iterate) HDassert(idx_info); HDassert(idx_info->f); @@ -1463,6 +1463,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 */ 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 */ @@ -1478,8 +1479,13 @@ H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") shared_init = TRUE; + /* Set up user data for callback */ + udata.layout = NULL; + udata.storage = &storage; + udata.offset = NULL; + /* Dump the records for the B-tree */ - (void)H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_BTREE, &ndims); + (void)H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_BTREE, &udata); done: if(shared_init) { diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index f05b3ce..5b1703a 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -4317,7 +4317,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) /* Convert from source file to memory */ H5_CHECK_OVERFLOW(udata->nelmts, uint32_t, size_t); - if(H5T_convert(tpath_src_mem, tid_src, tid_mem, (size_t)udata->nelmts, (size_t)0, (size_t)0, buf, NULL, udata->idx_info_dst->dxpl_id) < 0) + if(H5T_convert(tpath_src_mem, tid_src, tid_mem, (size_t)udata->nelmts, (size_t)0, (size_t)0, buf, bkg, udata->idx_info_dst->dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "datatype conversion failed") /* Copy into another buffer, to reclaim memory later */ diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index a3ce68a..f66e955 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -494,15 +494,19 @@ H5D_compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src, H5F_t *f_dst, HDmemcpy(buf, storage_src->buf, storage_src->size); + /* allocate temporary bkg buff for data conversion */ + if(NULL == (bkg = H5FL_BLK_MALLOC(type_conv, buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + /* Convert from source file to memory */ - if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0) + if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") + /* Copy into another buffer, to reclaim memory later */ HDmemcpy(reclaim_buf, buf, buf_size); - /* allocate temporary bkg buff for data conversion */ - if(NULL == (bkg = H5FL_BLK_CALLOC(type_conv, buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + /* Set background buffer to all zeros */ + HDmemset(bkg, 0, buf_size); /* Convert from memory to destination file */ if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0) diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 0ff3964..3e88be6 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -1396,7 +1396,7 @@ H5D_contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, /* Perform datatype conversion, if necessary */ if(is_vlen) { /* Convert from source file to memory */ - if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0) + if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") /* Copy into another buffer, to reclaim memory later */ diff --git a/src/H5Dearray.c b/src/H5Dearray.c index 55c0a8f..2215951 100644 --- a/src/H5Dearray.c +++ b/src/H5Dearray.c @@ -727,7 +727,6 @@ done: static herr_t H5D_earray_idx_open(const H5D_chk_idx_info_t *idx_info) { - const H5EA_class_t *cls; /* Extensible array class to use */ H5D_earray_ctx_ud_t udata; /* User data for extensible array open call */ herr_t ret_value = SUCCEED; /* Return value */ @@ -749,8 +748,7 @@ H5D_earray_idx_open(const H5D_chk_idx_info_t *idx_info) udata.chunk_size = idx_info->layout->size; /* Open the extensible array for the chunk index */ - cls = (idx_info->pline->nused > 0) ? H5EA_CLS_FILT_CHUNK : H5EA_CLS_CHUNK; - if(NULL == (idx_info->storage->u.earray.ea = H5EA_open(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr, cls, &udata))) + if(NULL == (idx_info->storage->u.earray.ea = H5EA_open(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr, &udata))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open extensible array") /* Check for SWMR writes to the file */ @@ -1528,6 +1526,7 @@ H5D_earray_idx_delete(const H5D_chk_idx_info_t *idx_info) /* Check if the index data structure has been allocated */ if(H5F_addr_defined(idx_info->storage->idx_addr)) { H5D_earray_ud_t udata; /* User data for callback */ + H5D_earray_ctx_ud_t ctx_udata; /* User data for extensible array open call */ /* Initialize user data for callback */ udata.f = idx_info->f; @@ -1542,8 +1541,12 @@ H5D_earray_idx_delete(const H5D_chk_idx_info_t *idx_info) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close extensible array") idx_info->storage->u.earray.ea = NULL; + /* Set up the context user data */ + ctx_udata.f = idx_info->f; + ctx_udata.chunk_size = idx_info->layout->size; + /* Delete extensible array */ - if(H5EA_delete(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr) < 0) + if(H5EA_delete(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr, &ctx_udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk extensible array") idx_info->storage->idx_addr = HADDR_UNDEF; } /* end if */ diff --git a/src/H5Defl.c b/src/H5Defl.c index 7ce0c67..8b2da6a 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -32,6 +32,7 @@ #include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ +#include "H5HLprivate.h" /* Local Heaps */ /****************/ @@ -50,7 +51,6 @@ /* Layout operation callbacks */ static herr_t H5D_efl_construct(H5F_t *f, H5D_t *dset); -static hbool_t H5D_efl_is_space_alloc(const H5O_storage_t *storage); static herr_t H5D_efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *cm); @@ -181,7 +181,7 @@ done: * *------------------------------------------------------------------------- */ -static hbool_t +hbool_t H5D_efl_is_space_alloc(const H5O_storage_t UNUSED *storage) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_efl_is_space_alloc) @@ -556,3 +556,37 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_efl_writevv() */ + +/*------------------------------------------------------------------------- + * Function: H5D_efl_bh_size + * + * Purpose: Retrieve the amount of heap storage used for External File + * List message + * + * Return: Success: Non-negative + * Failure: negative + * + * Programmer: Vailin Choi; August 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, hsize_t *heap_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_efl_bh_info, FAIL) + + /* Check args */ + HDassert(f); + HDassert(efl); + HDassert(H5F_addr_defined(efl->heap_addr)); + HDassert(heap_size); + + /* Get the size of the local heap for EFL's file list */ + if(H5HL_heapsize(f, dxpl_id, efl->heap_addr, heap_size) < 0) + HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, FAIL, "unable to retrieve local heap info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_chunk_bh_info() */ diff --git a/src/H5Dfarray.c b/src/H5Dfarray.c index 7b0e8a7..a62ae7a 100644 --- a/src/H5Dfarray.c +++ b/src/H5Dfarray.c @@ -731,7 +731,6 @@ H5D_farray_filt_debug(FILE *stream, int indent, int fwidth, hsize_t idx, static herr_t H5D_farray_idx_open(const H5D_chk_idx_info_t *idx_info) { - const H5FA_class_t *cls; /* Fixed array class to use */ H5D_farray_ctx_ud_t udata; /* User data for fixed array open call */ herr_t ret_value = SUCCEED; /* Return value */ @@ -753,8 +752,7 @@ H5D_farray_idx_open(const H5D_chk_idx_info_t *idx_info) udata.chunk_size = idx_info->layout->size; /* Open the fixed array for the chunk index */ - cls = (idx_info->pline->nused > 0) ? H5FA_CLS_FILT_CHUNK : H5FA_CLS_CHUNK; - if(NULL == (idx_info->storage->u.farray.fa = H5FA_open(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr, cls, &udata))) + if(NULL == (idx_info->storage->u.farray.fa = H5FA_open(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr, &udata))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open fixed array") done: @@ -1390,6 +1388,7 @@ H5D_farray_idx_delete(const H5D_chk_idx_info_t *idx_info) if(H5F_addr_defined(idx_info->storage->idx_addr)) { H5FA_t *fa; /* Pointer to fixed array structure */ H5FA_stat_t fa_stat; /* Fixed array statistics */ + H5D_farray_ctx_ud_t ctx_udata; /* User data for fixed array open call */ /* Check if the fixed array is open yet */ if(NULL == idx_info->storage->u.farray.fa) { @@ -1425,8 +1424,12 @@ H5D_farray_idx_delete(const H5D_chk_idx_info_t *idx_info) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close fixed array") idx_info->storage->u.farray.fa = NULL; + /* Set up the user data */ + ctx_udata.f = idx_info->f; + ctx_udata.chunk_size = idx_info->layout->size; + /* Delete fixed array */ - if(H5FA_delete(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr) < 0) + if(H5FA_delete(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr, &ctx_udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk fixed array") idx_info->storage->idx_addr = HADDR_UNDEF; } /* end if */ diff --git a/src/H5Dint.c b/src/H5Dint.c index 8ad3736..85d421a 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -178,7 +178,7 @@ H5D_init_interface(void) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve external file list") if(H5P_get(def_dcpl, H5D_CRT_FILL_VALUE_NAME, &H5D_def_dset.dcpl_cache.fill) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value") - if(H5P_get(def_dcpl, H5D_CRT_DATA_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0) + if(H5P_get(def_dcpl, H5O_CRT_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter") /* Reset the "default DXPL cache" information */ @@ -978,7 +978,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, /* Retrieve the properties we need */ pline = &new_dset->shared->dcpl_cache.pline; - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, pline) < 0) + if(H5P_get(dc_plist, H5O_CRT_PIPELINE_NAME, pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter") layout = &new_dset->shared->layout; if(H5P_get(dc_plist, H5D_CRT_LAYOUT_NAME, layout) < 0) @@ -1009,7 +1009,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, /* Set the latest version of the layout, pline & fill messages, if requested */ if(H5F_USE_LATEST_FORMAT(file)) { /* Set the latest version for the I/O pipeline message */ - if(H5Z_set_latest_version(&new_dset->shared->dcpl_cache.pline) < 0) + if(H5O_pline_set_latest_version(&new_dset->shared->dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of I/O filter pipeline") /* Set the latest version for the fill value message */ diff --git a/src/H5Dio.c b/src/H5Dio.c index 463c56e..62d2177 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -159,7 +159,7 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, else if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - if(!buf && H5S_GET_SELECT_NPOINTS(file_space) != 0) + if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") /* If the buffer is nil, and 0 element is selected, make a fake buffer. @@ -251,7 +251,7 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, else if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - if(!buf && H5S_GET_SELECT_NPOINTS(file_space) != 0) + if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") /* If the buffer is nil, and 0 element is selected, make a fake buffer. @@ -312,7 +312,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, if(!mem_space) mem_space = file_space; if((snelmts = H5S_GET_SELECT_NPOINTS(mem_space)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dst dataspace has invalid selection") H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t); /* Fill the DXPL cache values for later use */ diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index 4453735..c0a4aa3 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -509,7 +509,7 @@ H5D_layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message") /* Set the I/O pipeline info in the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &dataset->shared->dcpl_cache.pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &dataset->shared->dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set pipeline") } /* end if */ diff --git a/src/H5Doh.c b/src/H5Doh.c index e1d9827..30f1829 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -53,6 +53,8 @@ static hid_t H5O_dset_open(const H5G_loc_t *obj_loc, hid_t lapl_id, static void *H5O_dset_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id); static H5O_loc_t *H5O_dset_get_oloc(hid_t obj_id); +static herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5_ih_info_t *bh_info); /*********************/ @@ -78,7 +80,8 @@ const H5O_obj_class_t H5O_OBJ_DATASET[1] = {{ H5O_dset_isa, /* "isa" message */ H5O_dset_open, /* open an object of this class */ H5O_dset_create, /* create an object of this class */ - H5O_dset_get_oloc /* get an object header location for an object */ + H5O_dset_get_oloc, /* get an object header location for an object */ + H5O_dset_bh_info /* get the index & heap info for an object */ }}; /* Declare a free list to manage the H5D_copy_file_ud_t struct */ @@ -152,8 +155,8 @@ H5O_dset_free_copy_file_udata(void *_udata) H5T_close(udata->src_dtype); /* Release copy of dataset's filter pipeline, if it was set */ - if(udata->src_pline) - H5O_msg_free(H5O_PLINE_ID, udata->src_pline); + if(udata->common.src_pline) + H5O_msg_free(H5O_PLINE_ID, udata->common.src_pline); /* Release copy of dataset's layout, if it was set */ if(udata->src_layout) @@ -362,13 +365,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +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 */ - herr_t ret_value = SUCCEED; /* Return value */ + htri_t exists; /* Flag if header message of interest exists */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_dset_bh_info, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5O_dset_bh_info) /* Sanity check */ HDassert(f); @@ -391,7 +395,6 @@ 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 */ - htri_t exists; /* Flag if header message of interest exists */ /* Check for I/O pipeline message */ if((exists = H5O_msg_exists_oh(oh, H5O_PLINE_ID)) < 0) @@ -407,6 +410,25 @@ 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_CANTGET, FAIL, "can't determine chunked dataset btree info") } /* end if */ + /* Check for External File List message in the object header */ + if((exists = H5O_msg_exists_oh(oh, H5O_EFL_ID)) < 0) + 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") + + /* 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) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine EFL heap info") + } /* end if */ + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_dset_bh_info() */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 6790212..4596b05 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -668,6 +668,11 @@ H5_DLL herr_t H5D_compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src, H5F_t *f_dst, H5O_storage_compact_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id); +/* Functions that operate on EFL (External File List)*/ +H5_DLL hbool_t H5D_efl_is_space_alloc(const H5O_storage_t *storage); +H5_DLL herr_t H5D_efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, + hsize_t *heap_size); + /* Functions that perform fill value operations on datasets */ H5_DLL herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id); diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 3f5e379..666f969 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -47,7 +47,6 @@ #define H5D_CRT_FILL_VALUE_NAME "fill_value" /* Fill value */ #define H5D_CRT_ALLOC_TIME_STATE_NAME "alloc_time_state" /* Space allocation time state */ #define H5D_CRT_EXT_FILE_LIST_NAME "efl" /* External file list */ -#define H5D_CRT_DATA_PIPELINE_NAME "pline" /* Data filter pipeline */ /* ======== Dataset access property names ======== */ #define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */ @@ -135,15 +134,15 @@ typedef struct H5D_dxpl_cache_t { /* Typedef for cached dataset creation property list information */ typedef struct H5D_dcpl_cache_t { H5O_fill_t fill; /* Fill value info (H5D_CRT_FILL_VALUE_NAME) */ - H5O_pline_t pline; /* I/O pipeline info (H5D_CRT_DATA_PIPELINE_NAME) */ + H5O_pline_t pline; /* I/O pipeline info (H5O_CRT_PIPELINE_NAME) */ H5O_efl_t efl; /* External file list info (H5D_CRT_EXT_FILE_LIST_NAME) */ } H5D_dcpl_cache_t; -/* Callback information for copying dataset */ +/* Callback information for copying datasets */ typedef struct H5D_copy_file_ud_t { + H5O_copy_file_ud_common_t common; /* Shared information (must be first) */ struct H5S_extent_t *src_space_extent; /* Copy of dataspace extent for dataset */ H5T_t *src_dtype; /* Copy of datatype for dataset */ - H5O_pline_t *src_pline; /* Copy of filter pipeline for dataset */ H5O_layout_t *src_layout; /* Copy of layout for dataset */ } H5D_copy_file_ud_t; @@ -79,9 +79,20 @@ typedef herr_t (*H5EA__unprotect_func_t)(void *thing, hid_t dxpl_id, /* Package Variables */ /*********************/ -/* HDF5 API Entered variable */ -/* (move to H5.c when new FUNC_ENTER macros in actual use -QAK) */ -hbool_t H5_api_entered_g = FALSE; +/* Extensible array client ID to class mapping */ + +/* Remember to add client ID to H5EA_cls_id_t in H5EAprivate.h when adding a new + * client class.. + */ +extern const H5EA_class_t H5EA_CLS_CHUNK[1]; +extern const H5EA_class_t H5EA_CLS_FILT_CHUNK[1]; +extern const H5EA_class_t H5EA_CLS_TEST[1]; + +const H5EA_class_t *const H5EA_client_class_g[] = { + H5EA_CLS_CHUNK, /* 0 - H5EA_CLS_CHUNK_ID */ + H5EA_CLS_FILT_CHUNK, /* 1 - H5EA_CLS_FILT_CHUNK_ID */ + H5EA_CLS_TEST, /* ? - H5EA_CLS_TEST_ID */ +}; /*****************************/ @@ -131,6 +142,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(f); HDassert(cparam); + /* H5EA interface sanity check */ + HDcompile_assert(H5EA_NUM_CLS_ID == NELMTS(H5EA_client_class_g)); + /* Create extensible array header */ if(HADDR_UNDEF == (ea_addr = H5EA__hdr_create(f, dxpl_id, cparam, ctx_udata))) H5E_THROW(H5E_CANTINIT, "can't create extensible array header") @@ -140,7 +154,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array info") /* Lock the array header into memory */ - if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cparam->cls, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header") /* Point extensible array wrapper at header and bump it's ref count */ @@ -185,8 +199,7 @@ END_FUNC(PRIV) /* end H5EA_create() */ */ BEGIN_FUNC(PRIV, ERR, H5EA_t *, NULL, NULL, -H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5EA_class_t *cls, - void *ctx_udata)) +H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata)) /* Local variables */ H5EA_t *ea = NULL; /* Pointer to new extensible array wrapper */ @@ -197,13 +210,12 @@ H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5EA_class_t *cls, */ HDassert(f); HDassert(H5F_addr_defined(ea_addr)); - HDassert(cls); /* Load the array header into memory */ #ifdef QAK HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr); #endif /* QAK */ - if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cls, ctx_udata, H5AC_READ))) + if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header, address = %llu", (unsigned long long)ea_addr) /* Check for pending array deletion */ @@ -1031,28 +1043,52 @@ HDfprintf(stderr, "%s: Called\n", FUNC); } /* end if */ } /* end if */ - /* Decrement the reference count on the array header */ - /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5EA__hdr_decr(ea->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - /* Check for pending array deletion */ if(pending_delete) { H5EA_hdr_t *hdr; /* Another pointer to extensible array header */ +#ifndef NDEBUG +{ + unsigned hdr_status = 0; /* Header's status in the metadata cache */ + + /* Check the header's status in the metadata cache */ + if(H5AC_get_entry_status(ea->f, ea_addr, &hdr_status) < 0) + H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for extensible array header") + + /* Sanity checks on header */ + HDassert(hdr_status & H5AC_ES__IN_CACHE); + HDassert(hdr_status & H5AC_ES__IS_PINNED); + HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED)); +} +#endif /* NDEBUG */ + /* Lock the array header into memory */ + /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(ea->f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE))) H5E_THROW(H5E_CANTLOAD, "unable to load extensible array header") /* Set the shared array header's file context for this operation */ hdr->f = ea->f; + /* Decrement the reference count on the array header */ + /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5EA__hdr_decr(ea->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + /* Delete array, starting with header (unprotects header) */ if(H5EA__hdr_delete(hdr, dxpl_id) < 0) H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array") } /* end if */ + else { + /* Decrement the reference count on the array header */ + /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5EA__hdr_decr(ea->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + } /* end else */ /* Release the extensible array wrapper */ ea = (H5EA_t *)H5FL_FREE(H5EA_t, ea); @@ -1077,7 +1113,7 @@ END_FUNC(PRIV) /* end H5EA_close() */ */ BEGIN_FUNC(PRIV, ERR, herr_t, SUCCEED, FAIL, -H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr)) +H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata)) /* Local variables */ H5EA_hdr_t *hdr = NULL; /* The fractal heap header information */ @@ -1092,7 +1128,7 @@ H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr)) #ifdef QAK HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr); #endif /* QAK */ - if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array header, address = %llu", (unsigned long long)ea_addr) /* Check for files using shared array header */ diff --git a/src/H5EAcache.c b/src/H5EAcache.c index a254e84..2e1c632 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -198,11 +198,11 @@ const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1] = {{ */ BEGIN_FUNC(STATIC, ERR, H5EA_hdr_t *, NULL, NULL, -H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, +H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *ctx_udata)) /* Local variables */ - const H5EA_class_t *cls = (const H5EA_class_t *)_cls; /* Extensible array class */ + H5EA_cls_id_t id; /* ID of extensible array class, as found in file */ H5EA_hdr_t *hdr = NULL; /* Extensible array info */ size_t size; /* Header size */ H5WB_t *wb = NULL; /* Wrapped buffer for header data */ @@ -217,7 +217,7 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, HDassert(H5F_addr_defined(addr)); /* Allocate space for the extensible array data structure */ - if(NULL == (hdr = H5EA__hdr_alloc(f, cls, ctx_udata))) + if(NULL == (hdr = H5EA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header") /* Set the extensible array header's address */ @@ -250,9 +250,11 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, if(*p++ != H5EA_HDR_VERSION) H5E_THROW(H5E_VERSION, "wrong extensible array header version") - /* Extensible array type */ - if(*p++ != (uint8_t)cls->id) + /* Extensible array class */ + id = *p++; + if(id >= H5EA_NUM_CLS_ID) H5E_THROW(H5E_BADTYPE, "incorrect extensible array class") + hdr->cparam.cls = H5EA_client_class_g[id]; /* General array creation/configuration information */ hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */ @@ -314,7 +316,7 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array header") /* Finish initializing extensible array header */ - if(H5EA__hdr_init(hdr) < 0) + if(H5EA__hdr_init(hdr, ctx_udata) < 0) H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header") HDassert(hdr->size == size); diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c index c8dd34d..4280767 100644 --- a/src/H5EAhdr.c +++ b/src/H5EAhdr.c @@ -118,14 +118,13 @@ H5FL_SEQ_DEFINE_STATIC(H5EA_sblk_info_t); */ BEGIN_FUNC(PKG, ERR, H5EA_hdr_t *, NULL, NULL, -H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, void *udata)) +H5EA__hdr_alloc(H5F_t *f)) /* Local variables */ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */ /* Check arguments */ HDassert(f); - HDassert(cls); /* Allocate space for the shared information */ if(NULL == (hdr = H5FL_CALLOC(H5EA_hdr_t))) @@ -140,13 +139,6 @@ H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, void *udata)) hdr->sizeof_addr = H5F_SIZEOF_ADDR(f); hdr->sizeof_size = H5F_SIZEOF_SIZE(f); - /* Set the class of the array */ - hdr->cparam.cls = cls; - - /* Create the callback context */ - if(NULL == (hdr->cb_ctx = (*cls->crt_context)(udata))) - H5E_THROW(H5E_CANTCREATE, "unable to create extensible array client callback context") - /* Set the return value */ ret_value = hdr; @@ -196,7 +188,7 @@ END_FUNC(PKG) /* end H5EA__hdr_alloc() */ */ BEGIN_FUNC(PKG, ERR, herr_t, SUCCEED, FAIL, -H5EA__hdr_init(H5EA_hdr_t *hdr)) +H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata)) /* Local variables */ hsize_t start_idx; /* First element index for each super block */ @@ -241,6 +233,12 @@ HDfprintf(stderr, "%s: hdr->sblk_info[%Zu] = {%Zu, %Zu, %Hu, %Hu}\n", FUNC, u, h /* Set size of header on disk (locally and in statistics) */ hdr->stats.computed.hdr_size = hdr->size = H5EA_HEADER_SIZE(hdr); + /* Create the callback context, if there's one */ + if(hdr->cparam.cls->crt_context) { + if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata))) + H5E_THROW(H5E_CANTCREATE, "unable to create extensible array client callback context") + } /* end if */ + CATCH END_FUNC(PKG) /* end H5EA__hdr_init() */ @@ -420,7 +418,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); #endif /* NDEBUG */ /* Allocate space for the shared information */ - if(NULL == (hdr = H5EA__hdr_alloc(f, cparam->cls, ctx_udata))) + if(NULL == (hdr = H5EA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header") /* Set the internal parameters for the array */ @@ -430,7 +428,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); /* Finish initializing extensible array header */ - if(H5EA__hdr_init(hdr) < 0) + if(H5EA__hdr_init(hdr, ctx_udata) < 0) H5E_THROW(H5E_CANTINIT, "initialization failed for extensible array header") /* Allocate space for the header on disk */ @@ -695,8 +693,10 @@ H5EA__hdr_dest(H5EA_hdr_t *hdr)) HDassert(hdr->rc == 0); /* Destroy the callback context */ - if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) - H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array client callback context") + if(hdr->cb_ctx) { + if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTRELEASE, "unable to destroy extensible array client callback context") + } /* end if */ hdr->cb_ctx = NULL; /* Check for data block element buffer factory info to free */ diff --git a/src/H5EApkg.h b/src/H5EApkg.h index 9b91bdb..f729b69 100644 --- a/src/H5EApkg.h +++ b/src/H5EApkg.h @@ -354,6 +354,9 @@ H5_DLLVAR const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1]; H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1]; #endif /* H5EA_TESTING */ +/* Array of extensible array client ID -> client class mappings */ +extern const H5EA_class_t *const H5EA_client_class_g[]; + /******************************/ /* Package Private Prototypes */ @@ -366,9 +369,8 @@ H5_DLL herr_t H5EA__destroy_flush_depend(H5EA_hdr_t *hdr, H5AC_info_t *parent_en H5AC_info_t *child_entry); /* Header routines */ -H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls, - void *ctx_udata); -H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr); +H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f); +H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata); H5_DLL haddr_t H5EA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udata); H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts); diff --git a/src/H5EAprivate.h b/src/H5EAprivate.h index 12074fe..06bdd55 100644 --- a/src/H5EAprivate.h +++ b/src/H5EAprivate.h @@ -52,6 +52,7 @@ typedef enum H5EA_cls_id_t { H5EA_CLS_CHUNK_ID = 0, /* Extensible array is for indexing dataset chunks w/o filters */ H5EA_CLS_FILT_CHUNK_ID, /* Extensible array is for indexing dataset chunks w/filters */ + /* Start real class IDs at 0 -QAK */ /* (keep these last) */ H5EA_CLS_TEST_ID, /* Extensible array is for testing (do not use for actual data) */ H5EA_NUM_CLS_ID /* Number of Extensible Array class IDs (must be last) */ @@ -124,8 +125,7 @@ typedef struct H5EA_t H5EA_t; /* General routines */ H5_DLL H5EA_t *H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udata); -H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, - const H5EA_class_t *cls, void *ctx_udata); +H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); H5_DLL herr_t H5EA_get_nelmts(const H5EA_t *ea, hsize_t *nelmts); H5_DLL herr_t H5EA_get_addr(const H5EA_t *ea, haddr_t *addr); H5_DLL herr_t H5EA_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt); @@ -137,7 +137,7 @@ H5_DLL herr_t H5EA_support(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, H5_DLL herr_t H5EA_unsupport(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, H5AC_info_t *child_entry); H5_DLL herr_t H5EA_close(H5EA_t *ea, hid_t dxpl_id); -H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr); +H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); /* Statistics routines */ H5_DLL herr_t H5EA_get_stats(const H5EA_t *ea, H5EA_stat_t *stats); diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h index 3ca05e7..4c226d0 100644 --- a/src/H5Eprivate.h +++ b/src/H5Eprivate.h @@ -32,14 +32,14 @@ typedef struct H5E_t H5E_t; * and a FUNC_LEAVE() within a function body. The arguments are the major * error number, the minor error number, and a description of the error. */ -#define HERROR(maj_id, min_id, str) H5E_push_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, str) +#define HERROR(maj_id, min_id, ...) H5E_printf_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, __VA_ARGS__) /* * HCOMMON_ERROR macro, used by HDONE_ERROR and HGOTO_ERROR * (Shouldn't need to be used outside this header file) */ -#define HCOMMON_ERROR(maj, min, str) \ - HERROR(maj, min, str); \ +#define HCOMMON_ERROR(maj, min, ...) \ + HERROR(maj, min, __VA_ARGS__); \ err_occurred = TRUE; /* @@ -51,8 +51,8 @@ typedef struct H5E_t H5E_t; * (This macro can also be used to push an error and set the return value * without jumping to any labels) */ -#define HDONE_ERROR(maj, min, ret_val, str) { \ - HCOMMON_ERROR(maj, min, str); \ +#define HDONE_ERROR(maj, min, ret_val, ...) { \ + HCOMMON_ERROR(maj, min, __VA_ARGS__); \ ret_value = ret_val; \ } @@ -63,8 +63,8 @@ typedef struct H5E_t H5E_t; * error string. The return value is assigned to a variable `ret_value' and * control branches to the `done' label. */ -#define HGOTO_ERROR(maj, min, ret_val, str) { \ - HCOMMON_ERROR(maj, min, str); \ +#define HGOTO_ERROR(maj, min, ret_val, ...) { \ + HCOMMON_ERROR(maj, min, __VA_ARGS__); \ HGOTO_DONE(ret_val) \ } @@ -84,16 +84,13 @@ typedef struct H5E_t H5E_t; /* Retrieve the error code description string and push it onto the error * stack. */ -#define HSYS_ERROR(errnum) { \ - HERROR(H5E_INTERNAL, H5E_SYSERRSTR, HDstrerror(errnum)); \ -} #define HSYS_DONE_ERROR(majorcode, minorcode, retcode, str) { \ - HSYS_ERROR(errno); \ - HDONE_ERROR(majorcode, minorcode, retcode, str); \ + int myerrno = errno; \ + HDONE_ERROR(majorcode, minorcode, retcode, "%s, errno = %d, error message = '%s'", str, myerrno, HDstrerror(myerrno)); \ } #define HSYS_GOTO_ERROR(majorcode, minorcode, retcode, str) { \ - HSYS_ERROR(errno); \ - HGOTO_ERROR(majorcode, minorcode, retcode, str); \ + int myerrno = errno; \ + HGOTO_ERROR(majorcode, minorcode, retcode, "%s, errno = %d, error message = '%s'", str, myerrno, HDstrerror(myerrno)); \ } #ifdef H5_HAVE_PARALLEL @@ -891,6 +891,10 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes") HDassert(f->shared->sohm_nindexes < 255); + if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &f->shared->fs_strategy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space strategy") + if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &f->shared->fs_threshold) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold") /* Get the FAPL values to cache */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) @@ -1025,9 +1029,11 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) * and also because releasing free space can shrink the file's * 'eoa' value) */ - if(H5MF_close(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") + if(H5F_ACC_RDWR & H5F_INTENT(f)) { + if(H5MF_close(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") + } /* end if */ /* Unpin the superblock, since we're about to destroy the cache */ if(H5AC_unpin_entry(f, f->shared->sblock) < 0) @@ -1084,7 +1090,7 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list") /* Only truncate the file on an orderly close, with write-access */ - if(f->closing && (H5F_ACC_RDWR & f->shared->flags)) { + if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) { /* Truncate the file to the current allocated size */ if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) /* Push error, but keep going*/ @@ -1629,7 +1635,7 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * calling H5Fflush() with the read-only handle, still causes data * to be flushed. */ - if(H5F_ACC_RDWR & f->shared->flags) { + if(H5F_ACC_RDWR & H5F_INTENT(f)) { /* Flush other files, depending on scope */ if(H5F_SCOPE_GLOBAL == scope) { /* Call the flush routine for mounted file hierarchies */ @@ -1907,7 +1913,7 @@ H5F_try_close(H5F_t *f) * 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) { + 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") @@ -2798,11 +2804,13 @@ done: /*------------------------------------------------------------------------- - * Function: H5Fget_info - * 1. Get storage size for superblock extension if there is one + * Function: H5Fget_info2 + * + * Purpose: Gets general information about the file, including: + * 1. Get storage size for superblock extension if there is one. * 2. Get the amount of btree and heap storage for entries * in the SOHM table if there is one. - * Consider success when there is no superblock extension and/or SOHM table + * 3. The amount of free space tracked in the file. * * Return: Success: non-negative on success * Failure: Negative @@ -2813,12 +2821,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_info(hid_t obj_id, H5F_info_t *finfo) +H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) { H5F_t *f; /* Top file in mount hierarchy */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Fget_info, FAIL) + FUNC_ENTER_API(H5Fget_info2, FAIL) H5TRACE2("e", "i*x", obj_id, finfo); /* Check args */ @@ -2844,18 +2852,67 @@ H5Fget_info(hid_t obj_id, H5F_info_t *finfo) HDassert(f->shared); /* Reset file info struct */ - HDmemset(finfo, 0, sizeof(H5F_info_t)); + HDmemset(finfo, 0, sizeof(*finfo)); + + /* Get the size of the superblock and any superblock extensions */ + if(H5F_super_size(f, H5AC_ind_dxpl_id, &finfo->super.super_size, &finfo->super.super_ext_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock sizes") - /* Check for superblock extension info */ - if(H5F_super_size(f, H5AC_ind_dxpl_id, NULL, &finfo->super_ext_size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock extension size") + /* Get the size of any persistent free space */ + if(H5MF_get_freespace(f, H5AC_ind_dxpl_id, &finfo->free.tot_space, &finfo->free.meta_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve free space information") /* Check for SOHM info */ if(H5F_addr_defined(f->shared->sohm_addr)) - if(H5SM_ih_size(f, H5AC_ind_dxpl_id, finfo) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM btree & heap storage info") + if(H5SM_ih_size(f, H5AC_ind_dxpl_id, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM index & heap storage info") + + /* Set version # fields */ + finfo->super.version = f->shared->sblock->super_vers; + finfo->sohm.version = f->shared->sohm_vers; + finfo->free.version = HDF5_FREESPACE_VERSION; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_info2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fget_free_sections + * + * Purpose: To get free-space section information for free-space manager with + * TYPE that is associated with file FILE_ID. + * If SECT_INFO is null, this routine returns the total # of free-space + * sections. + * + * Return: Success: non-negative, the total # of free space sections + * Failure: negative + * + * Programmer: Vailin Choi; July 1st, 2009 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, + H5F_sect_info_t *sect_info/*out*/) +{ + H5F_t *file; /* Top file in mount hierarchy */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Fget_free_sections, FAIL) + H5TRACE4("Zs", "iFmzx", file_id, type, nsects, sect_info); + + /* Check args */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + if(sect_info && nsects == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "nsects must be > 0") + + /* Go get the free-space section information in the file */ + if((ret_value = H5MF_get_free_sections(file, H5AC_ind_dxpl_id, type, nsects, sect_info)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") done: FUNC_LEAVE_API(ret_value) -} /* end H5Fget_info() */ +} /* end H5Fget_free_sections() */ @@ -70,6 +70,17 @@ /* Package Variables */ /*********************/ +/* Fixed array client ID to class mapping */ + +/* Remember to add client ID to H5FA_cls_id_t in H5FAprivate.h when adding a new + * client class.. + */ +const H5FA_class_t *const H5FA_client_class_g[] = { + H5FA_CLS_CHUNK, /* 0 - H5FA_CLS_CHUNK_ID */ + H5FA_CLS_FILT_CHUNK, /* 1 - H5FA_CLS_FILT_CHUNK_ID */ + H5FA_CLS_TEST, /* ? - H5FA_CLS_TEST_ID */ +}; + /*****************************/ /* Library Private Variables */ @@ -120,6 +131,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(f); HDassert(cparam); + /* H5FA interface sanity check */ + HDcompile_assert(H5FA_NUM_CLS_ID == NELMTS(H5FA_client_class_g)); + /* Create fixed array header */ if(HADDR_UNDEF == (fa_addr = H5FA__hdr_create(f, dxpl_id, cparam, ctx_udata))) H5E_THROW(H5E_CANTINIT, "can't create fixed array header") @@ -129,7 +143,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info") /* Lock the array header into memory */ - if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cparam->cls, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header") /* Point fixed array wrapper at header and bump it's ref count */ @@ -173,8 +187,7 @@ END_FUNC(PRIV) /* end H5FA_create() */ */ BEGIN_FUNC(PRIV, ERR, H5FA_t *, NULL, NULL, -H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, const H5FA_class_t *cls, - void *ctx_udata)) +H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata)) /* Local variables */ H5FA_t *fa = NULL; /* Pointer to new fixed array wrapper */ @@ -185,13 +198,12 @@ H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, const H5FA_class_t *cls, */ HDassert(f); HDassert(H5F_addr_defined(fa_addr)); - HDassert(cls); /* Load the array header into memory */ #ifdef H5FA_DEBUG HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr); #endif /* H5FA_DEBUG */ - if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cls, ctx_udata, H5AC_READ))) + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_READ))) H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header, address = %llu", (unsigned long long)fa_addr) /* Check for pending array deletion */ @@ -561,28 +573,52 @@ HDfprintf(stderr, "%s: Called\n", FUNC); } /* end if */ } /* end if */ - /* Decrement the reference count on the array header */ - /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5FA__hdr_decr(fa->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - /* Check for pending array deletion */ if(pending_delete) { H5FA_hdr_t *hdr; /* Another pointer to fixed array header */ +#ifndef NDEBUG +{ + unsigned hdr_status = 0; /* Header's status in the metadata cache */ + + /* Check the header's status in the metadata cache */ + if(H5AC_get_entry_status(fa->f, fa_addr, &hdr_status) < 0) + H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for fixed array header") + + /* Sanity checks on header */ + HDassert(hdr_status & H5AC_ES__IN_CACHE); + HDassert(hdr_status & H5AC_ES__IS_PINNED); + HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED)); +} +#endif /* NDEBUG */ + /* Lock the array header into memory */ + /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(fa->f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE))) H5E_THROW(H5E_CANTLOAD, "unable to load fixed array header") /* Set the shared array header's file context for this operation */ hdr->f = fa->f; + /* Decrement the reference count on the array header */ + /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5FA__hdr_decr(fa->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + /* Delete array, starting with header (unprotects header) */ if(H5FA__hdr_delete(hdr, dxpl_id) < 0) H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array") } /* end if */ + else { + /* Decrement the reference count on the array header */ + /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5FA__hdr_decr(fa->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + } /* end else */ /* Release the fixed array wrapper */ fa = H5FL_FREE(H5FA_t, fa); @@ -606,7 +642,7 @@ END_FUNC(PRIV) /* end H5FA_close() */ */ BEGIN_FUNC(PRIV, ERR, herr_t, SUCCEED, FAIL, -H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr)) +H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata)) /* Local variables */ H5FA_hdr_t *hdr = NULL; /* The fixed array header information */ @@ -621,7 +657,7 @@ H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr)) #ifdef H5FA_DEBUG HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr); #endif /* H5FA_DEBUG */ - if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE))) + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, ctx_udata, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array header, address = %llu", (unsigned long long)fa_addr) /* Check for files using shared array header */ diff --git a/src/H5FAcache.c b/src/H5FAcache.c index 59a81e2..3488531 100644 --- a/src/H5FAcache.c +++ b/src/H5FAcache.c @@ -158,11 +158,11 @@ const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1] = {{ */ BEGIN_FUNC(STATIC, ERR, H5FA_hdr_t *, NULL, NULL, -H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, +H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *ctx_udata)) /* Local variables */ - const H5FA_class_t *cls = (const H5FA_class_t *)_cls; /* Fixed array class */ + H5FA_cls_id_t id; /* ID of fixed array class, as found in file */ H5FA_hdr_t *hdr = NULL; /* Fixed array info */ size_t size; /* Header size */ H5WB_t *wb = NULL; /* Wrapped buffer for header data */ @@ -177,7 +177,7 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, HDassert(H5F_addr_defined(addr)); /* Allocate space for the fixed array data structure */ - if(NULL == (hdr = H5FA__hdr_alloc(f, cls, ctx_udata))) + if(NULL == (hdr = H5FA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array shared header") /* Set the fixed array header's address */ @@ -210,9 +210,11 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, if(*p++ != H5FA_HDR_VERSION) H5E_THROW(H5E_VERSION, "wrong fixed array header version") - /* Fixed array type */ - if(*p++ != (uint8_t)cls->id) + /* Fixed array class */ + id = *p++; + if(id >= H5FA_NUM_CLS_ID) H5E_THROW(H5E_BADTYPE, "incorrect fixed array class") + hdr->cparam.cls = H5FA_client_class_g[id]; /* General array creation/configuration information */ hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */ @@ -226,10 +228,6 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, /* Internal information */ H5F_addr_decode(f, &p, &hdr->dblk_addr); /* Address of index block */ - /* Initializations of header info */ - hdr->stats.nelmts = hdr->cparam.nelmts; - hdr->stats.hdr_size = hdr->size = size; /* Size of header in file */ - /* Check for data block */ if(H5F_addr_defined(hdr->dblk_addr)) { H5FA_dblock_t dblock; /* Fake data block for computing size */ @@ -267,6 +265,11 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, if(stored_chksum != computed_chksum) H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array header") + /* Finish initializing fixed array header */ + if(H5FA__hdr_init(hdr, ctx_udata) < 0) + H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header") + HDassert(hdr->size == size); + /* Set return value */ ret_value = hdr; diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c index e6231d4..94fb7b2 100644 --- a/src/H5FAhdr.c +++ b/src/H5FAhdr.c @@ -95,14 +95,13 @@ H5FL_DEFINE_STATIC(H5FA_hdr_t); */ BEGIN_FUNC(PKG, ERR, H5FA_hdr_t *, NULL, NULL, -H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *udata)) +H5FA__hdr_alloc(H5F_t *f)) /* Local variables */ H5FA_hdr_t *hdr = NULL; /* Shared Fixed Array header */ /* Check arguments */ HDassert(f); - HDassert(cls); /* Allocate space for the shared information */ if(NULL == (hdr = H5FL_CALLOC(H5FA_hdr_t))) @@ -116,13 +115,6 @@ H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *udata)) hdr->sizeof_addr = H5F_SIZEOF_ADDR(f); hdr->sizeof_size = H5F_SIZEOF_SIZE(f); - /* Set the class of the array */ - hdr->cparam.cls = cls; - - /* Create the callback context */ - if(NULL == (hdr->cb_ctx = (*cls->crt_context)(udata))) - H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context") - /* Set the return value */ ret_value = hdr; @@ -135,6 +127,44 @@ END_FUNC(PKG) /* end H5FA__hdr_alloc() */ /*------------------------------------------------------------------------- + * Function: H5FA__hdr_init + * + * Purpose: Initialize shared fixed array header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Sunday, November 15, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata)) + + /* Local variables */ + + /* Check arguments */ + HDassert(hdr); + + /* Set size of header on disk (locally and in statistics) */ + hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr); + + /* Set number of elements for Fixed Array in statistics */ + hdr->stats.nelmts = hdr->cparam.nelmts; + + /* Create the callback context, if there's one */ + if(hdr->cparam.cls->crt_context) { + if(NULL == (hdr->cb_ctx = (*hdr->cparam.cls->crt_context)(ctx_udata))) + H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context") + } /* end if */ + +CATCH + +END_FUNC(PKG) /* end H5FA__hdr_init() */ + + +/*------------------------------------------------------------------------- * Function: H5FA__hdr_create * * Purpose: Creates a new Fixed Array header in the file @@ -175,7 +205,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); #endif /* NDEBUG */ /* Allocate space for the shared information */ - if(NULL == (hdr = H5FA__hdr_alloc(f, cparam->cls, ctx_udata))) + if(NULL == (hdr = H5FA__hdr_alloc(f))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for Fixed Array shared header") hdr->dblk_addr = HADDR_UNDEF; @@ -183,11 +213,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Set the creation parameters for the array */ HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); - /* Set size of header on disk (locally and in statistics) */ - hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr); - - /* Set number of elements for Fixed Array in statistics */ - hdr->stats.nelmts = hdr->cparam.nelmts; + /* Finish initializing fixed array header */ + if(H5FA__hdr_init(hdr, ctx_udata) < 0) + H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header") /* Allocate space for the header on disk */ if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_FARRAY_HDR, dxpl_id, (hsize_t)hdr->size))) @@ -445,8 +473,10 @@ H5FA__hdr_dest(H5FA_hdr_t *hdr)) HDassert(hdr->rc == 0); /* Destroy the callback context */ - if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) - H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context") + if(hdr->cb_ctx) { + if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context") + } /* end if */ hdr->cb_ctx = NULL; /* Free the shared info itself */ diff --git a/src/H5FApkg.h b/src/H5FApkg.h index 1ba8f84..8e2a515 100644 --- a/src/H5FApkg.h +++ b/src/H5FApkg.h @@ -224,9 +224,10 @@ H5_DLLVAR const H5FA_class_t H5FA_CLS_CHUNK[1]; H5_DLLVAR const H5FA_class_t H5FA_CLS_FILT_CHUNK[1]; /* Internal fixed array testing class */ -#ifdef H5FA_TESTING H5_DLLVAR const H5FA_class_t H5FA_CLS_TEST[1]; -#endif /* H5FA_TESTING */ + +/* Array of fixed array client ID -> client class mappings */ +extern const H5FA_class_t *const H5FA_client_class_g[]; /******************************/ @@ -234,7 +235,8 @@ H5_DLLVAR const H5FA_class_t H5FA_CLS_TEST[1]; /******************************/ /* Header routines */ -H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *ctx_udata); +H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f); +H5_DLL herr_t H5FA__hdr_init(H5FA_hdr_t *hdr, void *ctx_udata); H5_DLL haddr_t H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata); H5_DLL void *H5FA__hdr_alloc_elmts(H5FA_hdr_t *hdr, size_t nelmts); H5_DLL herr_t H5FA__hdr_free_elmts(H5FA_hdr_t *hdr, size_t nelmts, void *elmts); diff --git a/src/H5FAprivate.h b/src/H5FAprivate.h index 16397fd..08e6e50 100644 --- a/src/H5FAprivate.h +++ b/src/H5FAprivate.h @@ -49,6 +49,7 @@ typedef enum H5FA_cls_id_t { H5FA_CLS_CHUNK_ID = 0, /* Fixed array is for indexing dataset chunks w/o filters */ H5FA_CLS_FILT_CHUNK_ID, /* Fixed array is for indexing dataset chunks w/filters */ + /* Start real class IDs at 0 -QAK */ /* (keep these last) */ H5FA_CLS_TEST_ID, /* Fixed array is for testing (do not use for actual data) */ H5FA_NUM_CLS_ID /* Number of Fixed Array class IDs (must be last) */ @@ -113,15 +114,14 @@ typedef int (*H5FA_operator_t)(hsize_t idx, const void *_elmt, void *_udata); /* General routines */ H5_DLL H5FA_t *H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata); -H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5FA_class_t *cls, - void *ctx_udata); +H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); H5_DLL herr_t H5FA_get_nelmts(const H5FA_t *ea, hsize_t *nelmts); H5_DLL herr_t H5FA_get_addr(const H5FA_t *ea, haddr_t *addr); H5_DLL herr_t H5FA_set(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt); H5_DLL herr_t H5FA_get(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt); -H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id); -H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr); H5_DLL herr_t H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata); +H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id); +H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata); /* Statistics routines */ H5_DLL herr_t H5FA_get_stats(const H5FA_t *ea, H5FA_stat_t *stats); diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 54f0d03..318839d 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -739,11 +739,11 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, /* Check for overflow conditions */ if(!H5F_addr_defined(addr)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr) if(REGION_OVERFLOW(addr, size)) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) if((addr + size) > file->eoa) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* Seek to the correct location */ if((addr != file->pos || OP_READ != file->op) && @@ -820,9 +820,9 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had /* Check for overflow conditions */ if(!H5F_addr_defined(addr)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr) if(REGION_OVERFLOW(addr, size)) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* If the file is open for SWMR read access, allow access to data past * the end of the allocated space (the 'eoa'). This is done because the * eoa stored in the file's superblock might be out of sync with the @@ -830,7 +830,7 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had * SWMR write operations. */ if(!file->swmr_read && (addr + size) > file->eoa) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* Seek to the correct location */ if((addr != file->pos || OP_WRITE != file->op) && @@ -477,9 +477,6 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC); if(fspace->serial_sect_count > 0) /* Sanity check that section info has address */ HDassert(H5F_addr_defined(fspace->sect_addr)); - else - /* Sanity check that section info doesn't have address */ - HDassert(!H5F_addr_defined(fspace->sect_addr)); } /* end else */ /* Decrement the reference count on the free space manager header */ @@ -723,6 +720,183 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS_dirty() */ + +/*------------------------------------------------------------------------- + * Function: H5FS_alloc_hdr() + * + * Purpose: Allocate space for the free-space manager header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_alloc_hdr(H5F_t *f, H5FS_t *fspace, haddr_t *fs_addr, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5FS_alloc_hdr, FAIL) + + /* Check arguments. */ + HDassert(f); + HDassert(fspace); + + if(!H5F_addr_defined(fspace->addr)) { + /* Allocate space for the free space header */ + if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for free space header") + + /* Cache the new free space header (pinned) */ + if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space header to cache") + } /* end if */ + + if(fs_addr) + *fs_addr = fspace->addr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5FS_alloc_hdr() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_alloc_sect() + * + * Purpose: Allocate space for the free-space manager section info header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_alloc_sect(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5FS_alloc_sect, FAIL) + + /* Check arguments. */ + HDassert(f); + HDassert(fspace); + + if(!H5F_addr_defined(fspace->sect_addr) && fspace->sinfo && fspace->serial_sect_count > 0) { + /* Allocate space for section info from aggregator/vfd */ + /* (The original version called H5MF_alloc(), but that may cause sect_size to change again) */ + if(HADDR_UNDEF == (fspace->sect_addr = H5MF_aggr_vfd_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size))) + HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info") + + fspace->alloc_sect_size = fspace->sect_size; + + /* Mark free-space header as dirty */ + if(H5FS_dirty(f, fspace) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") + + /* Cache the free-space section info */ + if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space sections to cache") + + fspace->sinfo = NULL; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5FS_alloc_sect() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_free() + * + * Purpose: Free space for free-space manager header and section info header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + haddr_t saved_addr; + hsize_t saved_size; + unsigned cache_flags; + unsigned sinfo_status = 0; + unsigned hdr_status = 0; + + FUNC_ENTER_NOAPI(H5FS_free, FAIL) + + /* Check arguments. */ + HDassert(f); + HDassert(fspace); + + cache_flags = H5AC__DELETED_FLAG | H5AC__TAKE_OWNERSHIP_FLAG;; + + if(H5F_addr_defined(fspace->sect_addr)) { + + /* Check whether free-space manager section info is in cache or not */ + if(H5AC_get_entry_status(f, fspace->sect_addr, &sinfo_status) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free-space section info") + + /* Load free-space manager section info */ + if(sinfo_status & H5AC_ES__IN_CACHE || !fspace->sinfo) { + if(NULL == (fspace->sinfo = (H5FS_sinfo_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, NULL, fspace, H5AC_READ))) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to load free space section info") + + /* Unload and release ownership of the free-space manager section info */ + if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, cache_flags) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space section info") + } + + saved_addr = fspace->sect_addr; + saved_size = fspace->alloc_sect_size; + + fspace->sect_addr = HADDR_UNDEF; + fspace->alloc_sect_size = 0; + + /* Free space for the free-space manager section info */ + if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, saved_addr, saved_size) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections") + + /* Mark free-space manager header as dirty */ + if(H5FS_dirty(f, fspace) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") + } + + if(H5F_addr_defined(fspace->addr)) { + /* 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(f, fspace) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap header") + + /* Load the free-space manager header */ + if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, NULL, fspace, H5AC_READ))) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to load free space section info") + + /* Unload and release ownership of the free-space header */ + if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, cache_flags) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space section info") + } + saved_addr = fspace->addr; + fspace->addr = HADDR_UNDEF; + + /* Free space for the free-space manager header */ + 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() */ + #ifdef H5FS_DEBUG_ASSERT /*------------------------------------------------------------------------- diff --git a/src/H5FScache.c b/src/H5FScache.c index a7978f5..482b9cb 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -334,10 +334,7 @@ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n" if(H5FS_cache_sinfo_flush(f, dxpl_id, FALSE, fspace->sect_addr, fspace->sinfo, NULL) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space section info to disk") } /* end if */ - else { - /* Sanity check that section info doesn't have address */ - HDassert(!H5F_addr_defined(fspace->sect_addr)); - } /* end else */ + #ifdef QAK HDfprintf(stderr, "%s: Check 2.0\n", FUNC); HDfprintf(stderr, "%s: fspace->sect_addr = %a, fspace->sinfo = %p\n", FUNC, fspace->sect_addr, fspace->sinfo); @@ -348,15 +345,9 @@ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n" fspace->sinfo->dirty = FALSE; } /* end if */ } /* end if */ - else { - /* Just sanity checks... */ - if(fspace->serial_sect_count > 0) - /* Sanity check that section info has address */ - HDassert(H5F_addr_defined(fspace->sect_addr)); - else - /* Sanity check that section info doesn't have address */ - HDassert(!H5F_addr_defined(fspace->sect_addr)); - } /* end else */ + else if(fspace->serial_sect_count > 0) + /* Sanity check that section info has address */ + HDassert(H5F_addr_defined(fspace->sect_addr)); if(fspace->cache_info.is_dirty) { uint8_t *hdr; /* Pointer to header buffer */ diff --git a/src/H5FSdbg.c b/src/H5FSdbg.c index df48240..8cf64ef 100644 --- a/src/H5FSdbg.c +++ b/src/H5FSdbg.c @@ -286,10 +286,8 @@ H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, FILE *stream, int break; case H5FS_CLIENT_FILE_ID: -#ifdef NOT_YET - if(H5MF_sects_debug(f, dxpl_id, fs_addr, stream, indent + 3, MAX(0, fwidth - 3)) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_SYSTEM, FAIL, "unable to dump file free space sections") -#endif /* NOT_YET */ + if(H5MF_sects_debug(f, dxpl_id, fs_addr, stream, indent + 3, MAX(0, fwidth - 3)) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_SYSTEM, FAIL, "unable to dump file free space sections") break; default: diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h index 056449d..145c374 100644 --- a/src/H5FSprivate.h +++ b/src/H5FSprivate.h @@ -180,10 +180,15 @@ H5_DLL H5FS_t *H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, H5_DLL herr_t H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size); H5_DLL herr_t H5FS_delete(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr); H5_DLL herr_t H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace); +H5_DLL herr_t H5FS_alloc_hdr(H5F_t *f, H5FS_t *fspace, haddr_t *fs_addr, hid_t dxpl_id); +H5_DLL herr_t H5FS_alloc_sect(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id); +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, + 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); H5_DLL herr_t H5FS_sect_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, diff --git a/src/H5FSsection.c b/src/H5FSsection.c index 26ff7b9..30885a9 100644 --- a/src/H5FSsection.c +++ b/src/H5FSsection.c @@ -1562,6 +1562,71 @@ done: /*------------------------------------------------------------------------- + * Function: H5FS_sect_try_merge + * + * Purpose: Try to merge/shrink a block + * + * Return: TRUE: merged/shrunk + * FALSE: not merged/not shrunk + * Failure: negative + * + * Programmer: Vailin Choi; June 10, 2009 + * + *------------------------------------------------------------------------- + */ +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) +{ + hbool_t sinfo_valid = FALSE; /* Whether the section info is valid */ + hbool_t sinfo_modified = FALSE; /* Whether the section info was modified */ + hsize_t saved_fs_size; /* copy the free-space section size */ + htri_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI(H5FS_sect_try_merge, FAIL) + + /* Check arguments. */ + HDassert(f); + HDassert(fspace); + HDassert(sect); + HDassert(H5F_addr_defined(sect->addr)); + HDassert(sect->size); + + /* Get a pointer to the section info */ + if(H5FS_sinfo_lock(f, dxpl_id, fspace, H5AC_WRITE) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get section info") + sinfo_valid = TRUE; + saved_fs_size = sect->size; + + /* Attempt to merge/shrink section with existing sections */ + if(H5FS_sect_merge(fspace, §, op_data) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't merge sections") + + /* Check if section is shrunk and/or merged away completely */ + if(!sect) { + sinfo_modified = TRUE; + HGOTO_DONE(TRUE) + } /* end if */ + else { + /* Check if section is merged */ + if(sect->size > saved_fs_size) { + if(H5FS_sect_link(fspace, sect, flags) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space section into skip list") + sinfo_modified = TRUE; + HGOTO_DONE(TRUE) + } /* end if */ + } /* end else */ + +done: + /* Release the section info */ + if(sinfo_valid && H5FS_sinfo_unlock(f, dxpl_id, fspace, sinfo_modified) < 0) + HDONE_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release section info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5FS_sect_try_merge() */ + + +/*------------------------------------------------------------------------- * Function: H5FS_sect_find_node * * Purpose: Locate a section of free space (in existing free space list diff --git a/src/H5FStest.c b/src/H5FStest.c index 719e553..af9eaec 100644 --- a/src/H5FStest.c +++ b/src/H5FStest.c @@ -69,7 +69,7 @@ /*------------------------------------------------------------------------- - * Function: H5HF_get_cparam_test + * Function: H5FS_get_cparam_test * * Purpose: Retrieve the parameters used to create the free-space manager * @@ -101,7 +101,7 @@ H5FS_get_cparam_test(const H5FS_t *frsp, H5FS_create_t *cparam) } /* H5FS_get_cparam_test() */ /*------------------------------------------------------------------------- - * Function: H5HF_cmp_cparam_test + * Function: H5FS_cmp_cparam_test * * Purpose: Compare the parameters used to create the fractal heap * diff --git a/src/H5Faccum.c b/src/H5Faccum.c index d8b9820..e525a08 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -99,6 +99,10 @@ H5FL_BLK_DEFINE_STATIC(meta_accum); * Purpose: Attempts to read some data from the metadata accumulator for * a file into a buffer. * + * Note: We can't change (or add to) the metadata accumulator, because + * this might be a speculative read and could possibly read raw + * data into the metadata accumulator. + * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol @@ -185,69 +189,11 @@ H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Make certain we've read it all */ HDassert(size == 0); } /* end if */ - /* Current read doesn't overlap with metadata accumulator, read it into accumulator */ + /* Current read doesn't overlap with metadata accumulator, read it from file */ else { - /* Only update the metadata accumulator if it is not dirty or if - * we are allowed to write the accumulator out during reads (when - * it is dirty) - */ - if(f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA_READ || !f->shared->accum.dirty) { - /* Flush current contents, if dirty */ - if(f->shared->accum.dirty) { - if(H5FD_write(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, f->shared->accum.loc, f->shared->accum.size, f->shared->accum.buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "driver write request failed") - - /* Reset accumulator dirty flag */ - f->shared->accum.dirty = FALSE; - } /* end if */ - - /* Cache the new piece of metadata */ - /* Check if we need to resize the buffer */ - if(size > f->shared->accum.alloc_size) { - size_t new_size; /* New size of accumulator */ - - /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ - new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); - - /* Grow the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") - - /* Note the new buffer size */ - f->shared->accum.alloc_size = new_size; - } /* end if */ - else { - /* Check if we should shrink the accumulator buffer */ - if(size < (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE) && - f->shared->accum.alloc_size > H5F_ACCUM_THRESHOLD) { - size_t new_size = (f->shared->accum.alloc_size / H5F_ACCUM_THROTTLE); /* New size of accumulator buffer */ - - /* Shrink the accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") - - /* Note the new buffer size */ - f->shared->accum.alloc_size = new_size; - } /* end if */ - } /* end else */ - - /* Update accumulator information */ - f->shared->accum.loc = addr; - f->shared->accum.size = size; - f->shared->accum.dirty = FALSE; - - /* Read into accumulator */ - if(H5FD_read(f->shared->lf, dxpl_id, H5FD_MEM_DEFAULT, f->shared->accum.loc, f->shared->accum.size, f->shared->accum.buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - - /* Copy into buffer */ - HDmemcpy(buf, f->shared->accum.buf, size); - } /* end if */ - else { - /* Dispatch to driver */ - if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") - } /* end else */ + /* Dispatch to driver */ + if(H5FD_read(f->shared->lf, dxpl_id, type, addr, size, buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "driver read request failed") } /* end else */ /* Indicate success */ diff --git a/src/H5Fdeprec.c b/src/H5Fdeprec.c new file mode 100644 index 0000000..7e1136c --- /dev/null +++ b/src/H5Fdeprec.c @@ -0,0 +1,173 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Fdeprec.c + * October 1 2009 + * Quincey Koziol <koziol@hdfgroup.org> + * + * Purpose: Deprecated functions from the H5F interface. These + * functions are here for compatibility purposes and may be + * removed in the future. Applications should switch to the + * newer APIs. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5F_init_deprec_interface + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5Iprivate.h" /* IDs */ +#include "H5SMprivate.h" /* Shared object header messages */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*-------------------------------------------------------------------------- +NAME + H5F_init_deprec_interface -- Initialize interface-specific information +USAGE + herr_t H5F_init_deprec_interface() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5F_init() currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5F_init_deprec_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_init_deprec_interface) + + FUNC_LEAVE_NOAPI(H5F_init()) +} /* H5F_init_deprec_interface() */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/*------------------------------------------------------------------------- + * Function: H5Fget_info1 + * + * Purpose: Gets general information about the file, including: + * 1. Get storage size for superblock extension if there is one. + * 2. Get the amount of btree and heap storage for entries + * in the SOHM table if there is one. + * 3. The amount of free space tracked in the file. + * + * Return: Success: non-negative on success + * Failure: Negative + * + * Programmer: Vailin Choi + * July 11, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo) +{ + H5F_t *f; /* Top file in mount hierarchy */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Fget_info1, FAIL) + H5TRACE2("e", "i*x", obj_id, finfo); + + /* Check args */ + if(!finfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") + + /* For file IDs, get the file object directly */ + /* (This prevents the H5G_loc() call from returning the file pointer for + * the top file in a mount hierarchy) + */ + if(H5I_get_type(obj_id) == H5I_FILE ) { + if(NULL == (f = (H5F_t *)H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + } /* end if */ + else { + H5G_loc_t loc; /* Object location */ + + /* Get symbol table entry */ + if(H5G_loc(obj_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID") + f = loc.oloc->file; + } /* end else */ + HDassert(f->shared); + + /* Reset file info struct */ + HDmemset(finfo, 0, sizeof(*finfo)); + + /* Get the size of the superblock extension */ + if(H5F_super_size(f, H5AC_ind_dxpl_id, NULL, &finfo->super_ext_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock extension size") + + /* Check for SOHM info */ + if(H5F_addr_defined(f->shared->sohm_addr)) + if(H5SM_ih_size(f, H5AC_ind_dxpl_id, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM index & heap storage info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_info1() */ + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 15946d4..e664ca8 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -69,7 +69,9 @@ #define H5F_FS_MERGE_RAWDATA 0x02 /* Section can merge with small 'raw' data aggregator */ /* Macro to abstract checking whether file is using a free space manager */ -#define H5F_HAVE_FREE_SPACE_MANAGER(F) TRUE /* Currently always have a free space manager */ +#define H5F_HAVE_FREE_SPACE_MANAGER(F) \ + ((F)->shared->fs_strategy == H5F_FILE_SPACE_ALL || \ + (F)->shared->fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) /* Macros for encoding/decoding superblock */ #define H5F_MAX_DRVINFOBLOCK_SIZE 1024 /* Maximum size of superblock driver info buffer */ @@ -197,8 +199,8 @@ typedef struct H5F_file_t { H5F_mtab_t mtab; /* File mount table */ /* Cached values from FCPL/superblock */ - size_t sizeof_addr; /* Size of addresses in file */ - size_t sizeof_size; /* Size of offsets in file */ + uint8_t sizeof_addr; /* Size of addresses in file */ + uint8_t sizeof_size; /* Size of offsets in file */ haddr_t sohm_addr; /* Relative address of shared object header message table */ unsigned sohm_vers; /* Version of shared message table on disk */ unsigned sohm_nindexes; /* Number of shared messages indexes in the table */ @@ -229,6 +231,8 @@ typedef struct H5F_file_t { H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */ /* File space allocation information */ + H5F_file_space_type_t fs_strategy; /* File space handling strategy */ + hsize_t fs_threshold; /* Free space section threshold */ hbool_t use_tmp_space; /* Whether temp. file space allocation is allowed */ haddr_t tmp_addr; /* Next address to use for temp. space in the file */ unsigned fs_aggr_merge[H5FD_MEM_NTYPES]; /* Flags for whether free space can merge with aggregator(s) */ @@ -303,6 +307,7 @@ H5_DLL herr_t H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize /* Superblock extension related routines */ H5_DLL herr_t H5F_super_ext_open(H5F_t *f, haddr_t ext_addr, H5O_loc_t *ext_ptr); H5_DLL herr_t H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create); +H5_DLL herr_t H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id); H5_DLL herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr); /* Metadata accumulator routines */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 1e816f9..6ddbae3 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -350,6 +350,8 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_CRT_SHMSG_INDEX_MINSIZE_NAME "shmsg_message_minsize" /* Minimum size of messages in each index */ #define H5F_CRT_SHMSG_LIST_MAX_NAME "shmsg_list_max" /* Shared message list maximum size */ #define H5F_CRT_SHMSG_BTREE_MIN_NAME "shmsg_btree_min" /* Shared message B-tree minimum size */ +#define H5F_CRT_FILE_SPACE_STRATEGY_NAME "file_space_strategy" /* File space handling strategy */ +#define H5F_CRT_FREE_SPACE_THRESHOLD_NAME "free_space_threshold" /* Free space section threshold */ @@ -401,6 +403,11 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; must compensate. -QAK */ +/* Default file space handling strategy */ +#define H5F_FILE_SPACE_STRATEGY_DEF H5F_FILE_SPACE_ALL +/* Default free space section threshold used by free-space managers */ +#define H5F_FREE_SPACE_THRESHOLD_DEF 1 + /* Macros to define signatures of all objects in the file */ /* Size of signature information (on disk) */ @@ -475,8 +482,8 @@ H5_DLL haddr_t H5F_get_next_proxy_addr(const H5F_t *f); /* Functions than retrieve values set/cached from the superblock/FCPL */ H5_DLL hid_t H5F_get_fcpl(const H5F_t *f); -H5_DLL size_t H5F_sizeof_addr(const H5F_t *f); -H5_DLL size_t H5F_sizeof_size(const H5F_t *f); +H5_DLL uint8_t H5F_sizeof_addr(const H5F_t *f); +H5_DLL uint8_t H5F_sizeof_size(const H5F_t *f); H5_DLL unsigned H5F_sym_leaf_k(const H5F_t *f); H5_DLL unsigned H5F_Kvalue(const H5F_t *f, const struct H5B_class_t *type); H5_DLL size_t H5F_rdcc_nbytes(const H5F_t *f); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 6392c9e..0f79660 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -118,14 +118,23 @@ typedef enum H5F_close_degree_t { } H5F_close_degree_t; /* Current "global" information about file */ -/* (just size info currently) */ -typedef struct H5F_info_t { - hsize_t super_ext_size; /* Superblock extension size */ +typedef struct H5F_info2_t { + struct { + unsigned version; /* Superblock version # */ + hsize_t super_size; /* Superblock size */ + hsize_t super_ext_size; /* Superblock extension size */ + } super; + struct { + unsigned version; /* Version # of file free space management */ + hsize_t meta_size; /* Free space manager metadata size */ + hsize_t tot_space; /* Amount of free space in the file */ + } free; struct { + unsigned version; /* Version # of shared object header info */ hsize_t hdr_size; /* Shared object header message header size */ H5_ih_info_t msgs_info; /* Shared object header message index & heap size */ } sohm; -} H5F_info_t; +} H5F_info2_t; /* * Types of allocation requests. The values larger than H5FD_MEM_DEFAULT @@ -145,12 +154,30 @@ typedef enum H5F_mem_t { H5FD_MEM_NTYPES /*must be last*/ } H5F_mem_t; +/* Free space section information */ +typedef struct H5F_sect_info_t { + haddr_t addr; /* Address of free space section */ + hsize_t size; /* Size of free space section */ +} H5F_sect_info_t; + /* Library's file format versions */ typedef enum H5F_libver_t { H5F_LIBVER_EARLIEST, /* Use the earliest possible format for storing objects */ H5F_LIBVER_LATEST /* Use the latest possible format available for storing objects*/ } H5F_libver_t; +/* File space handling strategy */ +typedef enum H5F_file_space_type_t { + H5F_FILE_SPACE_DEFAULT = 0, /* Default (or current) free space strategy setting */ + H5F_FILE_SPACE_ALL_PERSIST = 1, /* Persistent free space managers, aggregators, virtual file driver */ + H5F_FILE_SPACE_ALL = 2, /* Non-persistent free space managers, aggregators, virtual file driver */ + /* This is the library default */ + H5F_FILE_SPACE_AGGR_VFD = 3, /* Aggregators, Virtual file driver */ + H5F_FILE_SPACE_VFD = 4, /* Virtual file driver */ + H5F_FILE_SPACE_NTYPES /* must be last */ +} H5F_file_space_type_t; + + #ifdef __cplusplus extern "C" { #endif @@ -186,7 +213,35 @@ H5_DLL herr_t H5Fget_mdc_size(hid_t file_id, int * cur_num_entries_ptr); H5_DLL herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id); H5_DLL ssize_t H5Fget_name(hid_t obj_id, char *name, size_t size); -H5_DLL herr_t H5Fget_info(hid_t obj_id, H5F_info_t *bh_info); +H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo); +H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, + size_t nsects, H5F_sect_info_t *sect_info/*out*/); + +/* Symbols defined for compatibility with previous versions of the HDF5 API. + * + * Use of these symbols is deprecated. + */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/* Macros */ + + +/* Typedefs */ + +/* Current "global" information about file */ +typedef struct H5F_info1_t { + hsize_t super_ext_size; /* Superblock extension size */ + struct { + hsize_t hdr_size; /* Shared object header message header size */ + H5_ih_info_t msgs_info; /* Shared object header message index & heap size */ + } sohm; +} H5F_info1_t; + + +/* Function prototypes */ +H5_DLL herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo); + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ #ifdef __cplusplus } diff --git a/src/H5Fquery.c b/src/H5Fquery.c index 93f2d6e..70c5ff1 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -195,7 +195,7 @@ H5F_get_fcpl(const H5F_t *f) * *------------------------------------------------------------------------- */ -size_t +uint8_t H5F_sizeof_addr(const H5F_t *f) { /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ @@ -222,7 +222,7 @@ H5F_sizeof_addr(const H5F_t *f) * *------------------------------------------------------------------------- */ -size_t +uint8_t H5F_sizeof_size(const H5F_t *f) { /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index e85c980..c24cfa1 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -400,6 +400,12 @@ 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 + */ + else if(f->shared->fs_strategy != H5F_FILE_SPACE_STRATEGY_DEF || + f->shared->fs_threshold != H5F_FREE_SPACE_THRESHOLD_DEF) + super_vers = HDF5_SUPERBLOCK_VERSION_2; /* Check for non-default indexed storage B-tree internal 'K' value * and set the version # of the superblock to 1 if it is a non-default * value. @@ -495,6 +501,12 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) HDassert(super_vers >= HDF5_SUPERBLOCK_VERSION_2); need_ext = TRUE; } /* end if */ + /* Files with non-default free space settings always need the superblock extension */ + else if(f->shared->fs_strategy != H5F_FILE_SPACE_STRATEGY_DEF || + f->shared->fs_threshold != H5F_FREE_SPACE_THRESHOLD_DEF) { + HDassert(super_vers >= HDF5_SUPERBLOCK_VERSION_2); + need_ext = TRUE; + } /* end if */ /* If we're going to use a version of the superblock format which allows * for the superblock extension, check for non-default values to store * in it. @@ -571,6 +583,18 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update driver info header message") } /* end if */ + /* Check for non-default free space settings */ + if(f->shared->fs_strategy != H5F_FILE_SPACE_STRATEGY_DEF || + f->shared->fs_threshold != H5F_FREE_SPACE_THRESHOLD_DEF) { + H5O_fsinfo_t fsinfo; /* Free space manager info message */ + + /* Write free-space manager info message to superblock extension object header if needed */ + fsinfo.strategy = f->shared->fs_strategy; + fsinfo.threshold = f->shared->fs_threshold; + if(H5O_msg_create(&ext_loc, H5O_FSINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &fsinfo, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update free-space info header message") + } /* end if */ + /* Close superblock extension */ if(H5F_super_ext_close(f, &ext_loc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") @@ -670,8 +694,8 @@ H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_ /* Set the superblock extension size */ if(super_ext_size) { if(H5F_addr_defined(f->shared->sblock->ext_addr)) { - H5O_loc_t ext_loc; /* "Object location" for superblock extension */ - H5O_info_t oinfo; /* Object info for superblock extension */ + H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + H5O_hdr_info_t hdr_info; /* Object info for superblock extension */ /* Set up "fake" object location for superblock extension */ H5O_loc_reset(&ext_loc); @@ -679,11 +703,11 @@ H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_ ext_loc.addr = f->shared->sblock->ext_addr; /* Get object header info for superblock extension */ - if(H5O_get_info(&ext_loc, dxpl_id, FALSE, &oinfo) < 0) + if(H5O_get_hdr_info(&ext_loc, dxpl_id, &hdr_info) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve superblock extension info") /* Set the superblock extension size */ - *super_ext_size = oinfo.hdr.space.total; + *super_ext_size = hdr_info.space.total; } /* end if */ else /* Set the superblock extension size to zero */ @@ -769,3 +793,66 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_super_ext_write_msg() */ + +/*------------------------------------------------------------------------- + * Function: H5F_super_ext_remove_msg + * + * Purpose: Remove the message with ID from the superblock extension + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id) +{ + htri_t status; /* Indicate whether the message exists or not */ + H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + int null_count = 0; /* # of null messages */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_super_ext_remove_msg, FAIL) + + /* Make sure that the superblock extension object header exists */ + HDassert(H5F_addr_defined(f->shared->sblock->ext_addr)); + + /* Open superblock extension object header */ + if(H5F_super_ext_open(f, f->shared->sblock->ext_addr, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "error in starting file's superblock extension") + + /* Check if message with ID exists in the object header */ + if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check object header for message") + else if(status) { /* message exists */ + H5O_hdr_info_t hdr_info; /* Object header info for superblock extension */ + + /* Remove the message */ + if(H5O_msg_remove(&ext_loc, id, H5O_ALL, TRUE, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete free-space manager info message") + + /* Get info for the superblock extension's object header */ + if(H5O_get_hdr_info(&ext_loc, dxpl_id, &hdr_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve superblock extension info") + + /* If the object header is an empty base chunk, remove superblock extension */ + if(hdr_info.nchunks == 1) { + if((null_count = H5O_msg_count(&ext_loc, H5O_NULL_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to count messages") + else if((unsigned)null_count == hdr_info.nmesgs) { + HDassert(H5F_addr_defined(ext_loc.addr)); + if(H5O_delete(f, dxpl_id, ext_loc.addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to count messages") + f->shared->sblock->ext_addr = HADDR_UNDEF; + } /* end if */ + } /* end if */ + } /* end if */ + + /* Close superblock extension object header */ + if(H5F_super_ext_close(f, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_super_ext_remove_msg() */ + diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 14454ef..1f2de6d 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -121,8 +121,8 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 H5FD_t *lf; /* file driver part of `shared' */ haddr_t stored_eoa; /*relative end-of-addr in file */ haddr_t eof; /*end of file address */ - size_t sizeof_addr; /* Size of offsets in the file (in bytes) */ - size_t sizeof_size; /* Size of lengths in the file (in bytes) */ + uint8_t sizeof_addr; /* Size of offsets in the file (in bytes) */ + uint8_t sizeof_size; /* Size of lengths in the file (in bytes) */ const size_t fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock */ size_t variable_size; /*variable sizeof superblock */ uint8_t *p; /* Temporary pointer into encoding buffer */ @@ -154,7 +154,7 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 /* Read fixed-size portion of the superblock */ p = sbuf; - if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, fixed_size) < 0) + if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)fixed_size) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed") if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)0, fixed_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") @@ -181,7 +181,7 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 HDassert(fixed_size + variable_size <= sizeof(sbuf)); /* Read in variable-sized portion of superblock */ - if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, fixed_size + variable_size) < 0) + if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)(fixed_size + variable_size)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed") if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)fixed_size, variable_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock") @@ -480,6 +480,7 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 H5O_loc_t ext_loc; /* "Object location" for superblock extension */ H5O_btreek_t btreek; /* v1 B-tree 'K' value message from superblock extension */ H5O_drvinfo_t drvinfo; /* Driver info message from superblock extension */ + size_t u; /* Local index variable */ htri_t status; /* Status for message existing */ /* Sanity check - superblock extension should only be defined for @@ -564,6 +565,41 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 sblock->sym_leaf_k = H5F_CRT_SYM_LEAF_DEF; } /* end if */ + /* Check for the extension having a 'free-space manager info' message */ + if((status = H5O_msg_exists(&ext_loc, H5O_FSINFO_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to check object header") + if(status) { + H5O_fsinfo_t fsinfo; /* Free-space manager info message from superblock extension */ + + /* Retrieve the 'free-space manager info' structure */ + if(NULL == H5O_msg_read(&ext_loc, H5O_FSINFO_ID, &fsinfo, dxpl_id)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to get free-space manager info message") + + if(shared->fs_strategy != fsinfo.strategy) { + shared->fs_strategy = fsinfo.strategy; + + /* Set non-default strategy in the property list */ + if(H5P_set(c_plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &fsinfo.strategy) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set file space strategy") + } /* end if */ + if(shared->fs_threshold != fsinfo.threshold) { + shared->fs_threshold = fsinfo.threshold; + + /* Set non-default threshold in the property list */ + if(H5P_set(c_plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &fsinfo.threshold) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set file space strategy") + } /* end if */ + + /* set free-space manager addresses */ + shared->fs_addr[0] = HADDR_UNDEF; + for(u = 1; u < NELMTS(f->shared->fs_addr); u++) + shared->fs_addr[u] = fsinfo.fs_addr[u-1]; + } /* end if */ + else { + for(u = 0; u < NELMTS(f->shared->fs_addr); u++) + shared->fs_addr[u] = HADDR_UNDEF; + } /* end else */ + /* Close superblock extension */ if(H5F_super_ext_close(f, &ext_loc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, NULL, "unable to close file's superblock extension") @@ -573,7 +609,6 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 ret_value = sblock; done: - FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_sblock_load() */ @@ -714,7 +749,7 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F_sup H5F_addr_encode(f, &p, root_oloc->addr); /* Compute superblock checksum */ - chksum = H5_checksum_metadata(buf, (H5F_SUPERBLOCK_SIZE(sblock->super_vers, f) - H5F_SIZEOF_CHKSUM), 0); + chksum = H5_checksum_metadata(buf, (size_t)(H5F_SUPERBLOCK_SIZE(sblock->super_vers, f) - H5F_SIZEOF_CHKSUM), 0); /* Superblock checksum */ UINT32ENCODE(p, chksum); @@ -432,6 +432,7 @@ H5Gget_create_plist(hid_t group_id) H5O_linfo_t linfo; /* Link info message */ htri_t ginfo_exists; htri_t linfo_exists; + htri_t pline_exists; H5G_t *grp = NULL; H5P_genplist_t *gcpl_plist; H5P_genplist_t *new_plist; @@ -481,6 +482,21 @@ H5Gget_create_plist(hid_t group_id) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info") } /* end if */ + /* Check for the group having a pipeline message */ + if((pline_exists = H5O_msg_exists(&(grp->oloc), H5O_PLINE_ID, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") + if(pline_exists) { + H5O_pline_t pline; /* Pipeline message */ + + /* Read the pipeline */ + if(NULL == H5O_msg_read(&(grp->oloc), H5O_PLINE_ID, &pline, H5AC_ind_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline") + + /* Set the pipeline for the property list */ + if(H5P_set(new_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link pipeline") + } /* end if */ + /* Set the return value */ ret_value = new_gcpl_id; @@ -838,9 +854,6 @@ H5G_t * H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id) { H5G_t *grp = NULL; /*new group */ - H5P_genplist_t *gc_plist; /* Property list created */ - H5O_ginfo_t ginfo; /* Group info */ - H5O_linfo_t linfo; /* Link info */ unsigned oloc_init = 0; /* Flag to indicate that the group object location was created successfully */ H5G_t *ret_value; /* Return value */ @@ -857,20 +870,8 @@ H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id) if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* Get the property list */ - if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(gcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list") - - /* Get the group info property */ - if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info") - - /* Get the link info property */ - if(H5P_get(gc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info") - /* Create the group object header */ - if(H5G_obj_create(file, dxpl_id, &ginfo, &linfo, gcpl_id, &(grp->oloc)/*out*/) < 0) + if(H5G_obj_create(file, dxpl_id, gcpl_id, &(grp->oloc)/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header") oloc_init = 1; /* Indicate that the object location information is valid */ diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c index 5f7ad23..29ab309 100644 --- a/src/H5Gbtree2.c +++ b/src/H5Gbtree2.c @@ -104,8 +104,9 @@ static herr_t H5G_dense_fh_name_cmp(const void *obj, size_t obj_len, void *op_da /* Package Variables */ /*********************/ /* v2 B-tree class for indexing 'name' field of links */ -const H5B2_class_t H5G_BT2_NAME[1]={{ /* B-tree class information */ +const H5B2_class_t H5G_BT2_NAME[1]={{ /* B-tree class information */ H5B2_GRP_DENSE_NAME_ID, /* Type of B-tree */ + "H5B2_GRP_DENSE_NAME_ID", /* Name of B-tree class */ sizeof(H5G_dense_bt2_name_rec_t), /* Size of native record */ H5G_dense_btree2_name_store, /* Record storage callback */ H5G_dense_btree2_name_compare, /* Record comparison callback */ @@ -117,6 +118,7 @@ const H5B2_class_t H5G_BT2_NAME[1]={{ /* B-tree class information */ /* v2 B-tree class for indexing 'creation order' field of links */ const H5B2_class_t H5G_BT2_CORDER[1]={{ /* B-tree class information */ H5B2_GRP_DENSE_CORDER_ID, /* Type of B-tree */ + "H5B2_GRP_DENSE_CORDER_ID", /* Name of B-tree class */ sizeof(H5G_dense_bt2_corder_rec_t), /* Size of native record */ H5G_dense_btree2_corder_store, /* Record storage callback */ H5G_dense_btree2_corder_compare, /* Record comparison callback */ diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 322b31b..f935a74 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -267,12 +267,15 @@ typedef struct { *------------------------------------------------------------------------- */ herr_t -H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo) +H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, + const H5O_pline_t *pline) { H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */ - H5HF_t *fheap; /* Fractal heap handle */ + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for names */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order */ size_t fheap_id_len; /* Fractal heap ID length */ - size_t bt2_rrec_size; /* v2 B-tree raw record size */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_dense_create, FAIL) @@ -293,6 +296,8 @@ H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo) fheap_cparam.managed.start_root_rows = H5G_FHEAP_MAN_START_ROOT_ROWS; fheap_cparam.checksum_dblocks = H5G_FHEAP_CHECKSUM_DBLOCKS; fheap_cparam.max_man_size = H5G_FHEAP_MAX_MAN_SIZE; + if(pline) + fheap_cparam.pline = *pline; /* Create fractal heap for storing links */ if(NULL == (fheap = H5HF_create(f, dxpl_id, &fheap_cparam))) @@ -300,7 +305,7 @@ H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo) /* Retrieve the heap's address in the file */ if(H5HF_get_heap_addr(fheap, &(linfo->fheap_addr)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address") + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get fractal heap address") #ifdef QAK HDfprintf(stderr, "%s: linfo->fheap_addr = %a\n", FUNC, linfo->fheap_addr); #endif /* QAK */ @@ -313,18 +318,20 @@ HDfprintf(stderr, "%s: linfo->fheap_addr = %a\n", FUNC, linfo->fheap_addr); HDfprintf(stderr, "%s: fheap_id_len = %Zu\n", FUNC, fheap_id_len); #endif /* QAK */ - /* Close the fractal heap */ - if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") - /* Create the name index v2 B-tree */ - bt2_rrec_size = 4 + /* Name's hash value */ + HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam)); + bt2_cparam.cls = H5G_BT2_NAME; + bt2_cparam.node_size = (size_t)H5G_NAME_BT2_NODE_SIZE; + bt2_cparam.rrec_size = 4 + /* Name's hash value */ fheap_id_len; /* Fractal heap ID */ - if(H5B2_create(f, dxpl_id, H5G_BT2_NAME, - (size_t)H5G_NAME_BT2_NODE_SIZE, bt2_rrec_size, - H5G_NAME_BT2_SPLIT_PERC, H5G_NAME_BT2_MERGE_PERC, - &(linfo->name_bt2_addr)) < 0) + bt2_cparam.split_percent = H5G_NAME_BT2_SPLIT_PERC; + bt2_cparam.merge_percent = H5G_NAME_BT2_MERGE_PERC; + if(NULL == (bt2_name = H5B2_create(f, dxpl_id, &bt2_cparam))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2_name, &(linfo->name_bt2_addr)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for name index") #ifdef QAK HDfprintf(stderr, "%s: linfo->name_bt2_addr = %a\n", FUNC, linfo->name_bt2_addr); #endif /* QAK */ @@ -332,19 +339,33 @@ HDfprintf(stderr, "%s: linfo->name_bt2_addr = %a\n", FUNC, linfo->name_bt2_addr) /* Check if we should create a creation order index v2 B-tree */ if(linfo->index_corder) { /* Create the creation order index v2 B-tree */ - bt2_rrec_size = 8 + /* Creation order value */ + HDmemset(&bt2_cparam, 0, sizeof(bt2_cparam)); + bt2_cparam.cls = H5G_BT2_CORDER; + bt2_cparam.node_size = (size_t)H5G_CORDER_BT2_NODE_SIZE; + bt2_cparam.rrec_size = 8 + /* Creation order value */ fheap_id_len; /* Fractal heap ID */ - if(H5B2_create(f, dxpl_id, H5G_BT2_CORDER, - (size_t)H5G_CORDER_BT2_NODE_SIZE, bt2_rrec_size, - H5G_CORDER_BT2_SPLIT_PERC, H5G_CORDER_BT2_MERGE_PERC, - &(linfo->corder_bt2_addr)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for name index") + bt2_cparam.split_percent = H5G_CORDER_BT2_SPLIT_PERC; + bt2_cparam.merge_percent = H5G_CORDER_BT2_MERGE_PERC; + if(NULL == (bt2_corder = H5B2_create(f, dxpl_id, &bt2_cparam))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create v2 B-tree for creation order index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2_corder, &(linfo->corder_bt2_addr)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for creation order index") #ifdef QAK HDfprintf(stderr, "%s: linfo->corder_bt2_addr = %a\n", FUNC, linfo->corder_bt2_addr); #endif /* QAK */ } /* end if */ done: + /* Close the open objects */ + if(fheap && H5HF_close(fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_dense_create() */ @@ -368,6 +389,8 @@ H5G_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, { H5G_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ size_t link_size; /* Size of serialized link in the heap */ H5WB_t *wb = NULL; /* Wrapped buffer for link data */ uint8_t link_buf[H5G_LINK_BUF_SIZE]; /* Buffer for serializing link */ @@ -414,6 +437,10 @@ HDfprintf(stderr, "%s: HDstrlen(lnk->name) = %Zu, link_size = %Zu\n", FUNC, HDst if(H5HF_insert(fheap, dxpl_id, link_size, link_ptr, udata.id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link into fractal heap") + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, linfo->name_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Create the callback information for v2 B-tree record insertion */ udata.common.f = f; udata.common.dxpl_id = dxpl_id; @@ -426,14 +453,18 @@ HDfprintf(stderr, "%s: HDstrlen(lnk->name) = %Zu, link_size = %Zu\n", FUNC, HDst /* udata.id already set in H5HF_insert() call */ /* Insert link into 'name' tracking v2 B-tree */ - if(H5B2_insert(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &udata) < 0) + if(H5B2_insert(bt2_name, dxpl_id, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree") /* Check if we should create a creation order index v2 B-tree record */ if(linfo->index_corder) { - /* Insert the record into the creation order index v2 B-tree */ + /* Open the creation order index v2 B-tree */ HDassert(H5F_addr_defined(linfo->corder_bt2_addr)); - if(H5B2_insert(f, dxpl_id, H5G_BT2_CORDER, linfo->corder_bt2_addr, &udata) < 0) + if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, linfo->corder_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + + /* Insert the record into the creation order index v2 B-tree */ + if(H5B2_insert(bt2_corder, dxpl_id, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert record into v2 B-tree") } /* end if */ @@ -441,6 +472,10 @@ done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer") @@ -504,6 +539,7 @@ H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, { H5G_bt2_ud_common_t udata; /* User data for v2 B-tree link lookup */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_dense_lookup, FAIL) @@ -520,6 +556,10 @@ H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, linfo->name_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Construct the user data for v2 B-tree callback */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -530,13 +570,15 @@ H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, udata.found_op_data = lnk; /* Find & copy the named link in the 'name' index */ - if((ret_value = H5B2_find(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &udata, NULL, NULL)) < 0) + if((ret_value = H5B2_find(bt2_name, dxpl_id, &udata, NULL, NULL)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in name index") done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_dense_lookup() */ @@ -641,7 +683,7 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, { H5HF_t *fheap = NULL; /* Fractal heap handle */ H5G_link_table_t ltable = {0, NULL}; /* Table of links */ - const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ herr_t ret_value = SUCCEED; /* Return value */ @@ -671,7 +713,6 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, * Otherwise, build a table. */ bt2_addr = linfo->corder_bt2_addr; - bt2_class = H5G_BT2_CORDER; } /* end else */ /* If the order is native and there's no B-tree for indexing the links, @@ -680,7 +721,6 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, */ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { bt2_addr = linfo->name_bt2_addr; - bt2_class = H5G_BT2_NAME; HDassert(H5F_addr_defined(bt2_addr)); } /* end if */ @@ -692,6 +732,10 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index") + /* Construct the user data for v2 B-tree callback */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -699,7 +743,7 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, udata.lnk = lnk; /* Find & copy the link in the appropriate index */ - if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_lookup_by_idx_bt2_cb, &udata) < 0) + if(H5B2_index(bt2, dxpl_id, order, n, H5G_dense_lookup_by_idx_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in index") } /* end if */ else { /* Otherwise, we need to build a table of the links and sort it */ @@ -720,6 +764,8 @@ done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index") if(ltable.lnks && H5G_link_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") @@ -943,7 +989,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, { H5HF_t *fheap = NULL; /* Fractal heap handle */ H5G_link_table_t ltable = {0, NULL}; /* Table of links */ - const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ herr_t ret_value; /* Return value */ @@ -973,7 +1019,6 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, * Otherwise, build a table. */ bt2_addr = linfo->corder_bt2_addr; - bt2_class = H5G_BT2_CORDER; } /* end else */ /* If the order is native and there's no B-tree for indexing the links, @@ -983,19 +1028,23 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { HDassert(H5F_addr_defined(linfo->name_bt2_addr)); bt2_addr = linfo->name_bt2_addr; - bt2_class = H5G_BT2_NAME; } /* end if */ /* Check on iteration order */ if(order == H5_ITER_NATIVE) { H5G_bt2_ud_it_t udata; /* User data for iterator callback */ + /* Sanity check */ HDassert(H5F_addr_defined(bt2_addr)); /* Open the fractal heap */ if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index") + /* Construct the user data for v2 B-tree iterator callback */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -1007,7 +1056,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, /* Iterate over the records in the v2 B-tree's "native" order */ /* (by hash of name) */ - if((ret_value = H5B2_iterate(f, dxpl_id, bt2_class, bt2_addr, H5G_dense_iterate_bt2_cb, &udata)) < 0) + if((ret_value = H5B2_iterate(bt2, dxpl_id, H5G_dense_iterate_bt2_cb, &udata)) < 0) HERROR(H5E_SYM, H5E_BADITER, "link iteration failed"); /* Update the last link examined, if requested */ @@ -1028,6 +1077,8 @@ done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index") if(ltable.lnks && H5G_link_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") @@ -1142,10 +1193,10 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name, size_t size) { - H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ H5G_link_table_t ltable = {0, NULL}; /* Table of links */ - const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ - haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ + haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ ssize_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_dense_get_name_by_idx, FAIL) @@ -1173,7 +1224,6 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, * Otherwise, build a table. */ bt2_addr = linfo->corder_bt2_addr; - bt2_class = H5G_BT2_CORDER; } /* end else */ /* If the order is native and there's no B-tree for indexing the links, @@ -1182,7 +1232,6 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, */ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { bt2_addr = linfo->name_bt2_addr; - bt2_class = H5G_BT2_NAME; HDassert(H5F_addr_defined(bt2_addr)); } /* end if */ @@ -1194,6 +1243,10 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index") + /* Set up the user data for the v2 B-tree 'record remove' callback */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -1202,7 +1255,7 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, udata.name_size = size; /* Retrieve the name according to the v2 B-tree's index order */ - if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_get_name_by_idx_bt2_cb, &udata) < 0) + if(H5B2_index(bt2, dxpl_id, order, n, H5G_dense_get_name_by_idx_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "can't locate object in v2 B-tree") /* Set return value */ @@ -1232,6 +1285,8 @@ done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index") if(ltable.lnks && H5G_link_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") @@ -1257,6 +1312,7 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) { H5G_fh_ud_rm_t *udata = (H5G_fh_ud_rm_t *)_udata; /* User data for fractal heap 'op' callback */ H5O_link_t *lnk = NULL; /* Pointer to link created from heap object */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_dense_remove_fh_cb) @@ -1269,13 +1325,16 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) if(H5F_addr_defined(udata->corder_bt2_addr)) { H5G_bt2_ud_common_t bt2_udata; /* Info for B-tree callbacks */ + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(udata->f, udata->dxpl_id, udata->corder_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + /* Set up the user data for the v2 B-tree 'record remove' callback */ HDassert(lnk->corder_valid); bt2_udata.corder = lnk->corder; /* Remove the record from the name index v2 B-tree */ - if(H5B2_remove(udata->f, udata->dxpl_id, H5G_BT2_CORDER, udata->corder_bt2_addr, - &bt2_udata, NULL, NULL) < 0) + if(H5B2_remove(bt2, udata->dxpl_id, &bt2_udata, NULL, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from creation order index v2 B-tree") } /* end if */ @@ -1290,7 +1349,9 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link") done: - /* Release the space allocated for the link */ + /* Release resources */ + if(bt2 && H5B2_close(bt2, udata->dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") if(lnk) H5O_msg_free(H5O_LINK_ID, lnk); @@ -1361,7 +1422,8 @@ H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, const char *name) { H5HF_t *fheap = NULL; /* Fractal heap handle */ - H5G_bt2_ud_rm_t udata; /* User data for v2 B-tree record removal */ + H5G_bt2_ud_rm_t udata; /* User data for v2 B-tree record removal */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_dense_remove, FAIL) @@ -1377,6 +1439,10 @@ H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the name index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, linfo->name_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Set up the user data for the v2 B-tree 'record remove' callback */ udata.common.f = f; udata.common.dxpl_id = dxpl_id; @@ -1391,13 +1457,15 @@ H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, udata.replace_names = TRUE; /* Remove the record from the name index v2 B-tree */ - if(H5B2_remove(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &udata, H5G_dense_remove_bt2_cb, &udata) < 0) + if(H5B2_remove(bt2, dxpl_id, &udata, H5G_dense_remove_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from name index v2 B-tree") done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_dense_remove() */ @@ -1453,6 +1521,7 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) { H5G_bt2_ud_rmbi_t *bt2_udata = (H5G_bt2_ud_rmbi_t *)_bt2_udata; /* User data for callback */ H5G_fh_ud_rmbi_t fh_udata; /* User data for fractal heap 'op' callback */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ const uint8_t *heap_id; /* Heap ID for link */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1488,22 +1557,15 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) /* Check for removing the link from the "other" index (creation order, when name used and vice versa) */ if(H5F_addr_defined(bt2_udata->other_bt2_addr)) { H5G_bt2_ud_common_t other_bt2_udata; /* Info for B-tree callbacks */ - const H5B2_class_t *other_bt2_class; /* Class of "other" v2 B-tree */ /* Determine the index being used */ if(bt2_udata->idx_type == H5_INDEX_NAME) { - /* Set the class of the "other" index */ - other_bt2_class = H5G_BT2_CORDER; - /* Set up the user data for the v2 B-tree 'record remove' callback */ other_bt2_udata.corder = fh_udata.lnk->corder; } /* end if */ else { HDassert(bt2_udata->idx_type == H5_INDEX_CRT_ORDER); - /* Set the class of the "other" index */ - other_bt2_class = H5G_BT2_NAME; - /* Set up the user data for the v2 B-tree 'record remove' callback */ other_bt2_udata.f = bt2_udata->f; other_bt2_udata.dxpl_id = bt2_udata->dxpl_id; @@ -1514,12 +1576,15 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) other_bt2_udata.found_op_data = NULL; } /* end else */ + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(bt2_udata->f, bt2_udata->dxpl_id, bt2_udata->other_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for 'other' index") + /* Set the common information for the v2 B-tree remove operation */ /* Remove the record from the name index v2 B-tree */ - if(H5B2_remove(bt2_udata->f, bt2_udata->dxpl_id, other_bt2_class, bt2_udata->other_bt2_addr, - &other_bt2_udata, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, H5_ITER_ERROR, "unable to remove link from creation order index v2 B-tree") + if(H5B2_remove(bt2, bt2_udata->dxpl_id, &other_bt2_udata, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, H5_ITER_ERROR, "unable to remove link from 'other' index v2 B-tree") } /* end if */ /* Replace open objects' names */ @@ -1539,6 +1604,10 @@ H5G_dense_remove_by_idx_bt2_cb(const void *_record, void *_bt2_udata) HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from fractal heap") done: + /* Release resources */ + if(bt2 && H5B2_close(bt2, bt2_udata->dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for 'other' index") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_dense_remove_by_idx_bt2_cb() */ @@ -1564,7 +1633,7 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, { H5HF_t *fheap = NULL; /* Fractal heap handle */ H5G_link_table_t ltable = {0, NULL}; /* Table of links */ - const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1593,7 +1662,6 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, * Otherwise, build a table. */ bt2_addr = linfo->corder_bt2_addr; - bt2_class = H5G_BT2_CORDER; } /* end else */ /* If the order is native and there's no B-tree for indexing the links, @@ -1602,7 +1670,6 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, */ if(order == H5_ITER_NATIVE && !H5F_addr_defined(bt2_addr)) { bt2_addr = linfo->name_bt2_addr; - bt2_class = H5G_BT2_NAME; HDassert(H5F_addr_defined(bt2_addr)); } /* end if */ @@ -1614,6 +1681,10 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for index") + /* Set up the user data for the v2 B-tree 'remove by index' callback */ udata.f = f; udata.dxpl_id = dxpl_id; @@ -1623,8 +1694,7 @@ H5G_dense_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, udata.grp_full_path_r = grp_full_path_r; /* Remove the record from the name index v2 B-tree */ - if(H5B2_remove_by_idx(f, dxpl_id, bt2_class, bt2_addr, - order, n, H5G_dense_remove_by_idx_bt2_cb, &udata) < 0) + if(H5B2_remove_by_idx(bt2, dxpl_id, order, n, H5G_dense_remove_by_idx_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "unable to remove link from indexed v2 B-tree") } /* end if */ else { /* Otherwise, we need to build a table of the links and sort it */ @@ -1645,6 +1715,8 @@ done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for index") if(ltable.lnks && H5G_link_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") @@ -1704,7 +1776,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link) udata.replace_names = FALSE; /* Delete the name index, adjusting the ref. count on links removed */ - if(H5B2_delete(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, H5G_dense_remove_bt2_cb, &udata) < 0) + if(H5B2_delete(f, dxpl_id, linfo->name_bt2_addr, H5G_dense_remove_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index") /* Close the fractal heap */ @@ -1713,7 +1785,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link) } /* end if */ else { /* Delete the name index, without adjusting the ref. count on the links */ - if(H5B2_delete(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, NULL, NULL) < 0) + if(H5B2_delete(f, dxpl_id, linfo->name_bt2_addr, NULL, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index") } /* end else */ linfo->name_bt2_addr = HADDR_UNDEF; @@ -1722,7 +1794,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link) if(linfo->index_corder) { /* Delete the creation order index, without adjusting the ref. count on the links */ HDassert(H5F_addr_defined(linfo->corder_bt2_addr)); - if(H5B2_delete(f, dxpl_id, H5G_BT2_CORDER, linfo->corder_bt2_addr, NULL, NULL) < 0) + if(H5B2_delete(f, dxpl_id, linfo->corder_bt2_addr, NULL, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for creation order index") linfo->corder_bt2_addr = HADDR_UNDEF; } /* end if */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index ddb5dfe..a18339b 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -890,7 +890,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, +H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5G_trav_goi_t *udata = (H5G_trav_goi_t *)_udata; /* User data passed in */ @@ -900,7 +900,7 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_ /* Check if the name in this group resolved to a valid link */ if(lnk == NULL && obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name) /* Only modify user's buffer if it's available */ if(udata->statbuf) { diff --git a/src/H5Glink.c b/src/H5Glink.c index 37a0ede..488c05b 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -609,7 +609,7 @@ H5G_link_iterate_table(const H5G_link_table_t *ltable, hsize_t skip, size_t u; /* Local index variable */ herr_t ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI(H5G_link_iterate_table, FAIL) + FUNC_ENTER_NOAPI_NOERR(H5G_link_iterate_table, -) /* Sanity check */ HDassert(ltable); diff --git a/src/H5Gobj.c b/src/H5Gobj.c index a11dc13..4281ac0 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -125,20 +125,78 @@ static herr_t H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, *------------------------------------------------------------------------- */ herr_t -H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - const H5O_linfo_t *linfo, hid_t gcpl_id, H5O_loc_t *oloc/*out*/) +H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, H5O_loc_t *oloc/*out*/) +{ + H5P_genplist_t *gc_plist; /* Group creation property list */ + H5O_ginfo_t ginfo; /* Group info */ + H5O_linfo_t linfo; /* Link info */ + H5O_pline_t pline; /* Pipeline */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_obj_create, FAIL) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(oloc); + + /* Get the property list */ + if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(gcpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a property list") + + /* Get the group info property */ + if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") + + /* Get the link info property */ + if(H5P_get(gc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") + + /* Get the pipeline property */ + if(H5P_get(gc_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") + + /* Call the "real" group creation routine now */ + if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcpl_id, oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create group") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_obj_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_obj_create_real + * + * Purpose: Create an object header for a group and update object location info + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 29 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, + const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id, + H5O_loc_t *oloc/*out*/) { size_t hdr_size; /* Size of object header to request */ hbool_t use_latest_format; /* Flag indicating the new group format should be used */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_obj_create, FAIL) + FUNC_ENTER_NOAPI(H5G_obj_create_real, FAIL) /* * Check arguments. */ HDassert(f); HDassert(ginfo); + HDassert(linfo); + HDassert(pline); HDassert(oloc); /* Check for invalid access request */ @@ -147,7 +205,8 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Check for using the latest version of the group format */ /* (add more checks for creating "new format" groups when needed) */ - if(H5F_USE_LATEST_FORMAT(f) || linfo->track_corder) + if(H5F_USE_LATEST_FORMAT(f) || linfo->track_corder + || (pline && pline->nused)) use_latest_format = TRUE; else use_latest_format = FALSE; @@ -164,6 +223,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, char null_char = '\0'; /* Character for creating null string */ size_t ginfo_size; /* Size of the group info message */ size_t linfo_size; /* Size of the link info message */ + size_t pline_size = 0; /* Size of the pipeline message */ size_t link_size; /* Size of a link message */ /* Calculate message size infomation, for creating group's object header */ @@ -173,6 +233,11 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, ginfo_size = H5O_msg_size_f(f, gcpl_id, H5O_GINFO_ID, ginfo, (size_t)0); HDassert(ginfo_size); + if(pline && pline->nused) { + pline_size = H5O_msg_size_f(f, gcpl_id, H5O_PLINE_ID, pline, (size_t)0); + HDassert(pline_size); + } /* end if */ + lnk.type = H5L_TYPE_HARD; lnk.corder = 0; lnk.corder_valid = linfo->track_corder; @@ -184,10 +249,11 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Compute size of header to use for creation */ hdr_size = linfo_size + ginfo_size + + pline_size + (ginfo->est_num_entries * link_size); } /* end if */ else - hdr_size = 4 + 2 * H5F_SIZEOF_ADDR(f); + hdr_size = (size_t)(4 + 2 * H5F_SIZEOF_ADDR(f)); /* * Create group's object header. It has a zero link count @@ -200,12 +266,17 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Check for format of group to create */ if(use_latest_format) { /* Insert link info message */ - if(H5O_msg_create(oloc, H5O_LINFO_ID, 0, 0, linfo, dxpl_id) < 0) + if(H5O_msg_create(oloc, H5O_LINFO_ID, 0, H5O_UPDATE_TIME, linfo, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") /* Insert group info message */ - if(H5O_msg_create(oloc, H5O_GINFO_ID, H5O_MSG_FLAG_CONSTANT, H5O_UPDATE_TIME, ginfo, dxpl_id) < 0) + if(H5O_msg_create(oloc, H5O_GINFO_ID, H5O_MSG_FLAG_CONSTANT, 0, ginfo, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") + + /* Insert pipeline message */ + if(pline && pline->nused) + if(H5O_msg_create(oloc, H5O_PLINE_ID, H5O_MSG_FLAG_CONSTANT, 0, pline, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") } /* end if */ else { H5O_stab_t stab; /* Symbol table message */ @@ -217,7 +288,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_obj_create() */ +} /* end H5G_obj_create_real() */ /*------------------------------------------------------------------------- @@ -238,6 +309,7 @@ done: htri_t H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo, hid_t dxpl_id) { + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_get_linfo, FAIL) @@ -258,9 +330,13 @@ H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo, hid_t dxpl_id) if(linfo->nlinks == HSIZET_MAX) { /* Check if we are using "dense" link storage */ if(H5F_addr_defined(linfo->fheap_addr)) { + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(grp_oloc->file, dxpl_id, linfo->name_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Retrieve # of records in "name" B-tree */ /* (should be same # of records in all indices) */ - if(H5B2_get_nrec(grp_oloc->file, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, &linfo->nlinks) < 0) + if(H5B2_get_nrec(bt2_name, &linfo->nlinks) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve # of records in index") } /* end if */ else { @@ -272,6 +348,10 @@ H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo, hid_t dxpl_id) } /* end if */ done: + /* Release resources */ + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_obj_get_linfo() */ @@ -369,6 +449,8 @@ herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, hbool_t adj_link, hid_t dxpl_id) { + H5O_pline_t tmp_pline; /* Pipeline message */ + H5O_pline_t *pline = NULL; /* Pointer to pipeline message */ H5O_linfo_t linfo; /* Link info message */ htri_t linfo_exists; /* Whether the link info message exists */ hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for insertions or not */ @@ -420,11 +502,21 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, else if(linfo.nlinks < ginfo.max_compact && link_msg_size < H5O_MESG_MAX_SIZE) use_new_dense = FALSE; else { + htri_t pline_exists; /* Whether the pipeline message exists */ H5G_obj_oh_it_ud1_t udata; /* User data for iteration */ H5O_mesg_operator_t op; /* Message operator */ + /* Get the pipeline message, if it exists */ + if((pline_exists = H5O_msg_exists(grp_oloc, H5O_PLINE_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") + if(pline_exists) { + if(NULL == H5O_msg_read(grp_oloc, H5O_PLINE_ID, &tmp_pline, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline") + pline = &tmp_pline; + } /* end if */ + /* The group doesn't currently have "dense" storage for links */ - if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo) < 0) + if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo, pline) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create 'dense' form of new format group") /* Set up user data for object header message iteration */ @@ -529,6 +621,10 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, } /* end if */ done: + /* Free any space used by the pipeline message */ + if(pline && H5O_msg_reset(H5O_PLINE_ID, pline) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "can't release pipeline") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_obj_insert() */ diff --git a/src/H5Goh.c b/src/H5Goh.c index d727cb7..2494838 100644 --- a/src/H5Goh.c +++ b/src/H5Goh.c @@ -45,12 +45,16 @@ /* Local Prototypes */ /********************/ +static void *H5O_group_get_copy_file_udata(void); +static void H5O_group_free_copy_file_udata(void *udata); static htri_t H5O_group_isa(H5O_t *loc); static hid_t H5O_group_open(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref); static void *H5O_group_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id); static H5O_loc_t *H5O_group_get_oloc(hid_t obj_id); +static herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5_ih_info_t *bh_info); /*********************/ @@ -71,14 +75,84 @@ static H5O_loc_t *H5O_group_get_oloc(hid_t obj_id); const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{ H5O_TYPE_GROUP, /* object type */ "group", /* object name, for debugging */ - NULL, /* get 'copy file' user data */ - NULL, /* free 'copy file' user data */ + H5O_group_get_copy_file_udata, /* get 'copy file' user data */ + H5O_group_free_copy_file_udata, /* free 'copy file' user data */ H5O_group_isa, /* "isa" message */ H5O_group_open, /* open an object of this class */ H5O_group_create, /* create an object of this class */ - H5O_group_get_oloc /* get an object header location for an object */ + H5O_group_get_oloc, /* get an object header location for an object */ + H5O_group_bh_info /* get the index & heap info for an object */ }}; +/* Declare the external free list to manage the H5O_ginfo_t struct */ +H5FL_DEFINE(H5G_copy_file_ud_t); + + +/*------------------------------------------------------------------------- + * Function: H5O_group_get_copy_file_udata + * + * Purpose: Allocates the user data needed for copying a group's + * object header from file to file. + * + * Return: Success: Non-NULL pointer to user data + * + * Failure: NULL + * + * Programmer: Neil Fortner + * Thursday, July 30, 2009 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_group_get_copy_file_udata(void) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_group_get_copy_file_udata) + + /* Allocate space for the 'copy file' user data for copying groups. + * Currently this is only a ginfo, so there is no specific struct type for + * this operation. */ + if(NULL == (ret_value = H5FL_CALLOC(H5G_copy_file_ud_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_group_get_copy_file_udata() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_group_free_copy_file_udata + * + * Purpose: Release the user data needed for copying a group's + * object header from file to file. + * + * Return: <none> + * + * Programmer: Neil Fortner + * Thursday, July 30, 2009 + * + *------------------------------------------------------------------------- + */ +static void +H5O_group_free_copy_file_udata(void *_udata) +{ + H5G_copy_file_ud_t *udata = (H5G_copy_file_ud_t *)_udata; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_group_free_copy_file_udata) + + /* Sanity check */ + HDassert(udata); + + /* Free the ginfo struct (including nested data structs) */ + H5O_msg_free(H5O_PLINE_ID, udata->common.src_pline); + + /* Release space for 'copy file' user data (ginfo struct) */ + (void)H5FL_FREE(H5G_copy_file_ud_t, udata); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5O_group_free_copy_file_udata() */ + /*------------------------------------------------------------------------- * Function: H5O_group_isa @@ -257,14 +331,16 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) { htri_t exists; /* Flag if header message of interest exists */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_group_bh_info, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5O_group_bh_info) /* Sanity check */ HDassert(f); @@ -281,30 +357,37 @@ H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_LINFO_ID, &linfo)) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't read LINFO message") - /* Get creation order B-tree size, if available */ - if(H5F_addr_defined(linfo.corder_bt2_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5G_BT2_CORDER, linfo.corder_bt2_addr, &bh_info->index_size) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + /* Check if name index available */ + if(H5F_addr_defined(linfo.name_bt2_addr)) { + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, linfo.name_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") - /* Get name order B-tree size, if available */ - if(H5F_addr_defined(linfo.name_bt2_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5G_BT2_NAME, linfo.name_bt2_addr, &bh_info->index_size) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + /* Get name index B-tree size */ + if(H5B2_size(bt2_name, dxpl_id, &bh_info->index_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info for name index") + } /* end if */ + + /* Check if creation order index available */ + if(H5F_addr_defined(linfo.corder_bt2_addr)) { + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, linfo.corder_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + + /* Get creation order index B-tree size */ + if(H5B2_size(bt2_corder, dxpl_id, &bh_info->index_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info for creation order index") + } /* end if */ /* Get fractal heap size, if available */ if(H5F_addr_defined(linfo.fheap_addr)) { /* Open the fractal heap for links */ if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo.fheap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Get heap storage size */ if(H5HF_size(fheap, dxpl_id, &bh_info->heap_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info") - - /* Release the fractal heap */ - if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") - fheap = NULL; + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info") } /* end if */ } /* end if */ else { @@ -322,7 +405,11 @@ H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_group_bh_info() */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 3d25109..80c4a7b 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -501,7 +501,8 @@ H5_DLL H5G_obj_t H5G_compact_get_type_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, /* Functions that understand "dense" link storage */ H5_DLL herr_t H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, H5G_link_table_t *ltable); -H5_DLL herr_t H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo); +H5_DLL herr_t H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, + const H5O_pline_t *pline); H5_DLL herr_t H5G_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, const H5O_link_t *lnk); H5_DLL htri_t H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, @@ -528,8 +529,11 @@ H5_DLL H5G_obj_t H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id, #endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Functions that understand group objects */ -H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - const H5O_linfo_t *linfo, hid_t gcpl_id, H5O_loc_t *oloc/*out*/); +H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, + H5O_loc_t *oloc/*out*/); +H5_DLL herr_t H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, + const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id, + H5O_loc_t *oloc/*out*/); H5_DLL htri_t H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo, hid_t dxpl_id); H5_DLL herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index ff20fe6..526fa82 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -141,6 +141,11 @@ typedef struct { H5G_name_t *path; /* Group hierarchy path */ } H5G_loc_t; +/* Callback information for copying groups */ +typedef struct H5G_copy_file_ud_t { + H5O_copy_file_ud_common_t common; /* Shared information (must be first) */ +} H5G_copy_file_ud_t; + typedef struct H5G_t H5G_t; typedef struct H5G_shared_t H5G_shared_t; typedef struct H5G_entry_t H5G_entry_t; diff --git a/src/H5Groot.c b/src/H5Groot.c index 5d07142..7dc98d1 100644 --- a/src/H5Groot.c +++ b/src/H5Groot.c @@ -137,25 +137,9 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) * with a hard link count of one since it's pointed to by the superblock. */ if(create_root) { - H5P_genplist_t *fc_plist; /* File creation property list */ - H5O_ginfo_t ginfo; /* Group info parameters */ - H5O_linfo_t linfo; /* Link info parameters */ - - /* Get the file creation property list */ - /* (Which is a sub-class of the group creation property class) */ - if(NULL == (fc_plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - /* Get the group info property */ - if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info") - - /* Get the link info property */ - if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") - /* Create root group */ - if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0) + /* (Pass the FCPL which is a sub-class of the group creation property class) */ + if(H5G_obj_create(f, dxpl_id, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") if(1 != H5O_link(root_loc.oloc, 1, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") diff --git a/src/H5Gtest.c b/src/H5Gtest.c index f3508eb..791c13a 100644 --- a/src/H5Gtest.c +++ b/src/H5Gtest.c @@ -382,6 +382,8 @@ done: herr_t H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count) { + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ H5O_linfo_t linfo; /* Link info message */ H5G_t *grp = NULL; /* Pointer to group */ herr_t ret_value = SUCCEED; /* Return value */ @@ -402,20 +404,34 @@ H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count) if(!H5F_addr_defined(linfo.name_bt2_addr)) HGOTO_DONE(FAIL) + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(grp->oloc.file, H5AC_dxpl_id, linfo.name_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Retrieve # of records in name index */ - if(H5B2_get_nrec(grp->oloc.file, H5AC_dxpl_id, H5G_BT2_NAME, linfo.name_bt2_addr, name_count) < 0) + if(H5B2_get_nrec(bt2_name, name_count) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") /* Check if there is a creation order index */ if(H5F_addr_defined(linfo.corder_bt2_addr)) { + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2_corder = H5B2_open(grp->oloc.file, H5AC_dxpl_id, linfo.corder_bt2_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + /* Retrieve # of records in creation order index */ - if(H5B2_get_nrec(grp->oloc.file, H5AC_dxpl_id, H5G_BT2_CORDER, linfo.corder_bt2_addr, corder_count) < 0) + if(H5B2_get_nrec(bt2_corder, corder_count) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index") } /* end if */ else *corder_count = 0; done: + /* Release resources */ + if(bt2_name && H5B2_close(bt2_name, H5AC_dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, H5AC_dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index") + FUNC_LEAVE_NOAPI(ret_value) } /* H5G_new_dense_info_test() */ diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 87ebc74..4c287d5 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -711,12 +711,15 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, if(target & H5G_CRT_INTMD_GROUP) { const H5O_ginfo_t def_ginfo = H5G_CRT_GROUP_INFO_DEF; /* Default group info settings */ const H5O_linfo_t def_linfo = H5G_CRT_LINK_INFO_DEF; /* Default link info settings */ + const H5O_pline_t def_pline = H5O_CRT_PIPELINE_DEF; /* Default filter pipeline settings */ H5O_ginfo_t par_ginfo; /* Group info settings for parent group */ H5O_linfo_t par_linfo; /* Link info settings for parent group */ + H5O_pline_t par_pline; /* Filter pipeline settings for parent group */ H5O_linfo_t tmp_linfo; /* Temporary link info settings */ htri_t exists; /* Whether a group or link info message exists */ const H5O_ginfo_t *ginfo; /* Group info settings for new group */ const H5O_linfo_t *linfo; /* Link info settings for new group */ + const H5O_pline_t *pline; /* Filter pipeline settings for new group */ /* Check for the parent group having a group info message */ /* (OK if not found) */ @@ -752,9 +755,25 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Use default link info settings */ linfo = &def_linfo; + /* Check for the parent group having a filter pipeline message */ + /* (OK if not found) */ + if((exists = H5O_msg_exists(grp_loc.oloc, H5O_PLINE_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") + if(exists) { + /* Get the filter pipeline for parent group */ + if(NULL == H5O_msg_read(grp_loc.oloc, H5O_PLINE_ID, &par_pline, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "filter pipeline message not present") + + /* Use parent filter pipeline settings */ + pline = &par_pline; + } /* end if */ + else + /* Use default filter pipeline settings */ + pline = &def_pline; + /* Create the intermediate group */ /* XXX: Should we allow user to control the group creation params here? -QAK */ - if(H5G_obj_create(grp_oloc.file, dxpl_id, ginfo, linfo, H5P_GROUP_CREATE_DEFAULT, obj_loc.oloc/*out*/) < 0) + if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, pline, H5P_GROUP_CREATE_DEFAULT, obj_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") /* Insert new group into current group's symbol table */ @@ -172,7 +172,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); /* Allocate fractal heap wrapper */ if(NULL == (fh = H5FL_MALLOC(H5HF_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info") + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed for fractal heap info") /* Lock the heap header into memory */ if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE))) @@ -196,10 +196,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC); done: if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header") - if(!ret_value) { - if(fh) - (void)H5HF_close(fh, dxpl_id); - } /* end if */ + if(!ret_value && fh) + if(H5HF_close(fh, dxpl_id) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, NULL, "unable to close fractal heap") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_create() */ @@ -250,7 +249,7 @@ HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fs /* Create fractal heap info */ if(NULL == (fh = H5FL_MALLOC(H5HF_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info") + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed for fractal heap info") /* Point fractal heap wrapper at header */ fh->hdr = hdr; @@ -270,10 +269,9 @@ HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fs done: if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header") - if(!ret_value) { - if(fh) - (void)H5HF_close(fh, dxpl_id); - } /* end if */ + if(!ret_value && fh) + if(H5HF_close(fh, dxpl_id) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, NULL, "unable to close fractal heap") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_open() */ @@ -324,7 +322,7 @@ H5HF_get_id_len(H5HF_t *fh, size_t *id_len_p) *------------------------------------------------------------------------- */ herr_t -H5HF_get_heap_addr(H5HF_t *fh, haddr_t *heap_addr_p) +H5HF_get_heap_addr(const H5HF_t *fh, haddr_t *heap_addr_p) { FUNC_ENTER_NOAPI_NOFUNC(H5HF_get_heap_addr) diff --git a/src/H5HFbtree2.c b/src/H5HFbtree2.c index 5958c03..ae50bf3 100644 --- a/src/H5HFbtree2.c +++ b/src/H5HFbtree2.c @@ -102,6 +102,7 @@ static herr_t H5HF_huge_btree2_filt_dir_debug(FILE *stream, const H5F_t *f, hid_ /* v2 B-tree class for indirectly accessed 'huge' objects */ const H5B2_class_t H5HF_BT2_INDIR[1]={{ /* B-tree class information */ H5B2_FHEAP_HUGE_INDIR_ID, /* Type of B-tree */ + "H5B2_FHEAP_HUGE_INDIR_ID", /* Name of B-tree class */ sizeof(H5HF_huge_bt2_indir_rec_t), /* Size of native record */ H5HF_huge_btree2_indir_store, /* Record storage callback */ H5HF_huge_btree2_indir_compare, /* Record comparison callback */ @@ -111,8 +112,9 @@ const H5B2_class_t H5HF_BT2_INDIR[1]={{ /* B-tree class information */ }}; /* v2 B-tree class for indirectly accessed, filtered 'huge' objects */ -const H5B2_class_t H5HF_BT2_FILT_INDIR[1]={{ /* B-tree class information */ +const H5B2_class_t H5HF_BT2_FILT_INDIR[1]={{ /* B-tree class information */ H5B2_FHEAP_HUGE_FILT_INDIR_ID, /* Type of B-tree */ + "H5B2_FHEAP_HUGE_FILT_INDIR_ID", /* Name of B-tree class */ sizeof(H5HF_huge_bt2_filt_indir_rec_t), /* Size of native record */ H5HF_huge_btree2_filt_indir_store, /* Record storage callback */ H5HF_huge_btree2_filt_indir_compare, /* Record comparison callback */ @@ -122,8 +124,9 @@ const H5B2_class_t H5HF_BT2_FILT_INDIR[1]={{ /* B-tree class information */ }}; /* v2 B-tree class for directly accessed 'huge' objects */ -const H5B2_class_t H5HF_BT2_DIR[1]={{ /* B-tree class information */ +const H5B2_class_t H5HF_BT2_DIR[1]={{ /* B-tree class information */ H5B2_FHEAP_HUGE_DIR_ID, /* Type of B-tree */ + "H5B2_FHEAP_HUGE_DIR_ID", /* Name of B-tree class */ sizeof(H5HF_huge_bt2_dir_rec_t), /* Size of native record */ H5HF_huge_btree2_dir_store, /* Record storage callback */ H5HF_huge_btree2_dir_compare, /* Record comparison callback */ @@ -133,8 +136,9 @@ const H5B2_class_t H5HF_BT2_DIR[1]={{ /* B-tree class information */ }}; /* v2 B-tree class for directly accessed, filtered 'huge' objects */ -const H5B2_class_t H5HF_BT2_FILT_DIR[1]={{ /* B-tree class information */ +const H5B2_class_t H5HF_BT2_FILT_DIR[1]={{ /* B-tree class information */ H5B2_FHEAP_HUGE_FILT_DIR_ID, /* Type of B-tree */ + "H5B2_FHEAP_HUGE_FILT_DIR_ID", /* Name of B-tree class */ sizeof(H5HF_huge_bt2_filt_dir_rec_t),/* Size of native record */ H5HF_huge_btree2_filt_dir_store, /* Record storage callback */ H5HF_huge_btree2_filt_dir_compare, /* Record comparison callback */ diff --git a/src/H5HFcache.c b/src/H5HFcache.c index b5d7cb5..6669853 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -294,7 +294,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer") /* Compute the 'base' size of the fractal heap header on disk */ - size = H5HF_HEADER_SIZE(hdr); + size = (size_t)H5HF_HEADER_SIZE(hdr); /* Get a pointer to a buffer that's large enough for serialized header */ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) @@ -364,9 +364,9 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); filter_info_off = (size_t)(p - buf); /* Compute the size of the extra filter information */ - filter_info_size = hdr->sizeof_size /* Size of size for filtered root direct block */ - + 4 /* Size of filter mask for filtered root direct block */ - + hdr->filter_len; /* Size of encoded I/O filter info */ + filter_info_size = (size_t)(hdr->sizeof_size /* Size of size for filtered root direct block */ + + (unsigned)4 /* Size of filter mask for filtered root direct block */ + + hdr->filter_len); /* Size of encoded I/O filter info */ /* Compute the heap header's size */ hdr->heap_size = size + filter_info_size; @@ -434,7 +434,8 @@ done: if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") if(!ret_value && hdr) - (void)H5HF_cache_hdr_dest(f, hdr); + if(H5HF_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -482,9 +483,6 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a uint8_t heap_flags; /* Status flags for heap */ uint32_t metadata_chksum; /* Computed metadata checksum value */ - /* Sanity check */ - HDassert(hdr->dirty); - /* Set the shared heap header's file context for this operation */ hdr->f = f; @@ -569,7 +567,6 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a if(H5F_block_write(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap header to disk") - hdr->dirty = FALSE; hdr->cache_info.is_dirty = FALSE; } /* end if */ @@ -623,16 +620,9 @@ H5HF_cache_hdr_dest(H5F_t *f, H5HF_hdr_t *hdr) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap header") } /* end if */ - /* Free the block size lookup table for the doubling table */ - H5HF_dtable_dest(&hdr->man_dtable); - - /* Release any I/O pipeline filter information */ - if(hdr->pline.nused) - H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline)); - /* Free the shared info itself */ - (void)H5FL_FREE(H5HF_hdr_t, hdr); - + if(H5HF_hdr_free(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "unable to release fractal heap header") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_cache_hdr_dest() */ @@ -1445,7 +1435,7 @@ HDfprintf(stderr, "%s: nbytes = %Zu, read_size = %Zu, read_buf = %p\n", FUNC, nb } /* end if */ /* Sanity check */ - HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); + HDassert((size_t)(p - dblock->blk) == (size_t)H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); /* Set return value */ ret_value = dblock; @@ -1533,7 +1523,7 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, } /* end if */ /* Sanity check */ - HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); + HDassert((size_t)(p - dblock->blk) == (size_t)H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); /* Check for I/O filters on this heap */ if(hdr->filter_len > 0) { diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index d1f2675..c326a59 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -79,7 +79,7 @@ /*********************/ /* Declare a free list to manage the H5HF_hdr_t struct */ -H5FL_DEFINE(H5HF_hdr_t); +H5FL_DEFINE_STATIC(H5HF_hdr_t); /*****************************/ @@ -110,7 +110,7 @@ H5HF_hdr_t * H5HF_hdr_alloc(H5F_t *f) { H5HF_hdr_t *hdr = NULL; /* Shared fractal heap header */ - H5HF_hdr_t *ret_value = NULL; /* Return value */ + H5HF_hdr_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_alloc) @@ -121,7 +121,7 @@ H5HF_hdr_alloc(H5F_t *f) /* Allocate space for the shared information */ if(NULL == (hdr = H5FL_CALLOC(H5HF_hdr_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared header") + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "allocation failed for fractal heap shared header") /* Set the internal parameters for the heap */ hdr->f = f; @@ -132,9 +132,9 @@ H5HF_hdr_alloc(H5F_t *f) ret_value = hdr; done: - if(!ret_value) - if(hdr) - (void)H5HF_cache_hdr_dest(f, hdr); + if(!ret_value && hdr) + if(H5HF_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_alloc() */ @@ -409,9 +409,6 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Set "huge" object tracker v2 B-tree address to indicate that there aren't any yet */ hdr->huge_bt2_addr = HADDR_UNDEF; - /* Note that the shared info is dirty (it's not written to the file yet) */ - hdr->dirty = TRUE; - /* First phase of header final initialization */ /* (doesn't need ID length set up) */ if(H5HF_hdr_finish_init_phase1(hdr) < 0) @@ -423,6 +420,17 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) * length is already set in that case (its stored in the header on disk)) */ if(cparam->pline.nused > 0) { + /* Check if the filters in the DCPL can be applied to this dataset */ + if(H5Z_can_apply_direct(&(cparam->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "I/O filters can't operate on this heap") + + /* Mark the filters as checked */ + hdr->checked_filters = TRUE; + + /* Make the "set local" filter callbacks for this dataset */ + if(H5Z_set_local_direct(&(cparam->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "unable to set local filter parameters") + /* Copy the I/O filter pipeline from the creation parameters to the header */ if(NULL == H5O_msg_copy(H5O_PLINE_ID, &(cparam->pline), &(hdr->pline))) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, HADDR_UNDEF, "can't copy I/O filter pipeline") @@ -430,7 +438,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Pay attention to the latest version flag for the file */ if(H5F_USE_LATEST_FORMAT(hdr->f)) /* Set the latest version for the I/O pipeline message */ - if(H5Z_set_latest_version(&(hdr->pline)) < 0) + if(H5O_pline_set_latest_version(&(hdr->pline)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, HADDR_UNDEF, "can't set latest version of I/O filter pipeline") /* Compute the I/O filters' encoded size */ @@ -446,10 +454,14 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", FUNC, hdr->filter_len); + 4 /* Size of filter mask for filtered root direct block */ + hdr->filter_len; /* Size of encoded I/O filter info */ } /* end if */ - else + else { /* Set size of header on disk */ hdr->heap_size = H5HF_HEADER_SIZE(hdr); + /* Mark filters as checked, for performance reasons */ + hdr->checked_filters = TRUE; + } /* end else */ + /* Set the length of IDs in the heap */ /* (This code is not in the "finish init phase" routines because those * routines are also called from the cache 'load' callback, and the ID @@ -457,7 +469,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", FUNC, hdr->filter_len); */ switch(cparam->id_len) { case 0: /* Set the length of heap IDs to just enough to hold the offset & length of 'normal' objects in the heap */ - hdr->id_len = 1 + hdr->heap_off_size + hdr->heap_len_size; + hdr->id_len = (unsigned)1 + hdr->heap_off_size + hdr->heap_len_size; break; case 1: /* Set the length of heap IDs to just enough to hold the information needed to directly access 'huge' objects in the heap */ @@ -505,15 +517,15 @@ HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); /* Cache the new fractal heap header */ if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't add fractal heap header to cache") + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, HADDR_UNDEF, "can't add fractal heap header to cache") /* Set address of heap header to return */ ret_value = hdr->heap_addr; done: - if(!H5F_addr_defined(ret_value)) - if(hdr) - (void)H5HF_cache_hdr_dest(NULL, hdr); + if(!H5F_addr_defined(ret_value) && hdr) + if(H5HF_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, HADDR_UNDEF, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_create() */ @@ -681,9 +693,6 @@ HDfprintf(stderr, "%s: Marking heap header as dirty\n", FUNC); if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark fractal heap header as dirty") - /* Set the dirty flags for the heap header */ - hdr->dirty = TRUE; - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_dirty() */ @@ -1493,6 +1502,43 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_hdr_free + * + * Purpose: Free shared fractal heap header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 27 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_hdr_free(H5HF_hdr_t *hdr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_free) + + /* + * Check arguments. + */ + HDassert(hdr); + + /* Free the block size lookup table for the doubling table */ + H5HF_dtable_dest(&hdr->man_dtable); + + /* Release any I/O pipeline filter information */ + if(hdr->pline.nused) + H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline)); + + /* Free the shared info itself */ + hdr = H5FL_FREE(H5HF_hdr_t, hdr); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_hdr_free() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_hdr_delete * * Purpose: Delete a fractal heap, starting with the header @@ -1508,8 +1554,8 @@ done: herr_t H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id) { - unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap header */ - herr_t ret_value = SUCCEED; + unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_hdr_delete, FAIL) diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c index 792a865..353ceb3 100644 --- a/src/H5HFhuge.c +++ b/src/H5HFhuge.c @@ -105,8 +105,7 @@ static herr_t H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, static herr_t H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id) { - const H5B2_class_t *bt2_class; /* v2 B-tree class to use */ - size_t rrec_size; /* Size of 'raw' records on disk */ + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_create) @@ -125,40 +124,46 @@ H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id) */ if(hdr->huge_ids_direct) { if(hdr->filter_len > 0) { - rrec_size = hdr->sizeof_addr /* Address of object */ + bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of object */ + hdr->sizeof_size /* Length of object */ + 4 /* Filter mask for filtered object */ - + hdr->sizeof_size; /* Size of de-filtered object in memory */ - bt2_class = H5HF_BT2_FILT_DIR; + + hdr->sizeof_size); /* Size of de-filtered object in memory */ + bt2_cparam.cls = H5HF_BT2_FILT_DIR; } /* end if */ else { - rrec_size = hdr->sizeof_addr /* Address of object */ - + hdr->sizeof_size; /* Length of object */ - bt2_class = H5HF_BT2_DIR; + bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of object */ + + hdr->sizeof_size); /* Length of object */ + bt2_cparam.cls = H5HF_BT2_DIR; } /* end else */ } /* end if */ else { - if (hdr->filter_len > 0) { - rrec_size = hdr->sizeof_addr /* Address of filtered object */ + if(hdr->filter_len > 0) { + bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of filtered object */ + hdr->sizeof_size /* Length of filtered object */ + 4 /* Filter mask for filtered object */ + hdr->sizeof_size /* Size of de-filtered object in memory */ - + hdr->sizeof_size; /* Unique ID for object */ - bt2_class = H5HF_BT2_FILT_INDIR; + + hdr->sizeof_size); /* Unique ID for object */ + bt2_cparam.cls = H5HF_BT2_FILT_INDIR; } /* end if */ else { - rrec_size = hdr->sizeof_addr /* Address of object */ + bt2_cparam.rrec_size = (size_t)(hdr->sizeof_addr /* Address of object */ + hdr->sizeof_size /* Length of object */ - + hdr->sizeof_size; /* Unique ID for object */ - bt2_class = H5HF_BT2_INDIR; + + hdr->sizeof_size); /* Unique ID for object */ + bt2_cparam.cls = H5HF_BT2_INDIR; } /* end else */ } /* end else */ + bt2_cparam.node_size = (size_t)H5HF_HUGE_BT2_NODE_SIZE; + bt2_cparam.split_percent = H5HF_HUGE_BT2_SPLIT_PERC; + bt2_cparam.merge_percent = H5HF_HUGE_BT2_MERGE_PERC; /* Create v2 B-tree for tracking 'huge' objects */ - if(H5B2_create(hdr->f, dxpl_id, bt2_class, (size_t)H5HF_HUGE_BT2_NODE_SIZE, rrec_size, - H5HF_HUGE_BT2_SPLIT_PERC, H5HF_HUGE_BT2_MERGE_PERC, &hdr->huge_bt2_addr/*out*/) < 0) + if(NULL == (hdr->huge_bt2 = H5B2_create(hdr->f, dxpl_id, &bt2_cparam))) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects") + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(hdr->huge_bt2, &hdr->huge_bt2_addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get v2 B-tree address for tracking 'huge' heap objects") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_huge_bt2_create() */ @@ -198,12 +203,12 @@ HDfprintf(stderr, "%s: hdr->id_len = %u\n", "H5HF_huge_init", (unsigned)hdr->id_ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr->filter_len); #endif /* QAK */ if(hdr->filter_len > 0) { - if((hdr->id_len - 1) >= (hdr->sizeof_addr + hdr->sizeof_size + 4 + hdr->sizeof_size)) { + if((hdr->id_len - 1) >= (unsigned)(hdr->sizeof_addr + hdr->sizeof_size + 4 + hdr->sizeof_size)) { /* Indicate that v2 B-tree doesn't have to be used to locate object */ hdr->huge_ids_direct = TRUE; /* Set the size of 'huge' object IDs */ - hdr->huge_id_size = hdr->sizeof_addr + hdr->sizeof_size + hdr->sizeof_size; + hdr->huge_id_size = (uint8_t)(hdr->sizeof_addr + hdr->sizeof_size + hdr->sizeof_size); } /* end if */ else /* Indicate that v2 B-tree must be used to access object */ @@ -215,7 +220,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr- hdr->huge_ids_direct = TRUE; /* Set the size of 'huge' object IDs */ - hdr->huge_id_size = hdr->sizeof_addr + hdr->sizeof_size; + hdr->huge_id_size = (uint8_t)(hdr->sizeof_addr + hdr->sizeof_size); } /* end if */ else /* Indicate that v2 B-tree must be used to locate object */ @@ -224,7 +229,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr- if(!hdr->huge_ids_direct) { /* Set the size and maximum value of 'huge' object ID */ if((hdr->id_len - 1) < sizeof(hsize_t)) { - hdr->huge_id_size = hdr->id_len - 1; + hdr->huge_id_size = (uint8_t)(hdr->id_len - 1); hdr->huge_max_id = ((hsize_t)1 << (hdr->huge_id_size * 8)) - 1; } /*end if */ else { @@ -232,6 +237,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr- hdr->huge_max_id = HSIZET_MAX; } /* end else */ } /* end if */ + hdr->huge_bt2 = NULL; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_huge_init() */ @@ -324,9 +330,20 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size); HDassert(id); /* Check if the v2 B-tree for tracking 'huge' heap objects has been created yet */ - if(!H5F_addr_defined(hdr->huge_bt2_addr)) + if(!H5F_addr_defined(hdr->huge_bt2_addr)) { + /* Go create (& open) v2 B-tree */ if(H5HF_huge_bt2_create(hdr, dxpl_id) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects") + } /* end if */ + else { + /* Check if v2 B-tree is open yet */ + if(NULL == hdr->huge_bt2) { + /* Open existing v2 B-tree */ + if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects") + } /* end if */ + } /* end else */ + HDassert(hdr->huge_bt2); /* Check for I/O pipeline filter on heap */ if(hdr->filter_len > 0) { @@ -386,7 +403,7 @@ HDfprintf(stderr, "%s: obj_rec = {%a, %Hu, %x, %Hu}\n", FUNC, obj_rec.addr, obj_ #endif /* QAK */ /* Insert record for object in v2 B-tree */ - if(H5B2_insert(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, &obj_rec) < 0) + if(H5B2_insert(hdr->huge_bt2, dxpl_id, &obj_rec) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree") /* Encode ID for user */ @@ -407,7 +424,7 @@ HDfprintf(stderr, "%s: obj_rec = {%a, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len); #endif /* QAK */ /* Insert record for object in v2 B-tree */ - if(H5B2_insert(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, &obj_rec) < 0) + if(H5B2_insert(hdr->huge_bt2, dxpl_id, &obj_rec) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree") /* Encode ID for user */ @@ -419,7 +436,6 @@ HDfprintf(stderr, "%s: obj_rec = {%a, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len); else { H5HF_huge_bt2_filt_indir_rec_t filt_indir_rec; /* Record for tracking filtered object */ H5HF_huge_bt2_indir_rec_t indir_rec; /* Record for tracking non-filtered object */ - const H5B2_class_t *bt2_class; /* v2 B-tree class to use */ void *ins_rec; /* Pointer to record to insert */ hsize_t new_id; /* New ID for object */ @@ -440,7 +456,6 @@ HDfprintf(stderr, "%s: filt_indir_rec = {%a, %Hu, %x, %Hu, %Hu}\n", FUNC, filt_i /* Set pointer to record to insert */ ins_rec = &filt_indir_rec; - bt2_class = H5HF_BT2_FILT_INDIR; } /* end if */ else { /* Initialize record for object in v2 B-tree */ @@ -453,11 +468,10 @@ HDfprintf(stderr, "%s: indir_rec = {%a, %Hu, %Hu}\n", FUNC, indir_rec.addr, indi /* Set pointer to record to insert */ ins_rec = &indir_rec; - bt2_class = H5HF_BT2_INDIR; } /* end else */ /* Insert record for tracking object in v2 B-tree */ - if(H5B2_insert(hdr->f, dxpl_id, bt2_class, hdr->huge_bt2_addr, ins_rec) < 0) + if(H5B2_insert(hdr->huge_bt2, dxpl_id, ins_rec) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree") /* Encode ID for user */ @@ -528,6 +542,13 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, } /* end else */ } /* end if */ else { + /* Check if v2 B-tree is open yet */ + if(NULL == hdr->huge_bt2) { + /* Open existing v2 B-tree */ + if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects") + } /* end if */ + if(hdr->filter_len > 0) { H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */ H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */ @@ -536,8 +557,7 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) != TRUE) + if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) != TRUE) HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") /* Retrieve the object's length */ @@ -551,8 +571,7 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE) + if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE) HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") /* Retrieve the object's length */ @@ -611,6 +630,16 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, UINT32DECODE(id, filter_mask); } /* end if */ else { + /* Sanity check */ + HDassert(H5F_addr_defined(hdr->huge_bt2_addr)); + + /* Check if v2 B-tree is open yet */ + if(NULL == hdr->huge_bt2) { + /* Open existing v2 B-tree */ + if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects") + } /* end if */ + if(hdr->filter_len > 0) { H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */ H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */ @@ -619,8 +648,7 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) != TRUE) + if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) != TRUE) HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") /* Retrieve the object's address & length */ @@ -636,8 +664,7 @@ H5HF_huge_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE) + if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE) HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") /* Retrieve the object's address & length */ @@ -751,12 +778,21 @@ H5HF_huge_write(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */ H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */ + /* Sanity check */ + HDassert(H5F_addr_defined(hdr->huge_bt2_addr)); + + /* Check if v2 B-tree is open yet */ + if(NULL == hdr->huge_bt2) { + /* Open existing v2 B-tree */ + if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects") + } /* end if */ + /* Get ID for looking up 'huge' object in v2 B-tree */ UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE) + if(H5B2_find(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_found, &found_rec) != TRUE) HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") /* Retrieve the object's address & length */ @@ -872,8 +908,16 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) * Check arguments. */ HDassert(hdr); + HDassert(H5F_addr_defined(hdr->huge_bt2_addr)); HDassert(id); + /* Check if v2 B-tree is open yet */ + if(NULL == hdr->huge_bt2) { + /* Open existing v2 B-tree */ + if(NULL == (hdr->huge_bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' heap objects") + } /* end if */ + /* Skip over the flag byte */ id++; @@ -893,8 +937,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) /* Remove the record for tracking the 'huge' object from the v2 B-tree */ /* (space in the file for the object is freed in the 'remove' callback) */ - if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_filt_dir_remove, &udata) < 0) + if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_dir_remove, &udata) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") } /* end if */ else { @@ -907,8 +950,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) /* Remove the record for tracking the 'huge' object from the v2 B-tree */ /* (space in the file for the object is freed in the 'remove' callback) */ - if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_dir_remove, &udata) < 0) + if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_dir_remove, &udata) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") } /* end else */ } /* end if */ @@ -921,8 +963,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) /* Remove the record for tracking the 'huge' object from the v2 B-tree */ /* (space in the file for the object is freed in the 'remove' callback) */ - if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_filt_indir_remove, &udata) < 0) + if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_filt_indir_remove, &udata) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") } /* end if */ else { @@ -933,8 +974,7 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) /* Remove the record for tracking the 'huge' object from the v2 B-tree */ /* (space in the file for the object is freed in the 'remove' callback) */ - if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_indir_remove, &udata) < 0) + if(H5B2_remove(hdr->huge_bt2, dxpl_id, &search_rec, H5HF_huge_bt2_indir_remove, &udata) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") } /* end else */ } /* end else */ @@ -977,6 +1017,17 @@ H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id) */ HDassert(hdr); + /* Check if v2 B-tree index is open */ + if(hdr->huge_bt2) { + /* Sanity check */ + HDassert(H5F_addr_defined(hdr->huge_bt2_addr)); + + /* Close v2 B-tree index */ + if(H5B2_close(hdr->huge_bt2, dxpl_id) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree") + hdr->huge_bt2 = NULL; + } /* end if */ + /* Check if there are no more 'huge' objects in the heap and delete the * v2 B-tree that tracks them, if so */ @@ -986,7 +1037,7 @@ H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id) /* Delete the v2 B-tree */ /* (any v2 B-tree class will work here) */ - if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, NULL, NULL) < 0) + if(H5B2_delete(hdr->f, dxpl_id, hdr->huge_bt2_addr, NULL, NULL) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") /* Reset the information about 'huge' objects in the file */ @@ -1022,6 +1073,7 @@ herr_t H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id) { H5HF_huge_remove_ud1_t udata; /* User callback data for v2 B-tree remove call */ + H5B2_remove_t op; /* Callback for v2 B-tree removal */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_delete) @@ -1038,28 +1090,24 @@ H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id) udata.hdr = hdr; udata.dxpl_id = dxpl_id; - /* Delete the v2 B-tree */ + /* Set the v2 B-tree callback operator */ if(hdr->huge_ids_direct) { - if(hdr->filter_len > 0) { - if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, H5HF_huge_bt2_filt_dir_remove, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") - } /* end if */ - else { - if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, H5HF_huge_bt2_dir_remove, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") - } /* end else */ + if(hdr->filter_len > 0) + op = H5HF_huge_bt2_filt_dir_remove; + else + op = H5HF_huge_bt2_dir_remove; } /* end if */ else { - if(hdr->filter_len > 0) { - if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, H5HF_huge_bt2_filt_indir_remove, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") - } /* end if */ - else { - if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, H5HF_huge_bt2_indir_remove, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") - } /* end else */ + if(hdr->filter_len > 0) + op = H5HF_huge_bt2_filt_indir_remove; + else + op = H5HF_huge_bt2_indir_remove; } /* end else */ + /* Delete the v2 B-tree */ + if(H5B2_delete(hdr->f, dxpl_id, hdr->huge_bt2_addr, op, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_huge_delete() */ diff --git a/src/H5HFman.c b/src/H5HFman.c index 5bdc769..3fb0cfb 100644 --- a/src/H5HFman.c +++ b/src/H5HFman.c @@ -44,6 +44,19 @@ /* Local Macros */ /****************/ +/* Macro to check if we can apply all filters in the pipeline. Use whenever + * performing a modification operation */ + #define H5HF_MAN_WRITE_CHECK_PLINE(HDR) \ +{ \ + if(!((HDR)->checked_filters)) { \ + if((HDR)->pline.nused) \ + if(H5Z_can_apply_direct(&((HDR)->pline)) < 0) \ + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "I/O filters can't operate on this heap") \ + \ + (HDR)->checked_filters = TRUE; \ + } /* end if */ \ +} + /******************/ /* Local Typedefs */ @@ -116,6 +129,9 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size); HDassert(obj); HDassert(id); + /* Check pipeline */ + H5HF_MAN_WRITE_CHECK_PLINE(hdr) + /* Look for free space */ if((node_found = H5HF_space_find(hdr, dxpl_id, (hsize_t)obj_size, &sec_node)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap") @@ -272,6 +288,9 @@ H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, /* Set the access mode for the direct block */ if(op_flags & H5HF_OP_MODIFY) { + /* Check pipeline */ + H5HF_MAN_WRITE_CHECK_PLINE(hdr) + dblock_access = H5AC_WRITE; dblock_cache_flags = H5AC__DIRTIED_FLAG; } /* end if */ @@ -533,6 +552,9 @@ H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) HDassert(hdr); HDassert(id); + /* Check pipeline */ + H5HF_MAN_WRITE_CHECK_PLINE(hdr) + /* Skip over the flag byte */ id++; diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index 3fe3ad2..dac6d39 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -335,25 +335,26 @@ typedef struct H5HF_hdr_t { /* Cached/computed values (not stored in header) */ size_t rc; /* Reference count of heap's components using heap header */ - hbool_t dirty; /* Shared info is modified */ haddr_t heap_addr; /* Address of heap header in the file */ size_t heap_size; /* Size of heap header in the file */ H5AC_protect_t mode; /* Access mode for heap */ H5F_t *f; /* Pointer to file for heap */ size_t file_rc; /* Reference count of files using heap header */ hbool_t pending_delete; /* Heap is pending deletion */ - size_t sizeof_size; /* Size of file sizes */ - size_t sizeof_addr; /* Size of file addresses */ + uint8_t sizeof_size; /* Size of file sizes */ + uint8_t sizeof_addr; /* Size of file addresses */ struct H5HF_indirect_t *root_iblock; /* Pointer to pinned root indirect block */ H5FS_t *fspace; /* Free space list for objects in heap */ H5HF_block_iter_t next_block; /* Block iterator for searching for next block with space */ + H5B2_t *huge_bt2; /* v2 B-tree handle for huge objects */ hsize_t huge_max_id; /* Max. 'huge' heap ID before rolling 'huge' heap IDs over */ + uint8_t huge_id_size; /* Size of 'huge' heap IDs (in bytes) */ hbool_t huge_ids_direct; /* Flag to indicate that 'huge' object's offset & length are stored directly in heap ID */ size_t tiny_max_len; /* Max. size of tiny objects for this heap */ hbool_t tiny_len_extended; /* Flag to indicate that 'tiny' object's length is stored in extended form (i.e. w/extra byte) */ - uint8_t huge_id_size; /* Size of 'huge' heap IDs (in bytes) */ - uint8_t heap_off_size; /* Size of heap offsets (in bytes) */ - uint8_t heap_len_size; /* Size of heap ID lengths (in bytes) */ + uint8_t heap_off_size; /* Size of heap offsets (in bytes) */ + uint8_t heap_len_size; /* Size of heap ID lengths (in bytes) */ + hbool_t checked_filters; /* TRUE if pipeline passes can_apply checks */ } H5HF_hdr_t; /* Common indirect block doubling table entry */ @@ -503,9 +504,6 @@ H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1]; /* H5HF indirect section inherits serializable properties from H5FS_section_class_t */ H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1]; -/* Declare a free list to manage the H5HF_hdr_t struct */ -H5FL_EXTERN(H5HF_hdr_t); - /* Declare a free list to manage the H5HF_indirect_t struct */ H5FL_EXTERN(H5HF_indirect_t); @@ -563,6 +561,7 @@ H5_DLL herr_t H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t dblock_addr); H5_DLL herr_t H5HF_hdr_reset_iter(H5HF_hdr_t *hdr, hsize_t curr_off); H5_DLL herr_t H5HF_hdr_empty(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_hdr_free(H5HF_hdr_t *hdr); H5_DLL herr_t H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id); /* Indirect block routines */ diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h index 790f5ea..55daa30 100644 --- a/src/H5HFprivate.h +++ b/src/H5HFprivate.h @@ -111,7 +111,7 @@ typedef herr_t (*H5HF_operator_t)(const void *obj/*in*/, size_t obj_len, H5_DLL H5HF_t *H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam); H5_DLL H5HF_t *H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr); H5_DLL herr_t H5HF_get_id_len(H5HF_t *fh, size_t *id_len_p/*out*/); -H5_DLL herr_t H5HF_get_heap_addr(H5HF_t *fh, haddr_t *heap_addr/*out*/); +H5_DLL herr_t H5HF_get_heap_addr(const H5HF_t *fh, haddr_t *heap_addr/*out*/); H5_DLL herr_t H5HF_insert(H5HF_t *fh, hid_t dxpl_id, size_t size, const void *obj, void *id/*out*/); H5_DLL herr_t H5HF_get_obj_len(H5HF_t *fh, hid_t dxpl_id, const void *id, diff --git a/src/H5HFstat.c b/src/H5HFstat.c index 8d6b2ba..fb535b9 100644 --- a/src/H5HFstat.c +++ b/src/H5HFstat.c @@ -126,9 +126,10 @@ H5HF_stat_info(const H5HF_t *fh, H5HF_stat_t *stats) herr_t H5HF_size(const H5HF_t *fh, hid_t dxpl_id, hsize_t *heap_size) { - H5HF_hdr_t *hdr; /* Fractal heap header */ - herr_t ret_value = SUCCEED; /* Return value */ - hsize_t meta_size = 0; /* free space storage size */ + H5HF_hdr_t *hdr; /* Fractal heap header */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ + hsize_t meta_size = 0; /* free space storage size */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_size, FAIL) @@ -151,35 +152,29 @@ H5HF_size(const H5HF_t *fh, hid_t dxpl_id, hsize_t *heap_size) if(H5HF_man_iblock_size(hdr->f, dxpl_id, hdr, hdr->man_dtable.table_addr, hdr->man_dtable.curr_root_rows, NULL, 0, heap_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to get fractal heap storage info for indirect block") - /* Get B-tree storage for huge objects in fractal heap */ + /* Check for B-tree storage of huge objects in fractal heap */ if(H5F_addr_defined(hdr->huge_bt2_addr)) { - const H5B2_class_t *huge_bt2_class; /* Class for huge v2 B-tree */ - - /* Determine the class of the huge v2 B-tree */ - if(hdr->huge_ids_direct) - if(hdr->filter_len > 0) - huge_bt2_class = H5HF_BT2_FILT_DIR; - else - huge_bt2_class = H5HF_BT2_DIR; - else - if(hdr->filter_len > 0) - huge_bt2_class = H5HF_BT2_FILT_INDIR; - else - huge_bt2_class = H5HF_BT2_INDIR; - - /* Get the B-tree storage for the appropriate class */ - if(H5B2_iterate_size(hdr->f, dxpl_id, huge_bt2_class, hdr->huge_bt2_addr, heap_size) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + /* Open the huge object index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(hdr->f, dxpl_id, hdr->huge_bt2_addr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for tracking 'huge' objects") + + /* Get the B-tree storage */ + if(H5B2_size(bt2, dxpl_id, heap_size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") } /* end if */ /* Get storage for free-space tracking info */ if(H5F_addr_defined(hdr->fs_addr)) { if(H5HF_space_size(hdr, dxpl_id, &meta_size) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't retrieve FS meta storage info") + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve FS meta storage info") *heap_size += meta_size; - } + } /* end if */ done: + /* Release resources */ + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for tracking 'huge' objects") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_size() */ diff --git a/src/H5HFtest.c b/src/H5HFtest.c index ab42735..30adf96 100644 --- a/src/H5HFtest.c +++ b/src/H5HFtest.c @@ -124,7 +124,7 @@ H5HF_get_cparam_test(const H5HF_t *fh, H5HF_create_t *cparam) int H5HF_cmp_cparam_test(const H5HF_create_t *cparam1, const H5HF_create_t *cparam2) { - int ret_value; /* Return value */ + int ret_value = 0; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cmp_cparam_test) @@ -133,8 +133,26 @@ H5HF_cmp_cparam_test(const H5HF_create_t *cparam1, const H5HF_create_t *cparam2) HDassert(cparam2); /* Compare doubling table parameters */ - if((ret_value = HDmemcmp(&(cparam1->managed), &(cparam2->managed), sizeof(H5HF_dtable_cparam_t)))) - HGOTO_DONE(ret_value) + if(cparam1->managed.width < cparam2->managed.width) + HGOTO_DONE(-1) + else if(cparam1->managed.width > cparam2->managed.width) + HGOTO_DONE(1) + if(cparam1->managed.start_block_size < cparam2->managed.start_block_size) + HGOTO_DONE(-1) + else if(cparam1->managed.start_block_size > cparam2->managed.start_block_size) + HGOTO_DONE(1) + if(cparam1->managed.max_direct_size < cparam2->managed.max_direct_size) + HGOTO_DONE(-1) + else if(cparam1->managed.max_direct_size > cparam2->managed.max_direct_size) + HGOTO_DONE(1) + if(cparam1->managed.max_index < cparam2->managed.max_index) + HGOTO_DONE(-1) + else if(cparam1->managed.max_index > cparam2->managed.max_index) + HGOTO_DONE(1) + if(cparam1->managed.start_root_rows < cparam2->managed.start_root_rows) + HGOTO_DONE(-1) + else if(cparam1->managed.start_root_rows > cparam2->managed.start_root_rows) + HGOTO_DONE(1) /* Compare other general parameters for heap */ if(cparam1->max_man_size < cparam2->max_man_size) @@ -310,7 +310,7 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr) * Find an ID for the new object. ID zero is reserved for the free space * object. */ - if(heap->nused<H5HG_MAXIDX) + if(heap->nused<=H5HG_MAXIDX) idx=heap->nused++; else { for (idx=1; idx<heap->nused; idx++) @@ -326,17 +326,21 @@ H5HG_alloc (H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned * heap_flags_ptr) H5HG_obj_t *new_obj; /* New array of object descriptions */ /* Determine the new number of objects to index */ - new_alloc=MAX(heap->nalloc*2,(idx+1)); - assert(new_alloc<=(H5HG_MAXIDX+1)); + /* nalloc is *not* guaranteed to be a power of 2! - NAF 10/26/09 */ + new_alloc = MIN(MAX(heap->nalloc * 2, (idx + 1)), (H5HG_MAXIDX + 1)); + HDassert(idx < new_alloc); /* Reallocate array of objects */ if (NULL==(new_obj = H5FL_SEQ_REALLOC (H5HG_obj_t, heap->obj, new_alloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed") + /* Clear newly allocated space */ + HDmemset(&new_obj[heap->nalloc], 0, (new_alloc - heap->nalloc) * sizeof(heap->obj[0])); + /* Update heap information */ heap->nalloc=new_alloc; heap->obj=new_obj; - assert(heap->nalloc>heap->nused); + HDassert(heap->nalloc>heap->nused); } /* end if */ /* Initialize the new object */ diff --git a/src/H5HGcache.c b/src/H5HGcache.c index f3d0f3a..ee318aa 100644 --- a/src/H5HGcache.c +++ b/src/H5HGcache.c @@ -171,11 +171,12 @@ H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1, /* Decode each object */ p = heap->chunk + H5HG_SIZEOF_HDR(f); nalloc = H5HG_NOBJS(f, heap->size); - if(NULL == (heap->obj = H5FL_SEQ_MALLOC(H5HG_obj_t, nalloc))) + + /* Calloc the obj array because the file format spec makes no guarantee + * about the order of the objects, and unused slots must be set to zero. + */ + if(NULL == (heap->obj = H5FL_SEQ_CALLOC(H5HG_obj_t, nalloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - heap->obj[0].nrefs = 0; - heap->obj[0].size = 0; - heap->obj[0].begin = NULL; heap->nalloc = nalloc; while(p < (heap->chunk + heap->size)) { @@ -202,14 +203,19 @@ H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1, /* Determine the new number of objects to index */ new_alloc = MAX(heap->nalloc * 2, (idx + 1)); + HDassert(idx < new_alloc); /* Reallocate array of objects */ if(NULL == (new_obj = H5FL_SEQ_REALLOC(H5HG_obj_t, heap->obj, new_alloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + /* Clear newly allocated space */ + HDmemset(&new_obj[heap->nalloc], 0, (new_alloc - heap->nalloc) * sizeof(heap->obj[0])); + /* Update heap information */ heap->nalloc = new_alloc; heap->obj = new_obj; + HDassert(heap->nalloc>heap->nused); } /* end if */ UINT16DECODE(p, heap->obj[idx].nrefs); @@ -220,16 +226,16 @@ H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1, /* * The total storage size includes the size of the object header * and is zero padded so the next object header is properly - * aligned. The last bit of space is the free space object whose - * size is never padded and already includes the object header. + * aligned. The entire obj array was calloc'ed, so no need to zero + * the space here. The last bit of space is the free space object + * whose size is never padded and already includes the object + * header. */ if(idx > 0) { need = H5HG_SIZEOF_OBJHDR(f) + H5HG_ALIGN(heap->obj[idx].size); - /* Check for "gap" in index numbers (caused by deletions) and fill in heap object values */ - if(idx > (max_idx + 1)) - HDmemset(&heap->obj[max_idx + 1], 0, sizeof(H5HG_obj_t) * (idx - (max_idx + 1))); - max_idx = idx; + if(idx > max_idx) + max_idx = idx; } /* end if */ else need = heap->obj[idx].size; diff --git a/src/H5HGdbg.c b/src/H5HGdbg.c index 7030da5..bda9832 100644 --- a/src/H5HGdbg.c +++ b/src/H5HGdbg.c @@ -93,7 +93,10 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, fprintf (stream, "%*s%-*s %u/%lu/", indent, "", fwidth, "Objects defined/allocated/max:", nused, (unsigned long)h->nalloc); - fprintf (stream, nused ? "%u\n": "NA\n", maxobj); + if(nused) + fprintf(stream, "%u\n", maxobj); + else + fprintf(stream, "NA\n"); fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth, "Free space:", @@ -716,7 +716,7 @@ H5Lget_val(hid_t loc_id, const char *name, void *buf/*out*/, size_t size, /* Get the link value */ if(H5L_get_val(&loc, name, buf, size, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value") + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value for '%s'", name) done: FUNC_LEAVE_API(ret_value) @@ -2120,7 +2120,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, +H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5L_trav_gv_t *udata = (H5L_trav_gv_t *)_udata; /* User data passed in */ @@ -2130,7 +2130,7 @@ H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H /* Check if the name in this group resolved to a valid link */ if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name) /* Retrieve the value for the link */ if(H5L_get_val_real(lnk, udata->buf, udata->size) < 0) diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 57414c7..640ac07 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -514,6 +514,7 @@ H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) { H5G_loc_t link_loc; /* Group location to create link */ + char *norm_obj_name = NULL; /* Pointer to normalized current name */ void *ext_link_buf = NULL; /* Buffer to contain external link */ size_t buf_size; /* Size of buffer to hold external link */ uint8_t *p; /* Pointer into external link buffer */ @@ -533,8 +534,12 @@ H5Lcreate_external(const char *file_name, const char *obj_name, if(!link_name || !*link_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified") + /* Get normalized copy of the link target */ + if(NULL == (norm_obj_name = H5G_normalize(obj_name))) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize object name") + /* Combine the filename and link name into a single buffer to give to the UD link */ - buf_size = 1 + (HDstrlen(file_name) + 1) + (HDstrlen(obj_name) + 1); + buf_size = 1 + (HDstrlen(file_name) + 1) + (HDstrlen(norm_obj_name) + 1); if(NULL == (ext_link_buf = H5MM_malloc(buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer") @@ -543,14 +548,14 @@ H5Lcreate_external(const char *file_name, const char *obj_name, *p++ = (H5L_EXT_VERSION << 4) | H5L_EXT_FLAGS_ALL; /* External link version & flags */ HDstrcpy((char *)p, file_name); /* Name of file containing external link's object */ p += HDstrlen(file_name) + 1; - HDstrcpy((char *)p, obj_name); /* External link's object */ + HDstrcpy((char *)p, norm_obj_name); /* External link's object */ /* Create an external link */ if(H5L_create_ud(&link_loc, link_name, ext_link_buf, buf_size, H5L_TYPE_EXTERNAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") done: - if(ext_link_buf != NULL) + if(norm_obj_name) H5MM_free(ext_link_buf); FUNC_LEAVE_API(ret_value) @@ -65,6 +65,13 @@ typedef enum { H5MF_AGGR_MERGE_TOGETHER /* Metadata & raw data in one free list */ } H5MF_aggr_merge_t; +/* User data for section info iterator callback for iterating over free space sections */ +typedef struct { + H5F_sect_info_t *sects; /* section info to be retrieved */ + size_t sect_count; /* # of sections requested */ + size_t sect_idx; /* the current count of sections */ +} H5MF_sect_iter_ud_t; + /********************/ /* Package Typedefs */ @@ -628,6 +635,12 @@ HDfprintf(stderr, "%s: Trying to avoid starting up free space manager\n", FUNC); else if(status > 0) /* Indicate success */ HGOTO_DONE(SUCCEED) + else if(size < f->shared->fs_threshold) { +#ifdef H5MF_ALLOC_DEBUG_MORE +HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size); +#endif /* H5MF_ALLOC_DEBUG_MORE */ + HGOTO_DONE(SUCCEED) + } } /* end if */ /* If we are deleting the free space manager, leave now, to avoid @@ -654,7 +667,6 @@ HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, a if(H5MF_alloc_start(f, dxpl_id, fs_type) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space") } /* end if */ - HDassert(f->shared->fs_man[fs_type]); /* Create free space section for block */ if(NULL == (node = H5MF_sect_simple_new(addr, size))) @@ -666,16 +678,31 @@ HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, a udata.alloc_type = alloc_type; udata.allow_sect_absorb = TRUE; - /* Add to the free space for the file */ + /* If size of section freed is larger than threshold, add it to the free space manager */ + if(size >= f->shared->fs_threshold) { + HDassert(f->shared->fs_man[fs_type]); + #ifdef H5MF_ALLOC_DEBUG_MORE HDfprintf(stderr, "%s: Before H5FS_sect_add()\n", FUNC); #endif /* H5MF_ALLOC_DEBUG_MORE */ - if(H5FS_sect_add(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space") - node = NULL; + /* Add to the free space for the file */ + if(H5FS_sect_add(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space") + node = NULL; #ifdef H5MF_ALLOC_DEBUG_MORE HDfprintf(stderr, "%s: After H5FS_sect_add()\n", FUNC); #endif /* H5MF_ALLOC_DEBUG_MORE */ + } /* end if */ + else { + htri_t merged; /* Whether node was merged */ + + /* Try to merge the section that is smaller than threshold */ + if((merged = H5FS_sect_try_merge(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata)) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't merge section to file free space") + else if(merged == TRUE) /* successfully merged */ + /* Indicate that the node was used */ + node = NULL; + } /* end else */ done: /* Release section node, if allocated and not added to section list or merged */ @@ -970,55 +997,147 @@ HDfprintf(stderr, "%s: Entering\n", FUNC); if(H5MF_free_aggrs(f, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators") - /* Iterate over all the free space types that have managers and get each free list's space */ - for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) { + /* Making free-space managers persistent for superblock version >= 2 */ + if(f->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2 + && f->shared->fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) { + H5O_fsinfo_t fsinfo; /* Free space manager info message */ + hbool_t update = FALSE; /* To update info for the message */ + + /* Check to remove free-space manager info message from superblock extension */ + if(H5F_addr_defined(f->shared->sblock->ext_addr)) + if(H5F_super_ext_remove_msg(f, dxpl_id, H5O_FSINFO_ID) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "error in removing message from superblock extension") + + /* Free free-space manager header and/or section info header */ + for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) { + H5FS_stat_t fs_stat; /* Information for free-space manager */ + + /* Check for free space manager of this type */ + if(f->shared->fs_man[type]) { + /* Switch to "about to be deleted" state */ + f->shared->fs_state[type] = H5F_FS_STATE_DELETING; + + /* Query the free space manager's information */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info") + + /* Check if the free space manager has space in the file */ + if(H5F_addr_defined(fs_stat.addr) || H5F_addr_defined(fs_stat.sect_addr)) { + /* Delete the free space manager in the file */ + /* (will re-allocate later) */ + if(H5FS_free(f, f->shared->fs_man[type], dxpl_id) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't release free-space headers") + f->shared->fs_addr[type] = HADDR_UNDEF; + } /* end if */ + } /* end iif */ + fsinfo.fs_addr[type-1] = HADDR_UNDEF; + } /* end for */ + + fsinfo.strategy = f->shared->fs_strategy; + fsinfo.threshold = f->shared->fs_threshold; + + /* Write free-space manager info message to superblock extension object header */ + /* Create the superblock extension object header in advance if needed */ + if(H5F_super_ext_write_msg(f, dxpl_id, &fsinfo, H5O_FSINFO_ID, TRUE) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension") + + /* Re-allocate free-space manager header and/or section info header */ + for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) { + H5FS_stat_t fs_stat; /* Information for free-space manager */ + + /* Check for active free space manager of this type */ + if(f->shared->fs_man[type]) { + /* Re-query free space manager info for this type */ + if(H5FS_stat_info(f, f->shared->fs_man[type], &fs_stat) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't get free-space info") + + /* Are there sections to persist? */ + if(fs_stat.serial_sect_count) { + /* Allocate space for free-space manager header */ + if(H5FS_alloc_hdr(f, f->shared->fs_man[type], &f->shared->fs_addr[type], dxpl_id) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "can't allocated free-space header") + + /* Allocate space for free-space maanger section info header */ + if(H5FS_alloc_sect(f, f->shared->fs_man[type], dxpl_id) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate free-space section info") + + HDassert(f->shared->fs_addr[type]); + fsinfo.fs_addr[type-1] = f->shared->fs_addr[type]; + update = TRUE; + } /* end if */ + } else if(H5F_addr_defined(f->shared->fs_addr[type])) { + fsinfo.fs_addr[type-1] = f->shared->fs_addr[type]; + update = TRUE; + } /* end else-if */ + } /* end for */ + + /* Update the free space manager info message in superblock extension object header */ + if(update) + if(H5F_super_ext_write_msg(f, dxpl_id, &fsinfo, H5O_FSINFO_ID, FALSE) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension") + + /* Final close of free-space managers */ + for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) { + if(f->shared->fs_man[type]) { + if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't close free space manager") + f->shared->fs_man[type] = NULL; + f->shared->fs_state[type] = H5F_FS_STATE_CLOSED; + } /* end if */ + f->shared->fs_addr[type] = HADDR_UNDEF; + } /* end for */ + } /* end if */ + else { /* super_vers can be 0, 1, 2 */ + /* Iterate over all the free space types that have managers and get each free list's space */ + for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) { #ifdef H5MF_ALLOC_DEBUG_MORE HDfprintf(stderr, "%s: Check 1.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", FUNC, (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]); #endif /* H5MF_ALLOC_DEBUG_MORE */ - /* If the free space manager for this type is open, close it */ - if(f->shared->fs_man[type]) { + /* If the free space manager for this type is open, close it */ + if(f->shared->fs_man[type]) { #ifdef H5MF_ALLOC_DEBUG_MORE HDfprintf(stderr, "%s: Before closing free space manager\n", FUNC); #endif /* H5MF_ALLOC_DEBUG_MORE */ - if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release free space info") - f->shared->fs_man[type] = NULL; - f->shared->fs_state[type] = H5F_FS_STATE_CLOSED; - } /* end if */ + if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release free space info") + f->shared->fs_man[type] = NULL; + f->shared->fs_state[type] = H5F_FS_STATE_CLOSED; + } /* end if */ #ifdef H5MF_ALLOC_DEBUG_MORE HDfprintf(stderr, "%s: Check 2.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", FUNC, (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]); #endif /* H5MF_ALLOC_DEBUG_MORE */ - /* If there is free space manager info for this type, delete it */ - /* (XXX: Make this optional when free space for a file can be persistant) */ - if(H5F_addr_defined(f->shared->fs_addr[type])) { - haddr_t tmp_fs_addr; /* Temporary holder for free space manager address */ + /* If there is free space manager info for this type, delete it */ + if(H5F_addr_defined(f->shared->fs_addr[type])) { + haddr_t tmp_fs_addr; /* Temporary holder for free space manager address */ - /* Put address into temporary variable and reset it */ - /* (Avoids loopback in file space freeing routine) */ - tmp_fs_addr = f->shared->fs_addr[type]; - f->shared->fs_addr[type] = HADDR_UNDEF; + /* Put address into temporary variable and reset it */ + /* (Avoids loopback in file space freeing routine) */ + tmp_fs_addr = f->shared->fs_addr[type]; + f->shared->fs_addr[type] = HADDR_UNDEF; - /* Shift to "deleting" state, to make certain we don't track any - * file space freed as a result of deleting the free space manager. - */ - f->shared->fs_state[type] = H5F_FS_STATE_DELETING; + /* Shift to "deleting" state, to make certain we don't track any + * file space freed as a result of deleting the free space manager. + */ + f->shared->fs_state[type] = H5F_FS_STATE_DELETING; #ifdef H5MF_ALLOC_DEBUG_MORE HDfprintf(stderr, "%s: Before deleting free space manager\n", FUNC); #endif /* H5MF_ALLOC_DEBUG_MORE */ - /* Delete free space manager for this type */ - if(H5FS_delete(f, dxpl_id, tmp_fs_addr) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't delete free space manager") - /* Shift [back] to closed state */ - HDassert(f->shared->fs_state[type] == H5F_FS_STATE_DELETING); - f->shared->fs_state[type] = H5F_FS_STATE_CLOSED; + /* Delete free space manager for this type */ + if(H5FS_delete(f, dxpl_id, tmp_fs_addr) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't delete free space manager") - /* Sanity check that the free space manager for this type wasn't started up again */ - HDassert(!H5F_addr_defined(f->shared->fs_addr[type])); - } /* end if */ - } /* end for */ + /* Shift [back] to closed state */ + HDassert(f->shared->fs_state[type] == H5F_FS_STATE_DELETING); + f->shared->fs_state[type] = H5F_FS_STATE_CLOSED; + + /* Sanity check that the free space manager for this type wasn't started up again */ + HDassert(!H5F_addr_defined(f->shared->fs_addr[type])); + } /* end if */ + } /* end for */ + } /* end else */ /* Free the space in aggregators (again) */ /* (in case any free space information re-started them) */ @@ -1032,3 +1151,126 @@ HDfprintf(stderr, "%s: Leaving\n", FUNC); FUNC_LEAVE_NOAPI(ret_value) } /* end H5MF_close() */ + +/*------------------------------------------------------------------------- + * Function: H5MF_sects_cb() + * + * Purpose: Iterator callback for each free-space section + * Retrieve address and size into user data + * + * Return: Always succeed + * + * Programmer: Vailin Choi + * July 1st, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5MF_sects_cb(const H5FS_section_info_t *_sect, void *_udata) +{ + const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; + H5MF_sect_iter_ud_t *udata = (H5MF_sect_iter_ud_t *)_udata; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MF_sects_cb) + + if(udata->sect_idx < udata->sect_count) { + udata->sects[udata->sect_idx].addr = sect->sect_info.addr; + udata->sects[udata->sect_idx].size = sect->sect_info.size; + udata->sect_idx++; + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5MF_sects_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5MF_get_free_sections() + * + * Purpose: To iterate over one or all free-space managers for: + * # of sections + * section info as defined in H5F_sect_info_t + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * July 1st, 2009 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5MF_get_free_sections(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info) +{ + size_t total_sects = 0; /* total number of sections */ + H5MF_sect_iter_ud_t sect_udata; /* User data for callback */ + H5FD_mem_t start_type, end_type; /* Memory types to iterate over */ + H5FD_mem_t ty; /* Memory type for iteration */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5MF_get_free_sections, FAIL) + + /* check args */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->lf); + + /* Determine start/end points for loop */ + if(type == H5FD_MEM_DEFAULT) { + start_type = H5FD_MEM_SUPER; + end_type = H5FD_MEM_NTYPES; + } /* end if */ + else { + start_type = end_type = type; + H5_INC_ENUM(H5FD_mem_t, end_type); + } /* end else */ + + /* Set up user data for section iteration */ + sect_udata.sects = sect_info; + sect_udata.sect_count = nsects; + sect_udata.sect_idx = 0; + + /* Iterate over memory types, retrieving the number of sections of each type */ + for(ty = start_type; ty < end_type; H5_INC_ENUM(H5FD_mem_t, ty)) { + hbool_t fs_started = FALSE; + + /* Open free space manager of this type, if it isn't already */ + if(!f->shared->fs_man[ty] && H5F_addr_defined(f->shared->fs_addr[ty])) { + if(H5MF_alloc_open(f, dxpl_id, ty) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, FAIL, "can't initialize file free space") + HDassert(f->shared->fs_man[ty]); + fs_started = TRUE; + } /* end if */ + + /* Check if f there's free space sections of this type */ + if(f->shared->fs_man[ty]) { + hsize_t hnums = 0; /* Total # of sections */ + size_t nums; /* Total # of sections, cast to a size_t */ + + /* Query how many sections of this type */ + if(H5FS_sect_stats(f->shared->fs_man[ty], NULL, &hnums) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space stats") + H5_ASSIGN_OVERFLOW(nums, hnums, hsize_t, size_t); + + /* Increment total # of sections */ + total_sects += nums; + + /* Check if we should retrieve the section info */ + if(sect_info && nums > 0) { + /* Iterate over all the free space sections of this type, adding them to the user's section info */ + if(H5FS_sect_iterate(f, dxpl_id, f->shared->fs_man[ty], H5MF_sects_cb, §_udata) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADITER, FAIL, "can't iterate over sections") + } /* end if */ + } /* end if */ + + /* Close the free space manager of this type, if we started it here */ + if(fs_started) + if(H5MF_alloc_close(f, dxpl_id, ty) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCLOSEOBJ, FAIL, "can't close file free space") + } /* end for */ + + /* Set return value */ + ret_value = (ssize_t)total_sects; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5MF_get_free_sections() */ + diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index aa982da..db13408 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -177,11 +177,11 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "Unable to get eoa") /* - * If the aggregation feature is enabled for this file, allocate "generic" - * space and sub-allocate out of that, if possible. Otherwise just allocate - * through H5FD_alloc() + * 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. + * Otherwise just allocate through H5FD_alloc(). */ - if(f->shared->feature_flags & aggr->feature_flag) { + if((f->shared->feature_flags & aggr->feature_flag) && f->shared->fs_strategy != H5F_FILE_SPACE_VFD) { haddr_t aggr_frag_addr = HADDR_UNDEF; /* Address of aggregrator fragment */ hsize_t aggr_frag_size = 0; /* Size of aggregator fragment */ hsize_t alignment; /* Alignment of this section */ diff --git a/src/H5MFdbg.c b/src/H5MFdbg.c index ca87c83..31cff15 100644 --- a/src/H5MFdbg.c +++ b/src/H5MFdbg.c @@ -41,7 +41,6 @@ #include "H5Fpkg.h" /* File access */ #include "H5MFpkg.h" /* File memory management */ -#ifdef H5MF_ALLOC_DEBUG_DUMP /****************/ /* Local Macros */ @@ -139,6 +138,67 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5MF_sects_debug_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5MF_sects_debug + * + * Purpose: Iterate over free space sections for a file + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * January 31 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5MF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, FILE *stream, int indent, int fwidth) +{ + herr_t ret_value = SUCCEED; /* Return value */ + H5FD_mem_t type; /* Memory type for iteration */ + + FUNC_ENTER_NOAPI(H5MF_sects_debug, FAIL) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(stream); + HDassert(indent >= 0); + HDassert(fwidth >= 0); + + for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) + if(H5F_addr_eq(f->shared->fs_addr[type], fs_addr)) { + if(!f->shared->fs_man[type]) + if(H5MF_alloc_open(f, dxpl_id, type) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space") + + if(f->shared->fs_man[type]) { + H5MF_debug_iter_ud_t udata; /* User data for callbacks */ + + /* Prepare user data for section iteration callback */ + udata.fspace = f->shared->fs_man[type]; + udata.stream = stream; + udata.indent = indent; + udata.fwidth = fwidth; + + /* Iterate over all the free space sections */ + if(H5FS_sect_iterate(f, dxpl_id, f->shared->fs_man[type], H5MF_sects_debug_cb, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space") + + /* Close the free space information */ + if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info") + } /* end if */ + break; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5MF_sects_debug() */ + +#ifdef H5MF_ALLOC_DEBUG_DUMP /*------------------------------------------------------------------------- * Function: H5MF_sects_dump diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 3f2a427..b471aa3 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -73,6 +73,8 @@ H5_DLL herr_t H5MF_try_extend(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested); H5_DLL htri_t H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, haddr_t addr, hsize_t size); +H5_DLL ssize_t H5MF_get_free_sections(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, + size_t nsects, H5F_sect_info_t *sect_info); /* File 'temporary' space allocation routines */ H5_DLL haddr_t H5MF_alloc_tmp(H5F_t *f, hsize_t size); @@ -82,10 +84,8 @@ H5_DLL herr_t H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id); /* Debugging routines */ #ifdef H5MF_DEBUGGING -#ifdef NOT_YET H5_DLL herr_t H5MF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth); -#endif /* NOT_YET */ #endif /* H5MF_DEBUGGING */ #endif /* end _H5MFprivate_H */ @@ -84,6 +84,7 @@ static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type); static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id); +static herr_t H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr); /*********************/ @@ -124,20 +125,9 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = { H5O_MSG_DRVINFO, /*0x0014 Driver info settings */ H5O_MSG_AINFO, /*0x0015 Attribute information */ H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */ - H5O_MSG_UNKNOWN, /*0x0017 Placeholder for unknown message */ - H5O_MSG_STORAGE, /*0x0018 Placeholder for unknown message */ -}; - -/* Header object ID to class mapping */ -/* - * Initialize the object class info table. Begin with the most general types - * and end with the most specific. For instance, any object that has a - * datatype message is a datatype but only some of them are datasets. - */ -const H5O_obj_class_t *const H5O_obj_class_g[] = { - H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */ - H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */ - H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */ + H5O_MSG_FSINFO, /*0x0017 Free-space manager info message */ + H5O_MSG_STORAGE, /*0x0018 Data storage */ + H5O_MSG_UNKNOWN, /*0x0019 Placeholder for unknown message */ }; /* Declare a free list to manage the H5O_t struct */ @@ -168,6 +158,18 @@ H5FL_EXTERN(H5_obj_t); /* Local Variables */ /*******************/ +/* Header object ID to class mapping */ +/* + * Initialize the object class info table. Begin with the most general types + * and end with the most specific. For instance, any object that has a + * datatype message is a datatype but only some of them are datasets. + */ +static const H5O_obj_class_t *const H5O_obj_class_g[] = { + H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */ + H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */ + H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */ +}; + /*------------------------------------------------------------------------- @@ -2297,6 +2299,131 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_get_hdr_info + * + * Purpose: Retrieve the object header information for an object + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * September 22 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr) +{ + H5O_t *oh = NULL; /* Object header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_get_hdr_info, FAIL) + + /* Check args */ + HDassert(oloc); + HDassert(hdr); + + /* Reset the object header info structure */ + HDmemset(hdr, 0, sizeof(*hdr)); + + /* Get the object header */ + if(NULL == (oh = (H5O_t *)H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + + /* Get the information for the object header */ + if(H5O_get_hdr_info_real(oh, hdr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info") + +done: + if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_get_hdr_info() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_get_hdr_info_real + * + * Purpose: Internal routine to retrieve the object header information for an object + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * September 22 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr) +{ + const H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ + const H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_get_hdr_info_real) + + /* Check args */ + HDassert(oh); + HDassert(hdr); + + /* Set the version for the object header */ + hdr->version = oh->version; + + /* Set the number of messages & chunks */ + hdr->nmesgs = oh->nmesgs; + hdr->nchunks = oh->nchunks; + + /* Set the status flags */ + hdr->flags = oh->flags; + + /* Iterate over all the messages, accumulating message size & type information */ + hdr->space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); + hdr->space.mesg = 0; + hdr->space.free = 0; + hdr->mesg.present = 0; + hdr->mesg.shared = 0; + for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { + uint64_t type_flag; /* Flag for message type */ + + /* Accumulate space usage information, based on the type of message */ + if(H5O_NULL_ID == curr_msg->type->id) + hdr->space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else if(H5O_CONT_ID == curr_msg->type->id) + hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else { + hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh); + hdr->space.mesg += curr_msg->raw_size; + } /* end else */ + + /* Set flag to indicate presence of message type */ + type_flag = ((uint64_t)1) << curr_msg->type->id; + hdr->mesg.present |= type_flag; + + /* Set flag if the message is shared in some way */ + if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \ + hdr->mesg.shared |= type_flag; + } /* end for */ + + /* Iterate over all the chunks, adding any gaps to the free space */ + hdr->space.total = 0; + for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) { + /* Accumulate the size of the header on disk */ + hdr->space.total += curr_chunk->size; + + /* If the chunk has a gap, add it to the free space */ + hdr->space.free += curr_chunk->gap; + } /* end for */ + + /* Sanity check that all the bytes are accounted for */ + HDassert(hdr->space.total == (hdr->space.free + hdr->space.meta + hdr->space.mesg)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_get_hdr_info_real() */ + + +/*------------------------------------------------------------------------- * Function: H5O_get_info * * Purpose: Retrieve the information for an object @@ -2310,12 +2437,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *oinfo) +H5O_get_info(const H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, + H5O_info_t *oinfo) { + const H5O_obj_class_t *obj_class; /* Class of object for header */ H5O_t *oh = NULL; /* Object header */ - H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */ - H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ - unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_get_info, FAIL) @@ -2337,20 +2463,12 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o /* Set the object's address */ oinfo->addr = oloc->addr; - /* Retrieve the type of the object */ - if(H5O_obj_type_real(oh, &oinfo->type) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") + /* Get class for object */ + if(NULL == (obj_class = H5O_obj_class_real(oh))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class") - /* Retrieve btree and heap storage info, if requested */ - if(want_ih_info) { - if(oinfo->type == H5O_TYPE_GROUP) { - if(H5O_group_bh_info(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve group btree & heap info") - } else if(oinfo->type == H5O_TYPE_DATASET) { - if(H5O_dset_bh_info(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve chunked dataset btree info") - } - } /* end if */ + /* Retrieve the type of the object */ + oinfo->type = obj_class->type; /* Set the object's reference count */ oinfo->rc = oh->nlink; @@ -2396,66 +2514,29 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o } /* end else */ } /* end else */ - /* Set the version for the object header */ - oinfo->hdr.version = oh->version; - - /* Set the number of messages & chunks */ - oinfo->hdr.nmesgs = oh->nmesgs; - oinfo->hdr.nchunks = oh->nchunks; - - /* Set the status flags */ - oinfo->hdr.flags = oh->flags; - - /* Iterate over all the messages, accumulating message size & type information */ - oinfo->hdr.space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); - oinfo->hdr.space.mesg = 0; - oinfo->hdr.space.free = 0; - oinfo->hdr.mesg.present = 0; - oinfo->hdr.mesg.shared = 0; - for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { - uint64_t type_flag; /* Flag for message type */ - - /* Accumulate space usage information, based on the type of message */ - if(H5O_NULL_ID == curr_msg->type->id) - oinfo->hdr.space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; - else if(H5O_CONT_ID == curr_msg->type->id) - oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; - else { - oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh); - oinfo->hdr.space.mesg += curr_msg->raw_size; - } /* end else */ - - /* Set flag to indicate presence of message type */ - type_flag = ((uint64_t)1) << curr_msg->type->id; - oinfo->hdr.mesg.present |= type_flag; - - /* Set flag if the message is shared in some way */ - if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \ - oinfo->hdr.mesg.shared |= type_flag; - } /* end for */ + /* Get the information for the object header */ + if(H5O_get_hdr_info_real(oh, &oinfo->hdr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info") /* Retrieve # of attributes */ if(H5O_attr_count_real(oloc->file, dxpl_id, oh, &oinfo->num_attrs) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute count") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute count") /* Get B-tree & heap metadata storage size, if requested */ if(want_ih_info) { - if((oinfo->num_attrs > 0) && (H5O_attr_bh_info(oloc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info") - } /* end if */ - - /* Iterate over all the chunks, adding any gaps to the free space */ - oinfo->hdr.space.total = 0; - for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) { - /* Accumulate the size of the header on disk */ - oinfo->hdr.space.total += curr_chunk->size; - - /* If the chunk has a gap, add it to the free space */ - oinfo->hdr.space.free += curr_chunk->gap; - } /* end for */ + /* Check for 'bh_info' callback for this type of object */ + if(obj_class->bh_info) { + /* Call the object's class 'bh_info' routine */ + if((obj_class->bh_info)(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj) /* out */) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object's btree & heap info") + } /* end if */ - /* Sanity check that all the bytes are accounted for */ - HDassert(oinfo->hdr.space.total == (oinfo->hdr.space.free + oinfo->hdr.space.meta + oinfo->hdr.space.mesg)); + /* Get B-tree & heap info for any attributes */ + if(oinfo->num_attrs > 0) { + if(H5O_attr_bh_info(oloc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info") + } /* end if */ + } /* end if */ done: if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 253f615..c624ee1 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -1859,6 +1859,8 @@ herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) { H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_attr_bh_info, FAIL) @@ -1876,30 +1878,37 @@ H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) if((ainfo_exists = H5A_get_ainfo(f, dxpl_id, oh, &ainfo)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") else if(ainfo_exists > 0) { - /* Get storage size of creation order index, if it's used */ - if(H5F_addr_defined(ainfo.corder_bt2_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5A_BT2_CORDER, ainfo.corder_bt2_addr, &(bh_info->index_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + /* Check if name index available */ + if(H5F_addr_defined(ainfo.name_bt2_addr)) { + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo.name_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + + /* Get name index B-tree size */ + if(H5B2_size(bt2_name, dxpl_id, &(bh_info->index_size)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + } /* end if */ + + /* Check if creation order index available */ + if(H5F_addr_defined(ainfo.corder_bt2_addr)) { + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, ainfo.corder_bt2_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") - /* Get storage size of name index, if it's used */ - if(H5F_addr_defined(ainfo.name_bt2_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, &(bh_info->index_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + /* Get creation order index B-tree size */ + if(H5B2_size(bt2_corder, dxpl_id, &(bh_info->index_size)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + } /* end if */ /* Get storage size of fractal heap, if it's used */ if(H5F_addr_defined(ainfo.fheap_addr)) { /* Open the fractal heap for attributes */ if(NULL == (fheap = H5HF_open(f, dxpl_id, ainfo.fheap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Get heap storage size */ if(H5HF_size(fheap, dxpl_id, &(bh_info->heap_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") - - /* Release the fractal heap */ - if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") - fheap = NULL; + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") } /* end if */ } /* end else */ } /* end if */ @@ -1907,7 +1916,11 @@ H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index") FUNC_LEAVE_NOAPI(ret_value) } /* H5O_attr_bh_info() */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index a9812690..fc71d65 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -269,9 +269,9 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p */ dt->shared->u.compnd.nmembs = flags & 0xffff; HDassert(dt->shared->u.compnd.nmembs > 0); - dt->shared->u.compnd.packed = TRUE; /* Start off packed */ dt->shared->u.compnd.nalloc = dt->shared->u.compnd.nmembs; dt->shared->u.compnd.memb = (H5T_cmemb_t *)H5MM_calloc(dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t)); + dt->shared->u.compnd.memb_size = 0; if(NULL == dt->shared->u.compnd.memb) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") for(i = 0; i < dt->shared->u.compnd.nmembs; i++) { @@ -385,6 +385,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Member size */ dt->shared->u.compnd.memb[i].size = temp_type->shared->size; + dt->shared->u.compnd.memb_size += temp_type->shared->size; /* Set the field datatype (finally :-) */ dt->shared->u.compnd.memb[i].type = temp_type; @@ -400,31 +401,11 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Update the maximum member position covered */ max_memb_pos = MAX(max_memb_pos, (dt->shared->u.compnd.memb[i].offset + dt->shared->u.compnd.memb[i].size)); - - /* Check if the datatype stayed packed */ - if(dt->shared->u.compnd.packed) { - /* Check if the member type is packed */ - if(H5T_is_packed(temp_type) > 0) { - if(i == 0) { - /* If the is the first member, the datatype is not packed - * if the first member isn't at offset 0 - */ - if(dt->shared->u.compnd.memb[i].offset > 0) - dt->shared->u.compnd.packed = FALSE; - } /* end if */ - else { - /* If the is not the first member, the datatype is not - * packed if the new member isn't adjoining the previous member - */ - if(dt->shared->u.compnd.memb[i].offset != (dt->shared->u.compnd.memb[i - 1].offset + dt->shared->u.compnd.memb[i - 1].size)) - dt->shared->u.compnd.packed = FALSE; - } /* end else */ - } /* end if */ - else - dt->shared->u.compnd.packed = FALSE; - } /* end if */ } /* end for */ + /* Check if the compound type is packed */ + H5T_update_packed(dt); + /* Upgrade the compound if requested */ if(version < upgrade_to) { version = upgrade_to; diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c new file mode 100644 index 0000000..fb0151f --- /dev/null +++ b/src/H5Ofsinfo.c @@ -0,0 +1,309 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Ofsinfo.c + * Feb 2009 + * Vailin Choi + * + * Purpose: Free space manager info message. + * + *------------------------------------------------------------------------- + */ + +#define H5O_PACKAGE /* suppress error about including H5Opkg */ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Opkg.h" /* Object headers */ + +/* PRIVATE PROTOTYPES */ +static void *H5O_fsinfo_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned mesg_flags, unsigned *ioflags, const uint8_t *p); +static herr_t H5O_fsinfo_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg); +static void *H5O_fsinfo_copy(const void *_mesg, void *_dest); +static size_t H5O_fsinfo_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg); +static herr_t H5O_fsinfo_free(void *mesg); +static herr_t H5O_fsinfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, + FILE * stream, int indent, int fwidth); + +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_FSINFO[1] = {{ + H5O_FSINFO_ID, /* message id number */ + "fsinfo", /* message name for debugging */ + sizeof(H5O_fsinfo_t), /* native message size */ + 0, /* messages are sharable? */ + H5O_fsinfo_decode, /* decode message */ + H5O_fsinfo_encode, /* encode message */ + H5O_fsinfo_copy, /* copy the native value */ + H5O_fsinfo_size, /* size of free-space manager info message */ + NULL, /* default reset method */ + H5O_fsinfo_free, /* free method */ + NULL, /* file delete method */ + NULL, /* link method */ + NULL, /* set share method */ + NULL, /* can share method */ + NULL, /* pre copy native value to file */ + NULL, /* copy native value to file */ + NULL, /* post copy native value to file */ + NULL, /* get creation index */ + NULL, /* set creation index */ + H5O_fsinfo_debug /* debug the message */ +}}; + +/* Current version of free-space manager info information */ +#define H5O_FSINFO_VERSION 0 + +/* Declare a free list to manage the H5O_fsinfo_t struct */ +H5FL_DEFINE_STATIC(H5O_fsinfo_t); + + +/*------------------------------------------------------------------------- + * Function: H5O_fsinfo_decode + * + * Purpose: Decode a message and return a pointer to a newly allocated one. + * + * Return: Success: Ptr to new message in native form. + * Failure: NULL + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +static void * +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 */ + H5FD_mem_t type; /* Memory type for iteration */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_fsinfo_decode) + + /* check args */ + HDassert(f); + HDassert(p); + + /* Version of message */ + if(*p++ != H5O_FSINFO_VERSION) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") + + /* Allocate space for message */ + if(NULL == (fsinfo = H5FL_CALLOC(H5O_fsinfo_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + fsinfo->strategy = *p++; /* file space strategy */ + H5F_DECODE_LENGTH(f, p, fsinfo->threshold); /* free space section size threshold */ + + /* Addresses of free space managers: only exist for H5F_FILE_SPACE_ALL_PERSIST */ + if(fsinfo->strategy == H5F_FILE_SPACE_ALL_PERSIST) { + for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) + H5F_addr_decode(f, &p, &(fsinfo->fs_addr[type-1])); + } /* end if */ + else { + for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) + fsinfo->fs_addr[type-1] = HADDR_UNDEF; + } /* end else */ + + /* Set return value */ + ret_value = fsinfo; + +done: + if(ret_value == NULL && fsinfo != NULL) + fsinfo = H5FL_FREE(H5O_fsinfo_t, fsinfo); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_fsinfo_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_fsinfo_encode + * + * Purpose: Encodes a message. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fsinfo_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg) +{ + const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *)_mesg; + H5FD_mem_t type; /* Memory type for iteration */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_encode) + + /* check args */ + HDassert(f); + HDassert(p); + HDassert(fsinfo); + + *p++ = H5O_FSINFO_VERSION; /* message version */ + *p++ = fsinfo->strategy; /* file space strategy */ + H5F_ENCODE_LENGTH(f, p, fsinfo->threshold); /* free-space section size threshold */ + + /* Addresses of free space managers: only exist for H5F_FILE_SPACE_ALL_PERSIST */ + if(fsinfo->strategy == H5F_FILE_SPACE_ALL_PERSIST) { + for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) + H5F_addr_encode(f, &p, fsinfo->fs_addr[type-1]); + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_fsinfo_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_fsinfo_copy + * + * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if + * necessary. + * + * Return: Success: Ptr to _DEST + * Failure: NULL + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_fsinfo_copy(const void *_mesg, void *_dest) +{ + const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *)_mesg; + H5O_fsinfo_t *dest = (H5O_fsinfo_t *) _dest; + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_fsinfo_copy) + + /* check args */ + HDassert(fsinfo); + if(!dest && NULL == (dest = H5FL_CALLOC(H5O_fsinfo_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* copy */ + *dest = *fsinfo; + + /* Set return value */ + ret_value = dest; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_fsinfo_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_fsinfo_size + * + * Purpose: Returns the size of the raw message in bytes not counting + * the message type or size fields, but only the data fields. + * This function doesn't take into account alignment. + * + * Return: Success: Message data size in bytes without alignment. + * Failure: zero + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +static size_t +H5O_fsinfo_size(const H5F_t *f, hbool_t UNUSED disable_shared, const void *_mesg) +{ + const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *)_mesg; + size_t fs_addr_size = 0; + size_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_size) + + + /* Addresses of free-space managers exist only for H5F_FILE_SPACE_ALL_PERSIST type */ + if(H5F_FILE_SPACE_ALL_PERSIST == fsinfo->strategy) + fs_addr_size = (H5FD_MEM_NTYPES - 1) * H5F_SIZEOF_ADDR(f); + + ret_value = 2 /* Version & strategy */ + + H5F_SIZEOF_SIZE(f) /* Threshold */ + + fs_addr_size; /* Addresses of free-space managers */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_fsinfo_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_fsinfo_free + * + * Purpose: Free's the message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fsinfo_free(void *mesg) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_free) + + HDassert(mesg); + + (void)H5FL_FREE(H5O_fsinfo_t, mesg); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_fsinfo_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_fsinfo_debug + * + * Purpose: Prints debugging info for a message. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Feb 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_fsinfo_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream, + int indent, int fwidth) +{ + const H5O_fsinfo_t *fsinfo = (const H5O_fsinfo_t *) _mesg; + H5FD_mem_t type; /* Memory type for iteration */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fsinfo_debug) + + /* check args */ + HDassert(f); + HDassert(fsinfo); + HDassert(stream); + HDassert(indent >= 0); + HDassert(fwidth >= 0); + + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "File space strategy:", fsinfo->strategy); + + HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, + "Free space section threshold:", fsinfo->threshold); + + if(fsinfo->strategy == H5F_FILE_SPACE_ALL_PERSIST) { + for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, + "Free space manager address:", fsinfo->fs_addr[type-1]); + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_fsinfo_debug() */ + diff --git a/src/H5Olayout.c b/src/H5Olayout.c index ce0e539..330189c 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -856,7 +856,7 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, case H5D_CHUNKED: if(H5D_chunk_is_space_alloc(&layout_src->storage)) { /* Create chunked layout */ - if(H5D_chunk_copy(file_src, &layout_src->storage.u.chunk, &layout_src->u.chunk, file_dst, &layout_dst->storage.u.chunk, udata->src_space_extent, udata->src_dtype, udata->src_pline, cpy_info, dxpl_id) < 0) + if(H5D_chunk_copy(file_src, &layout_src->storage.u.chunk, &layout_src->u.chunk, file_dst, &layout_dst->storage.u.chunk, udata->src_space_extent, udata->src_dtype, udata->common.src_pline, cpy_info, dxpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy chunked storage") } /* end if */ break; diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index 5ba237a..ba5ec56 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -377,11 +377,12 @@ done: */ static void * H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, - hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, + hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id) { H5O_linfo_t *linfo_src = (H5O_linfo_t *) native_src; H5O_linfo_t *linfo_dst = NULL; + H5G_copy_file_ud_t *udata = (H5G_copy_file_ud_t *) _udata; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_linfo_copy_file) @@ -411,7 +412,8 @@ H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, * dense link storage components and use those - QAK) */ if(H5F_addr_defined(linfo_src->fheap_addr)) { - if(H5G_dense_create(file_dst, dxpl_id, linfo_dst) < 0) + /* Create the dense link storage */ + if(H5G_dense_create(file_dst, dxpl_id, linfo_dst, udata->common.src_pline) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create 'dense' form of new format group") } /* end if */ } /* end else */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 90f3997..edb5d94 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -30,7 +30,7 @@ #define H5O_NMESGS 8 /*initial number of messages */ #define H5O_NCHUNKS 2 /*initial number of chunks */ #define H5O_MIN_SIZE 22 /* Min. obj header data size (must be big enough for a message prefix and a continuation message) */ -#define H5O_MSG_TYPES 25 /* # of types of messages */ +#define H5O_MSG_TYPES 26 /* # of types of messages */ #define H5O_MAX_CRT_ORDER_IDX 65535 /* Max. creation order index value */ /* Versions of object header structure */ @@ -320,6 +320,7 @@ typedef struct H5O_obj_class_t { hid_t (*open)(const H5G_loc_t *, hid_t, hid_t, hbool_t ); /*open an object of this class */ void *(*create)(H5F_t *, void *, H5G_loc_t *, hid_t ); /*create an object of this class */ H5O_loc_t *(*get_oloc)(hid_t ); /*get the object header location for an object */ + herr_t (*bh_info)(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info); /*get the index & heap info for an object */ } H5O_obj_class_t; /* Node in skip list to map addresses from one file to another during object header copy */ @@ -337,9 +338,6 @@ H5_DLLVAR const H5AC_class_t H5AC_OHDR[1]; /* Header message ID to class mapping */ H5_DLLVAR const H5O_msg_class_t *const H5O_msg_class_g[H5O_MSG_TYPES]; -/* Header object ID to class mapping */ -H5_DLLVAR const H5O_obj_class_t *const H5O_obj_class_g[3]; - /* Declare external the free list for H5O_t's */ H5FL_EXTERN(H5O_t); @@ -451,12 +449,15 @@ H5_DLLVAR const H5O_msg_class_t H5O_MSG_AINFO[1]; /* Reference Count Message. (0x0016) */ H5_DLLVAR const H5O_msg_class_t H5O_MSG_REFCOUNT[1]; -/* Placeholder for unknown message. (0x0017) */ -H5_DLLVAR const H5O_msg_class_t H5O_MSG_UNKNOWN[1]; +/* Free-space Manager Info message. (0x0017) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_FSINFO[1]; /* Data Storage Message. (0x0018) */ H5_DLLVAR const H5O_msg_class_t H5O_MSG_STORAGE[1]; +/* Placeholder for unknown message. (0x0019) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_UNKNOWN[1]; + /* * Object header "object" types @@ -500,10 +501,6 @@ H5_DLL herr_t H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *t const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id); /* Collect storage info for btree and heap */ -H5_DLL herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, - H5_ih_info_t *bh_info); -H5_DLL herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, - H5_ih_info_t *bh_info); H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info); diff --git a/src/H5Opline.c b/src/H5Opline.c index cc00996..0a50963 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -572,7 +572,7 @@ H5O_pline_pre_copy_file(H5F_t UNUSED *file_src, const void *mesg_src, hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info, void *_udata) { const H5O_pline_t *pline_src = (const H5O_pline_t *)mesg_src; /* Source datatype */ - H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ + H5O_copy_file_ud_common_t *udata = (H5O_copy_file_ud_common_t *)_udata; /* Object copying user data */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_pline_pre_copy_file) @@ -580,7 +580,7 @@ H5O_pline_pre_copy_file(H5F_t UNUSED *file_src, const void *mesg_src, /* check args */ HDassert(pline_src); - /* If the user data is non-NULL, assume we are copying a dataset + /* If the user data is non-NULL, assume we are copying a dataset or group * and make a copy of the filter pipeline for later in * the object copying process. */ @@ -665,3 +665,30 @@ H5O_pline_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *mesg, FILE *s FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_pline_debug() */ + +/*------------------------------------------------------------------------- + * Function: H5O_pline_set_latest_version + * + * Purpose: Set the encoding for a I/O filter pipeline to the latest version. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, July 24, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_pline_set_latest_version(H5O_pline_t *pline) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5O_pline_set_latest_version) + + /* Sanity check */ + HDassert(pline); + + /* Set encoding of I/O pipeline to latest version */ + pline->version = H5O_PLINE_VERSION_LATEST; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_pline_set_latest_version() */ + diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 21362b0..db2dab8 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -88,6 +88,8 @@ typedef struct H5O_t H5O_t; #define H5O_CRT_ATTR_MAX_COMPACT_NAME "max compact attr" /* Max. # of attributes to store compactly */ #define H5O_CRT_ATTR_MIN_DENSE_NAME "min dense attr" /* Min. # of attributes to store densely */ #define H5O_CRT_OHDR_FLAGS_NAME "object header flags" /* Object header flags */ +#define H5O_CRT_PIPELINE_NAME "pline" /* Filter pipeline */ +#define H5O_CRT_PIPELINE_DEF {{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL} #ifdef H5O_ENABLE_BOGUS #define H5O_BOGUS_MSG_FLAGS_NAME "bogus msg flags" /* Flags for 'bogus' message */ #define H5O_BOGUS_MSG_FLAGS_SIZE sizeof(uint8_t) @@ -165,9 +167,10 @@ typedef struct H5O_copy_t { #define H5O_DRVINFO_ID 0x0014 /* Driver info message. */ #define H5O_AINFO_ID 0x0015 /* Attribute info message. */ #define H5O_REFCOUNT_ID 0x0016 /* Reference count message. */ -#define H5O_UNKNOWN_ID 0x0017 /* Placeholder message ID for unknown message. */ - /* (this should never exist in a file) */ +#define H5O_FSINFO_ID 0x0017 /* Free-space manager info message. */ #define H5O_STORAGE_ID 0x0018 /* Data Storage message. */ +#define H5O_UNKNOWN_ID 0x0019 /* Placeholder message ID for unknown message. */ + /* (this should never exist in a file) */ /* Shared object message types. @@ -499,6 +502,20 @@ typedef struct H5O_ginfo_t { * Filter pipeline message. * (Data structure in memory) */ + +/* The initial version of the format */ +#define H5O_PLINE_VERSION_1 1 + +/* This version encodes the message fields more efficiently */ +/* (Drops the reserved bytes, doesn't align the name and doesn't encode the + * filter name at all if it's a filter provided by the library) + */ +#define H5O_PLINE_VERSION_2 2 + +/* The latest version of the format. Look through the 'encode' and 'size' + * callbacks for places to change when updating this. */ +#define H5O_PLINE_VERSION_LATEST H5O_PLINE_VERSION_2 + typedef struct H5O_pline_t { H5O_shared_t sh_loc; /* Shared message info (must be first) */ @@ -603,6 +620,17 @@ typedef uint32_t H5O_refcount_t; /* Contains # of links to object, if >1 */ typedef unsigned H5O_unknown_t; /* Original message type ID */ +/* + * Free space manager info Message. + * Contains file space management info and + * addresses of free space managers for file memory + * (Data structure in memory) + */ +typedef struct H5O_fsinfo_t { + H5F_file_space_type_t strategy; /* File space strategy */ + hsize_t threshold; /* Free space section threshold */ + haddr_t fs_addr[H5FD_MEM_NTYPES-1]; /* Addresses of free space managers */ +} H5O_fsinfo_t; /* Typedef for "application" iteration operations */ typedef herr_t (*H5O_operator_t)(const void *mesg/*in*/, unsigned idx, @@ -655,7 +683,8 @@ H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned mesg_flags); #endif /* H5O_ENABLE_BOGUS */ H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); -H5_DLL herr_t H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, +H5_DLL herr_t H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr); +H5_DLL herr_t H5O_get_info(const H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *oinfo); H5_DLL herr_t H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id); H5_DLL herr_t H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, struct H5P_genplist_t *oc_plist); @@ -747,6 +776,9 @@ H5_DLL herr_t H5O_fill_set_latest_version(H5O_fill_t *fill); H5_DLL herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg); +/* Filter pipeline operators */ +H5_DLL herr_t H5O_pline_set_latest_version(H5O_pline_t *pline); + /* Shared message operators */ H5_DLL herr_t H5O_set_shared(H5O_shared_t *dst, const H5O_shared_t *src); diff --git a/src/H5Opublic.h b/src/H5Opublic.h index ddf1a93..84fdecc 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -87,6 +87,24 @@ typedef enum H5O_type_t { H5O_TYPE_NTYPES /* Number of different object types (must be last!) */ } H5O_type_t; +/* Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */ +typedef struct H5O_hdr_info_t { + unsigned version; /* Version number of header format in file */ + unsigned nmesgs; /* Number of object header messages */ + unsigned nchunks; /* Number of object header chunks */ + unsigned flags; /* Object header status flags */ + struct { + hsize_t total; /* Total space for storing object header in file */ + hsize_t meta; /* Space within header for object header metadata information */ + hsize_t mesg; /* Space within header for actual message information */ + hsize_t free; /* Free space within object header */ + } space; + struct { + uint64_t present; /* Flags to indicate presence of message type in header */ + uint64_t shared; /* Flags to indicate message type is shared in header */ + } mesg; +} H5O_hdr_info_t; + /* Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */ typedef struct H5O_info_t { unsigned long fileno; /* File number that object is located in */ @@ -98,22 +116,7 @@ typedef struct H5O_info_t { time_t ctime; /* Change time */ time_t btime; /* Birth time */ hsize_t num_attrs; /* # of attributes attached to object */ - struct { - unsigned version; /* Version number of header format in file */ - unsigned nmesgs; /* Number of object header messages */ - unsigned nchunks; /* Number of object header chunks */ - unsigned flags; /* Object header status flags */ - struct { - hsize_t total; /* Total space for storing object header in file */ - hsize_t meta; /* Space within header for object header metadata information */ - hsize_t mesg; /* Space within header for actual message information */ - hsize_t free; /* Free space within object header */ - } space; - struct { - uint64_t present; /* Flags to indicate presence of message type in header */ - uint64_t shared; /* Flags to indicate message type is shared in header */ - } mesg; - } hdr; + H5O_hdr_info_t hdr; /* Object header information */ /* Extra metadata storage for obj & attributes */ struct { H5_ih_info_t obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ diff --git a/src/H5Ostorage.c b/src/H5Ostorage.c index 0229677..f6891d7 100644 --- a/src/H5Ostorage.c +++ b/src/H5Ostorage.c @@ -569,7 +569,7 @@ H5O_storage_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, case H5D_CHUNKED: if(H5D_chunk_is_space_alloc(storage_src)) { /* Create chunked layout */ - if(H5D_chunk_copy(file_src, &storage_src->u.chunk, &udata->src_layout->u.chunk, file_dst, &storage_dst->u.chunk, udata->src_space_extent, udata->src_dtype, udata->src_pline, cpy_info, dxpl_id) < 0) + if(H5D_chunk_copy(file_src, &storage_src->u.chunk, &udata->src_layout->u.chunk, file_dst, &storage_dst->u.chunk, udata->src_space_extent, udata->src_dtype, udata->common.src_pline, cpy_info, dxpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy chunked storage") } /* end if */ break; diff --git a/src/H5Otest.c b/src/H5Otest.c index c2b30fa..45ade3a 100644 --- a/src/H5Otest.c +++ b/src/H5Otest.c @@ -158,6 +158,7 @@ htri_t H5O_is_attr_empty_test(hid_t oid) { H5O_t *oh = NULL; /* Object header */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ H5O_ainfo_t ainfo; /* Attribute information for object */ htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */ H5O_loc_t *oloc; /* Pointer to object's location */ @@ -192,9 +193,13 @@ H5O_is_attr_empty_test(hid_t oid) /* Check for any messages in object header */ HDassert(nattrs == 0); + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(oloc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Retrieve # of records in name index */ - if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, &nattrs) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") + if(H5B2_get_nrec(bt2_name, &nattrs) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") } /* end if */ /* Verify that attribute count in object header is correct */ @@ -208,6 +213,9 @@ H5O_is_attr_empty_test(hid_t oid) ret_value = (nattrs == 0) ? TRUE : FALSE; done: + /* Release resources */ + if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") if(oh && H5AC_unprotect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") @@ -238,6 +246,7 @@ herr_t H5O_num_attrs_test(hid_t oid, hsize_t *nattrs) { H5O_t *oh = NULL; /* Object header */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ H5O_ainfo_t ainfo; /* Attribute information for object */ H5O_loc_t *oloc; /* Pointer to object's location */ hsize_t obj_nattrs; /* Number of attributes */ @@ -271,9 +280,13 @@ H5O_num_attrs_test(hid_t oid, hsize_t *nattrs) /* Check for any messages in object header */ HDassert(obj_nattrs == 0); + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(oloc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Retrieve # of records in name index */ - if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, &obj_nattrs) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") + if(H5B2_get_nrec(bt2_name, &obj_nattrs) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") } /* end if */ /* Verify that attribute count in object header is correct */ @@ -284,6 +297,9 @@ H5O_num_attrs_test(hid_t oid, hsize_t *nattrs) *nattrs = obj_nattrs; done: + /* Release resources */ + if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") if(oh && H5AC_unprotect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") @@ -316,6 +332,8 @@ herr_t H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count) { H5O_t *oh = NULL; /* Object header */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ H5O_ainfo_t ainfo; /* Attribute information for object */ H5O_loc_t *oloc; /* Pointer to object's location */ herr_t ret_value = SUCCEED; /* Return value */ @@ -344,20 +362,33 @@ H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count) if(!H5F_addr_defined(ainfo.name_bt2_addr)) HGOTO_DONE(FAIL) + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(oloc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + /* Retrieve # of records in name index */ - if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, name_count) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") + if(H5B2_get_nrec(bt2_name, name_count) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index") /* Check if there is a creation order index */ if(H5F_addr_defined(ainfo.corder_bt2_addr)) { + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2_corder = H5B2_open(oloc->file, H5AC_ind_dxpl_id, ainfo.corder_bt2_addr))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") + /* Retrieve # of records in creation order index */ - if(H5B2_get_nrec(oloc->file, H5AC_ind_dxpl_id, H5A_BT2_CORDER, ainfo.corder_bt2_addr, corder_count) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index") + if(H5B2_get_nrec(bt2_corder, corder_count) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index") } /* end if */ else *corder_count = 0; done: + /* Release resources */ + if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, H5AC_ind_dxpl_id) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index") if(oh && H5AC_unprotect(oloc->file, H5AC_ind_dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index d96f30a..17e1011 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -89,10 +89,6 @@ #define H5D_CRT_EXT_FILE_LIST_SIZE sizeof(H5O_efl_t) #define H5D_CRT_EXT_FILE_LIST_DEF {HADDR_UNDEF, 0, 0, NULL} #define H5D_CRT_EXT_FILE_LIST_CMP H5P_dcrt_ext_file_list_cmp -/* Definitions for data filter pipeline */ -#define H5D_CRT_DATA_PIPELINE_SIZE sizeof(H5O_pline_t) -#define H5D_CRT_DATA_PIPELINE_DEF {{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL} -#define H5D_CRT_DATA_PIPELINE_CMP H5P_dcrt_data_pipeline_cmp /******************/ @@ -123,7 +119,6 @@ static herr_t H5P_dcrt_close(hid_t dxpl_id, void *close_data); /* Property callbacks */ static int H5P_dcrt_layout_cmp(const void *value1, const void *value2, size_t size); static int H5P_dcrt_ext_file_list_cmp(const void *value1, const void *value2, size_t size); -static int H5P_dcrt_data_pipeline_cmp(const void *value1, const void *value2, size_t size); /*********************/ @@ -185,7 +180,6 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass) H5O_fill_t fill = H5D_CRT_FILL_VALUE_DEF; /* Default fill value */ unsigned alloc_time_state = H5D_CRT_ALLOC_TIME_STATE_DEF; /* Default allocation time state */ H5O_efl_t efl = H5D_CRT_EXT_FILE_LIST_DEF; /* Default external file list */ - H5O_pline_t pline = H5D_CRT_DATA_PIPELINE_DEF; /* Default I/O pipeline setting */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_dcrt_reg_prop) @@ -206,10 +200,6 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass) 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) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - /* Register the data pipeline property */ - if(H5P_register(pclass, H5D_CRT_DATA_PIPELINE_NAME, H5D_CRT_DATA_PIPELINE_SIZE, &pline, NULL, NULL, NULL, NULL, NULL, H5D_CRT_DATA_PIPELINE_CMP, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_dcrt_reg_prop() */ @@ -240,7 +230,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) { H5O_fill_t src_fill, dst_fill; /* Source & destination fill values */ H5O_efl_t src_efl, dst_efl; /* Source & destination external file lists */ - H5O_pline_t src_pline, dst_pline; /* Source & destination I/O pipelines */ H5O_layout_t src_layout, dst_layout; /* Source & destination layout */ H5P_genplist_t *src_plist; /* Pointer to source property list */ H5P_genplist_t *dst_plist; /* Pointer to destination property list */ @@ -263,8 +252,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value") if(H5P_get(src_plist, H5D_CRT_EXT_FILE_LIST_NAME, &src_efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list") - if(H5P_get(src_plist, H5D_CRT_DATA_PIPELINE_NAME, &src_pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") /* Make copy of layout */ if(NULL == H5O_msg_copy(H5O_LAYOUT_ID, &src_layout, &dst_layout)) @@ -319,10 +306,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) dst_efl.slot[i].name_offset = 0; } /* end if */ - /* Make copy of data pipeline */ - if(NULL == H5O_msg_copy(H5O_PLINE_ID, &src_pline, &dst_pline)) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy data pipeline") - /* Set the layout, fill value, external file list, and data pipeline * properties for the destination property list */ @@ -332,8 +315,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value") if(H5P_set(dst_plist, H5D_CRT_EXT_FILE_LIST_NAME, &dst_efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set external file list") - if(H5P_set(dst_plist, H5D_CRT_DATA_PIPELINE_NAME, &dst_pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") done: FUNC_LEAVE_NOAPI(ret_value) @@ -361,7 +342,6 @@ H5P_dcrt_close(hid_t dcpl_id, void UNUSED *close_data) { H5O_fill_t fill; /* Fill value */ H5O_efl_t efl; /* External file list */ - H5O_pline_t pline; /* I/O pipeline */ H5P_genplist_t *plist; /* Property list */ herr_t ret_value = SUCCEED; /* Return value */ @@ -377,17 +357,12 @@ H5P_dcrt_close(hid_t dcpl_id, void UNUSED *close_data) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value") if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list") - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - /* Clean up any values set for the fill-value, external file-list and - * data pipeline */ + /* Clean up any values set for the fill-value and external file-list */ if(H5O_msg_reset(H5O_FILL_ID, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release fill info") if(H5O_msg_reset(H5O_EFL_ID, &efl) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release external file list info") - if(H5O_msg_reset(H5O_PLINE_ID, &pline) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release pipeline info") done: FUNC_LEAVE_NOAPI(ret_value) @@ -606,92 +581,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5P_dcrt_data_pipeline_cmp - * - * Purpose: Callback routine which is called whenever the filter pipeline - * property in the dataset creation property list is compared. - * - * Return: positive if VALUE1 is greater than VALUE2, negative if - * VALUE2 is greater than VALUE1 and zero if VALUE1 and - * VALUE2 are equal. - * - * Programmer: Quincey Koziol - * Wednesday, January 7, 2004 - * - *------------------------------------------------------------------------- - */ -static int -H5P_dcrt_data_pipeline_cmp(const void *_pline1, const void *_pline2, size_t UNUSED size) -{ - const H5O_pline_t *pline1 = (const H5O_pline_t *)_pline1, /* Create local aliases for values */ - *pline2 = (const H5O_pline_t *)_pline2; - int cmp_value; /* Value from comparison */ - herr_t ret_value = 0; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_dcrt_data_pipeline_cmp) - - /* Sanity check */ - HDassert(pline1); - HDassert(pline2); - HDassert(size == sizeof(H5O_pline_t)); - - /* Check the number of allocated pipeline entries */ - if(pline1->nalloc < pline2->nalloc) HGOTO_DONE(-1); - if(pline1->nalloc > pline2->nalloc) HGOTO_DONE(1); - - /* Check the number of used pipeline entries */ - if(pline1->nused < pline2->nused) HGOTO_DONE(-1); - if(pline1->nused > pline2->nused) HGOTO_DONE(1); - - /* Check the filter entry information */ - if(pline1->filter == NULL && pline2->filter != NULL) HGOTO_DONE(-1); - if(pline1->filter != NULL && pline2->filter == NULL) HGOTO_DONE(1); - if(pline1->filter != NULL && pline1->nused > 0) { - size_t u; /* Local index variable */ - - /* Loop through all filters, comparing them */ - for(u = 0; u < pline1->nused; u++) { - /* Check the ID of the filter */ - if(pline1->filter[u].id < pline2->filter[u].id) HGOTO_DONE(-1); - if(pline1->filter[u].id > pline2->filter[u].id) HGOTO_DONE(1); - - /* Check the flags for the filter */ - if(pline1->filter[u].flags < pline2->filter[u].flags) HGOTO_DONE(-1); - if(pline1->filter[u].flags > pline2->filter[u].flags) HGOTO_DONE(1); - - /* Check the name of the filter */ - if(pline1->filter[u].name == NULL && pline2->filter[u].name != NULL) HGOTO_DONE(-1); - if(pline1->filter[u].name != NULL && pline2->filter[u].name == NULL) HGOTO_DONE(1); - if(pline1->filter[u].name != NULL) - if((cmp_value = HDstrcmp(pline1->filter[u].name, pline2->filter[u].name)) != 0) - HGOTO_DONE(cmp_value); - - /* Check the number of parameters for the filter */ - if(pline1->filter[u].cd_nelmts < pline2->filter[u].cd_nelmts) HGOTO_DONE(-1); - if(pline1->filter[u].cd_nelmts > pline2->filter[u].cd_nelmts) HGOTO_DONE(1); - - /* Check the filter parameter information */ - if(pline1->filter[u].cd_values == NULL && pline2->filter[u].cd_values != NULL) HGOTO_DONE(-1); - if(pline1->filter[u].cd_values != NULL && pline2->filter[u].cd_values == NULL) HGOTO_DONE(1); - if(pline1->filter[u].cd_values != NULL && pline1->filter[u].cd_nelmts > 0) { - size_t v; /* Local index variable */ - - /* Loop through all parameters, comparing them */ - for(v = 0; v < pline1->filter[u].cd_nelmts; v++) { - /* Check each parameter for the filter */ - if(pline1->filter[u].cd_values[v] < pline2->filter[u].cd_values[v]) HGOTO_DONE(-1); - if(pline1->filter[u].cd_values[v] > pline2->filter[u].cd_values[v]) HGOTO_DONE(1); - } /* end for */ - } /* end if */ - } /* end for */ - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_dcrt_data_pipeline_cmp() */ - - -/*------------------------------------------------------------------------- * Function: H5P_set_layout * * Purpose: Sets the layout of raw data in the file. @@ -1273,700 +1162,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5P_modify_filter - * - * Purpose: Modifies the specified FILTER in the - * transient or permanent output filter pipeline - * depending on whether PLIST is a dataset creation or dataset - * transfer property list. The FLAGS argument specifies certain - * general properties of the filter and is documented below. - * The CD_VALUES is an array of CD_NELMTS integers which are - * auxiliary data for the filter. The integer vlues will be - * stored in the dataset object header as part of the filter - * information. - * - * The FLAGS argument is a bit vector of the following fields: - * - * H5Z_FLAG_OPTIONAL(0x0001) - * If this bit is set then the filter is optional. If the - * filter fails during an H5Dwrite() operation then the filter - * is just excluded from the pipeline for the chunk for which it - * failed; the filter will not participate in the pipeline - * during an H5Dread() of the chunk. If this bit is clear and - * the filter fails then the entire I/O operation fails. - * If this bit is set but encoding is disabled for a filter, - * attempting to write will generate an error. - * - * Note: This function currently supports only the permanent filter - * pipeline. That is, PLIST_ID must be a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Wednesday, October 17, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned flags, - size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/]) -{ - H5O_pline_t pline; - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_NOAPI(H5P_modify_filter, FAIL) - - /* Get the pipeline property to append to */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Modify the filter parameters of the I/O pipeline */ - if(H5Z_modify(&pline, filter, flags, cd_nelmts, cd_values) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") - - /* Put the I/O pipeline information back into the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_modify_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pmodify_filter - * - * Purpose: Modifies the specified FILTER in the - * transient or permanent output filter pipeline - * depending on whether PLIST is a dataset creation or dataset - * transfer property list. The FLAGS argument specifies certain - * general properties of the filter and is documented below. - * The CD_VALUES is an array of CD_NELMTS integers which are - * auxiliary data for the filter. The integer vlues will be - * stored in the dataset object header as part of the filter - * information. - * - * The FLAGS argument is a bit vector of the following fields: - * - * H5Z_FLAG_OPTIONAL(0x0001) - * If this bit is set then the filter is optional. If the - * filter fails during an H5Dwrite() operation then the filter - * is just excluded from the pipeline for the chunk for which it - * failed; the filter will not participate in the pipeline - * during an H5Dread() of the chunk. If this bit is clear and - * the filter fails then the entire I/O operation fails. - * If this bit is set but encoding is disabled for a filter, - * attempting to write will generate an error. - * - * Note: This function currently supports only the permanent filter - * pipeline. That is, PLIST_ID must be a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Friday, April 5, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, - size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pmodify_filter, FAIL) - H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); - - /* Check args */ - if (filter<0 || filter>H5Z_FILTER_MAX) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") - if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") - if (cd_nelmts>0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Modify the filter parameters of the I/O pipeline */ - if(H5P_modify_filter(plist, filter, flags, cd_nelmts, cd_values) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't modify filter") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pmodify_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pset_filter - * - * Purpose: Adds the specified FILTER and corresponding properties to the - * end of the transient or permanent output filter pipeline - * depending on whether PLIST is a dataset creation or dataset - * transfer property list. The FLAGS argument specifies certain - * general properties of the filter and is documented below. - * The CD_VALUES is an array of CD_NELMTS integers which are - * auxiliary data for the filter. The integer vlues will be - * stored in the dataset object header as part of the filter - * information. - * - * The FLAGS argument is a bit vector of the following fields: - * - * H5Z_FLAG_OPTIONAL(0x0001) - * If this bit is set then the filter is optional. If the - * filter fails during an H5Dwrite() operation then the filter - * is just excluded from the pipeline for the chunk for which it - * failed; the filter will not participate in the pipeline - * during an H5Dread() of the chunk. If this bit is clear and - * the filter fails then the entire I/O operation fails. - * If this bit is set but encoding is disabled for a filter, - * attempting to write will generate an error. - * - * Note: This function currently supports only the permanent filter - * pipeline. That is, PLIST_ID must be a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - * Modifications: - * - * Raymond Lu - * Tuesday, October 2, 2001 - * Changed the way to check parameter and set property for - * generic property list. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, - size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset_filter, FAIL) - H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); - - /* Check args */ - if (filter<0 || filter>H5Z_FILTER_MAX) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") - if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") - if (cd_nelmts>0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get the pipeline property to append to */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Add the filter to the I/O pipeline */ - if(H5Z_append(&pline, filter, flags, cd_nelmts, cd_values) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") - - /* Put the I/O pipeline information back into the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") - -done: - FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_nfilters - * - * Purpose: Returns the number of filters in the permanent or transient - * pipeline depending on whether PLIST_ID is a dataset creation - * or dataset transfer property list. In each pipeline the - * filters are numbered from zero through N-1 where N is the - * value returned by this function. During output to the file - * the filters of a pipeline are applied in increasing order - * (the inverse is true for input). - * - * Note: Only permanent filters are supported at this time. - * - * Return: Success: Number of filters or zero if there are none. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Tuesday, August 4, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5Pget_nfilters(hid_t plist_id) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - int ret_value; /* return value */ - - FUNC_ENTER_API(H5Pget_nfilters, FAIL) - H5TRACE1("Is", "i", plist_id); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get value */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Set return value */ - ret_value=(int)(pline.nused); - -done: - FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5P_get_filter - * - * Purpose: Internal component of H5Pget_filter & H5Pget_filter_id - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, October 23, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5P_get_filter(const H5Z_filter_info_t *filter, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, - unsigned *filter_config /*out*/) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_filter) - - /* Check arguments */ - HDassert(filter); - - /* Filter flags */ - if(flags) - *flags = filter->flags; - - /* Filter parameters */ - if(cd_values) { - size_t i; /* Local index variable */ - - for(i = 0; i < filter->cd_nelmts && i < *cd_nelmts; i++) - cd_values[i] = filter->cd_values[i]; - } /* end if */ - - /* Number of filter parameters */ - if(cd_nelmts) - *cd_nelmts = filter->cd_nelmts; - - /* Filter name */ - if(namelen > 0 && name) { - const char *s = filter->name; - - /* If there's no name on the filter, use the class's filter name */ - if(!s) { - H5Z_class2_t *cls = H5Z_find(filter->id); - - if(cls) - s = cls->name; - } /* end if */ - - /* Check for actual name */ - if(s) { - HDstrncpy(name, s, namelen); - name[namelen - 1] = '\0'; - } /* end if */ - else { - /* Check for unknown library filter */ - /* (probably from a future version of the library) */ - if(filter->id < 256) { - HDstrncpy(name, "Unknown library filter", namelen); - name[namelen - 1] = '\0'; - } /* end if */ - else - name[0] = '\0'; - } /* end if */ - } /* end if */ - - /* Filter configuration (assume filter ID has already been checked) */ - if(filter_config) - H5Zget_filter_info(filter->id, filter_config); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5P_get_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter2 - * - * Purpose: This is the query counterpart of H5Pset_filter() and returns - * information about a particular filter number in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. FILTER_CONFIG is a bit - * field contaning encode/decode flags from H5Zpublic.h. The IDX - * should be a value between zero and N-1 as described for - * H5Pget_nfilters() and the function will return failure if the - * filter number is out of range. - * - * Return: Success: Filter identification number. - * - * Failure: H5Z_FILTER_ERROR (Negative) - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - *------------------------------------------------------------------------- - */ -H5Z_filter_t -H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, - unsigned *filter_config /*out*/) -{ - H5O_pline_t pline; /* Filter pipeline */ - const H5Z_filter_info_t *filter; /* Pointer to filter information */ - H5P_genplist_t *plist; /* Property list pointer */ - H5Z_filter_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pget_filter2, H5Z_FILTER_ERROR) - H5TRACE8("Zf", "iIux*zxzxx", plist_id, idx, flags, cd_nelmts, cd_values, - namelen, name, filter_config); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") - - /* Check more args */ - if(idx >= pline.nused) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") - - /* Set pointer to particular filter to query */ - filter = &pline.filter[idx]; - - /* Get filter information */ - if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") - - /* Set return value */ - ret_value = filter->id; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter2() */ - - -/*------------------------------------------------------------------------- - * Function: H5P_get_filter_by_id - * - * Purpose: This is an additional query counterpart of H5Pset_filter() and - * returns information about a particular filter in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. FILTER_CONFIG is a bit - * field contaning encode/decode flags from H5Zpublic.h. The ID - * should be the filter ID to retrieve the parameters for. If the - * filter is not set for the property list, an error will be returned. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * Wednesday, October 17, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, unsigned *filter_config) -{ - H5O_pline_t pline; /* Filter pipeline */ - H5Z_filter_info_t *filter; /* Pointer to filter information */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_get_filter_by_id, FAIL) - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Get pointer to filter in pipeline */ - if(NULL == (filter = H5Z_filter_info(&pline, id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid") - - /* Get filter information */ - if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_get_filter_by_id() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter_by_id2 - * - * Purpose: This is an additional query counterpart of H5Pset_filter() and - * returns information about a particular filter in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. FILTER_CONFIG is a bit - * field contaning encode/decode flags from H5Zpublic.h. The ID - * should be the filter ID to retrieve the parameters for. If the - * filter is not set for the property list, an error will be returned. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, April 5, 2003 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, unsigned *filter_config) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pget_filter_by_id2, FAIL) - H5TRACE8("e", "iZfx*zxzx*Iu", plist_id, id, flags, cd_nelmts, cd_values, - namelen, name, filter_config); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get filter info */ - if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter_by_id2() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pall_filters_avail - * - * Purpose: This is a query routine to verify that all the filters set - * in the dataset creation property list are available currently. - * - * Return: Success: TRUE if all filters available, FALSE if one or - * more filters not currently available. - * Failure: FAIL on error - * - * Programmer: Quincey Koziol - * Tuesday, April 8, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5Pall_filters_avail(hid_t plist_id) -{ - H5P_genplist_t *plist; /* Property list pointer */ - H5O_pline_t pline; /* Filter pipeline */ - htri_t ret_value; /* Return value */ - - FUNC_ENTER_API(H5Pall_filters_avail, FAIL) - H5TRACE1("t", "i", plist_id); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Check if all filters are available */ - if((ret_value = H5Z_all_filters_avail(&pline)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't check pipeline information") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pall_filters_avail() */ - - -/*------------------------------------------------------------------------- - * Function: H5Premove_filter - * - * Purpose: Deletes a filter from the dataset creation property list; - * deletes all filters if FILTER is H5Z_FILTER_NONE - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Pedro Vicente - * January 26, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Premove_filter(hid_t plist_id, H5Z_filter_t filter) -{ - H5P_genplist_t *plist; /* Property list pointer */ - H5O_pline_t pline; /* Filter pipeline */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Premove_filter, FAIL) - H5TRACE2("e", "iZf", plist_id, filter); - - /* Get the property list structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") - - /* Check if there are any filters */ - if (pline.filter) { - /* Delete filter */ - if(H5Z_delete(&pline, filter) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't delete filter") - - /* Put the I/O pipeline information back into the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") - } /* end if */ - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Premove_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pset_deflate - * - * Purpose: Sets the compression method for a permanent or transient - * filter pipeline (depending on whether PLIST_ID is a dataset - * creation or transfer property list) to H5Z_FILTER_DEFLATE - * and the compression level to LEVEL which should be a value - * between zero and nine, inclusive. Lower compression levels - * are faster but result in less compression. This is the same - * algorithm as used by the GNU gzip program. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - * Modifications: - * - * Raymond Lu - * Tuesday, October 2, 2001 - * Changed the way to check parameter and set property for - * generic property list. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_deflate(hid_t plist_id, unsigned level) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset_deflate, FAIL) - H5TRACE2("e", "iIu", plist_id, level); - - /* Check arguments */ - if(level>9) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level") - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Add the filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - if(H5Z_append(&pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &level) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pset_deflate() */ - - -/*------------------------------------------------------------------------- * Function: H5Pset_szip * * Purpose: Sets the compression method for a permanent or transient @@ -2033,11 +1228,11 @@ H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block) cd_values[1]=pixels_per_block; /* Add the filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_SZIP, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add szip filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2080,11 +1275,11 @@ H5Pset_shuffle(hid_t plist_id) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Add the filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_SHUFFLE, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to shuffle the data") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2126,11 +1321,11 @@ H5Pset_nbit(hid_t plist_id) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Add the nbit filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_NBIT, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add nbit filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2205,11 +1400,11 @@ H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_fac cd_values[1] = (unsigned)scale_factor; /* Add the scaleoffset filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_SCALEOFFSET, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add scaleoffset filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2218,48 +1413,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Pset_fletcher32 - * - * Purpose: Sets Fletcher32 checksum of EDC for a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * Dec 19, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_fletcher32(hid_t plist_id) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset_fletcher32, FAIL) - H5TRACE1("e", "i", plist_id); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Add the Fletcher32 checksum as a filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - if(H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pset_fletcher32() */ - - -/*------------------------------------------------------------------------- * Function: H5Pset_fill_value * * Purpose: Set the fill value for a dataset creation property list. The @@ -2831,158 +1984,3 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_fill_time() */ -#ifndef H5_NO_DEPRECATED_SYMBOLS - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter1 - * - * Purpose: This is the query counterpart of H5Pset_filter() and returns - * information about a particular filter number in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. The IDX - * should be a value between zero and N-1 as described for - * H5Pget_nfilters() and the function will return failure if the - * filter number is out of range. - * - * Return: Success: Filter identification number. - * - * Failure: H5Z_FILTER_ERROR (Negative) - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - *------------------------------------------------------------------------- - */ -H5Z_filter_t -H5Pget_filter1(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/) -{ - H5O_pline_t pline; /* Filter pipeline */ - const H5Z_filter_info_t *filter; /* Pointer to filter information */ - H5P_genplist_t *plist; /* Property list pointer */ - H5Z_filter_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pget_filter1, H5Z_FILTER_ERROR) - H5TRACE7("Zf", "iIux*zxzx", plist_id, idx, flags, cd_nelmts, cd_values, namelen, - name); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") - - /* Check more args */ - if(idx >= pline.nused) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") - - /* Set pointer to particular filter to query */ - filter = &pline.filter[idx]; - - /* Get filter information */ - if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") - - /* Set return value */ - ret_value = filter->id; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter1() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter_by_id1 - * - * Purpose: This is an additional query counterpart of H5Pset_filter() and - * returns information about a particular filter in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. The ID - * should be the filter ID to retrieve the parameters for. If the - * filter is not set for the property list, an error will be returned. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, April 5, 2003 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pget_filter_by_id1, FAIL) - H5TRACE7("e", "iZfx*zxzx", plist_id, id, flags, cd_nelmts, cd_values, namelen, - name); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get filter info */ - if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter_by_id1() */ - -#endif /* H5_NO_DEPRECATED_SYMBOLS */ - diff --git a/src/H5Pdeprec.c b/src/H5Pdeprec.c index 208fcb2..5c72247 100644 --- a/src/H5Pdeprec.c +++ b/src/H5Pdeprec.c @@ -440,5 +440,59 @@ H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value, done: FUNC_LEAVE_API(ret_value); } /* H5Pinsert1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_version + * + * Purpose: Retrieves version information for various parts of a file. + * + * SUPER: The file super block. + * FREELIST: The global free list. + * STAB: The root symbol table entry. + * SHHDR: Shared object headers. + * + * Any (or even all) of the output arguments can be null + * pointers. + * + * Return: Success: Non-negative, version information is returned + * through the arguments. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_version(hid_t plist_id, unsigned *super/*out*/, unsigned *freelist/*out*/, + unsigned *stab/*out*/, unsigned *shhdr/*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pget_version, FAIL) + H5TRACE5("e", "ixxxx", plist_id, super, freelist, stab, shhdr); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get values */ + if(super) + if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, super) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get superblock version") + if(freelist) + *freelist = HDF5_FREESPACE_VERSION; /* (hard-wired) */ + if(stab) + *stab = HDF5_OBJECTDIR_VERSION; /* (hard-wired) */ + if(shhdr) + *shhdr = HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_version() */ + #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index efbdfe7..aab8b57 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -839,7 +839,7 @@ H5Pget_preserve(hid_t plist_id) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Get value */ - if (H5P_get(plist,H5D_XFER_BKGR_BUF_NAME,&need_bkg)<0) + if (H5P_get(plist,H5D_XFER_BKGR_BUF_TYPE_NAME,&need_bkg)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") /* Set return value */ diff --git a/src/H5Pfcpl.c b/src/H5Pfcpl.c index 406dbe1..cb3bccd 100644 --- a/src/H5Pfcpl.c +++ b/src/H5Pfcpl.c @@ -55,10 +55,10 @@ #define H5F_CRT_BTREE_RANK_SIZE sizeof(unsigned[H5B_NUM_BTREE_ID]) #define H5F_CRT_BTREE_RANK_DEF {HDF5_BTREE_SNODE_IK_DEF,HDF5_BTREE_CHUNK_IK_DEF} /* Definitions for byte number in an address */ -#define H5F_CRT_ADDR_BYTE_NUM_SIZE sizeof(size_t) +#define H5F_CRT_ADDR_BYTE_NUM_SIZE sizeof(uint8_t) #define H5F_CRT_ADDR_BYTE_NUM_DEF H5F_OBJ_ADDR_SIZE /* Definitions for byte number for object size */ -#define H5F_CRT_OBJ_BYTE_NUM_SIZE sizeof(size_t) +#define H5F_CRT_OBJ_BYTE_NUM_SIZE sizeof(uint8_t) #define H5F_CRT_OBJ_BYTE_NUM_DEF H5F_OBJ_SIZE_SIZE /* Definitions for version number of the superblock */ #define H5F_CRT_SUPER_VERS_SIZE sizeof(unsigned) @@ -75,6 +75,11 @@ #define H5F_CRT_SHMSG_LIST_MAX_DEF (50) #define H5F_CRT_SHMSG_BTREE_MIN_SIZE sizeof(unsigned) #define H5F_CRT_SHMSG_BTREE_MIN_DEF (40) +/* Definitions for file space handling strategy */ +#define H5F_CRT_FILE_SPACE_STRATEGY_SIZE sizeof(unsigned) +#define H5F_CRT_FILE_SPACE_STRATEGY_DEF H5F_FILE_SPACE_STRATEGY_DEF +#define H5F_CRT_FREE_SPACE_THRESHOLD_SIZE sizeof(hsize_t) +#define H5F_CRT_FREE_SPACE_THRESHOLD_DEF H5F_FREE_SPACE_THRESHOLD_DEF /******************/ @@ -142,14 +147,16 @@ H5P_fcrt_reg_prop(H5P_genclass_t *pclass) hsize_t userblock_size = H5F_CRT_USER_BLOCK_DEF; /* Default userblock size */ unsigned sym_leaf_k = H5F_CRT_SYM_LEAF_DEF; /* Default size for symbol table leaf nodes */ unsigned btree_k[H5B_NUM_BTREE_ID] = H5F_CRT_BTREE_RANK_DEF; /* Default 'K' values for B-trees in file */ - size_t sizeof_addr = H5F_CRT_ADDR_BYTE_NUM_DEF; /* Default size of addresses in the file */ - size_t sizeof_size = H5F_CRT_OBJ_BYTE_NUM_DEF; /* Default size of sizes in the file */ + uint8_t sizeof_addr = H5F_CRT_ADDR_BYTE_NUM_DEF; /* Default size of addresses in the file */ + uint8_t sizeof_size = H5F_CRT_OBJ_BYTE_NUM_DEF; /* Default size of sizes in the file */ unsigned superblock_ver = H5F_CRT_SUPER_VERS_DEF; /* Default superblock version # */ unsigned num_sohm_indexes = H5F_CRT_SHMSG_NINDEXES_DEF; unsigned sohm_index_flags[H5O_SHMESG_MAX_NINDEXES] = H5F_CRT_SHMSG_INDEX_TYPES_DEF; unsigned sohm_index_minsizes[H5O_SHMESG_MAX_NINDEXES] = H5F_CRT_SHMSG_INDEX_MINSIZE_DEF; unsigned sohm_list_max = H5F_CRT_SHMSG_LIST_MAX_DEF; unsigned sohm_btree_min = H5F_CRT_SHMSG_BTREE_MIN_DEF; + unsigned file_space_strategy = H5F_CRT_FILE_SPACE_STRATEGY_DEF; + hsize_t free_space_threshold = H5F_CRT_FREE_SPACE_THRESHOLD_DEF; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_fcrt_reg_prop) @@ -192,65 +199,19 @@ H5P_fcrt_reg_prop(H5P_genclass_t *pclass) 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) 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) + 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) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_fcrt_reg_prop() */ /*------------------------------------------------------------------------- - * Function: H5Pget_version - * - * Purpose: Retrieves version information for various parts of a file. - * - * SUPER: The file super block. - * FREELIST: The global free list. - * STAB: The root symbol table entry. - * SHHDR: Shared object headers. - * - * Any (or even all) of the output arguments can be null - * pointers. - * - * Return: Success: Non-negative, version information is returned - * through the arguments. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_version(hid_t plist_id, unsigned *super/*out*/, unsigned *freelist/*out*/, - unsigned *stab/*out*/, unsigned *shhdr/*out*/) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pget_version, FAIL) - H5TRACE5("e", "ixxxx", plist_id, super, freelist, stab, shhdr); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get values */ - if(super) - if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, super) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get superblock version") - if(freelist) - *freelist = HDF5_FREESPACE_VERSION; /* (hard-wired) */ - if(stab) - *stab = HDF5_OBJECTDIR_VERSION; /* (hard-wired) */ - if(shhdr) - *shhdr = HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */ - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_version() */ - - -/*------------------------------------------------------------------------- * Function: H5Pset_userblock * * Purpose: Sets the userblock size field of a file creation property @@ -351,46 +312,48 @@ done: * Programmer: Robb Matzke * Tuesday, January 6, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t H5Pset_sizes(hid_t plist_id, size_t sizeof_addr, size_t sizeof_size) { H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ + herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_API(H5Pset_sizes, FAIL); + FUNC_ENTER_API(H5Pset_sizes, FAIL) H5TRACE3("e", "izz", plist_id, sizeof_addr, sizeof_size); /* Check arguments */ - if (sizeof_addr) { - if (sizeof_addr != 2 && sizeof_addr != 4 && - sizeof_addr != 8 && sizeof_addr != 16) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file haddr_t size is not valid"); - } - if (sizeof_size) { - if (sizeof_size != 2 && sizeof_size != 4 && - sizeof_size != 8 && sizeof_size != 16) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file size_t size is not valid"); - } + if(sizeof_addr) { + if(sizeof_addr != 2 && sizeof_addr != 4 && sizeof_addr != 8 && sizeof_addr != 16) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file haddr_t size is not valid") + } /* end if */ + if(sizeof_size) { + if(sizeof_size != 2 && sizeof_size != 4 && sizeof_size != 8 && sizeof_size != 16) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file size_t size is not valid") + } /* end if */ /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Set value */ - if (sizeof_addr) - if(H5P_set(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for an address"); - if (sizeof_size) - if(H5P_set(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for object "); + if(sizeof_addr) { + uint8_t tmp_sizeof_addr = (uint8_t)sizeof_addr; + + if(H5P_set(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &tmp_sizeof_addr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for an address") + } /* end if */ + if(sizeof_size) { + uint8_t tmp_sizeof_size = (uint8_t)sizeof_size; + + if(H5P_set(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &tmp_sizeof_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set byte number for object ") + } /* end if */ done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_sizes() */ /*------------------------------------------------------------------------- @@ -401,41 +364,45 @@ done: * even both) SIZEOF_ADDR and SIZEOF_SIZE may be null pointers. * * Return: Success: Non-negative, sizes returned through arguments. - * * Failure: Negative * * Programmer: Robb Matzke * Wednesday, January 7, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t -H5Pget_sizes(hid_t plist_id, - size_t *sizeof_addr /*out */ , size_t *sizeof_size /*out */ ) +H5Pget_sizes(hid_t plist_id, size_t *sizeof_addr, size_t *sizeof_size) { H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ + herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_API(H5Pget_sizes, FAIL); - H5TRACE3("e", "ixx", plist_id, sizeof_addr, sizeof_size); + FUNC_ENTER_API(H5Pget_sizes, FAIL) + H5TRACE3("e", "i*z*z", plist_id, sizeof_addr, sizeof_size); /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Get values */ - if (sizeof_addr) - if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, sizeof_addr) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for an address"); - if (sizeof_size) - if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, sizeof_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for object "); + if(sizeof_addr) { + uint8_t tmp_sizeof_addr; + + if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &tmp_sizeof_addr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for an address") + *sizeof_addr = tmp_sizeof_addr; + } /* end if */ + if(sizeof_size) { + uint8_t tmp_sizeof_size; + + if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &tmp_sizeof_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get byte number for object ") + *sizeof_size = tmp_sizeof_size; + } /* end if */ done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_sizes() */ /*------------------------------------------------------------------------- @@ -943,3 +910,88 @@ done: FUNC_LEAVE_API(ret_value); } /* end H5Pget_shared_mesg_phase_change() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_file_space + * + * Purpose: Sets the strategy that the library employs in managing file space. + * If strategy is zero, the property is not changed; the existing + * strategy is retained. + * Sets the threshold value that the file's free space + * manager(s) will use to track free space sections. + * If threshold is zero, the property is not changed; the existing + * threshold is retained. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 10, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_file_space(hid_t plist_id, H5F_file_space_type_t strategy, hsize_t threshold) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pset_file_space, FAIL) + H5TRACE3("e", "iFfh", plist_id, strategy, threshold); + + if((unsigned)strategy >= H5F_FILE_SPACE_NTYPES) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid strategy") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set value(s), if non-zero */ + if(strategy) + if(H5P_set(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &strategy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set file space strategy") + if(threshold) + if(H5P_set(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &threshold) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set free-space threshold") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Pset_file_space() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_file_space + * + * Purpose: Retrieves the strategy that the library uses in managing file space. + * Retrieves the threshold value that the file's free space + * managers use to track free space sections. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 10, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_file_space(hid_t plist_id, H5F_file_space_type_t *strategy, hsize_t *threshold) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pget_file_space, FAIL) + H5TRACE3("e", "i*Ff*h", plist_id, strategy, threshold); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get value(s) */ + if(strategy) + if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, strategy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file space strategy") + if(threshold) + if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, threshold) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get free-space threshold") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Pget_file_space() */ + diff --git a/src/H5Pint.c b/src/H5Pint.c index 364cab2..4da7f09 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -782,14 +782,22 @@ H5P_copy_plist(H5P_genplist_t *old_plist, hbool_t app_ref) /* 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; - /* Call the class callback (if it exists) now that we have the property list ID */ - if(new_plist->pclass->copy_func!=NULL) { - if((new_plist->pclass->copy_func)(new_plist_id,old_plist->plist_id,old_plist->pclass->copy_data) < 0) { - /* Delete ID, ignore return value */ - H5I_remove(new_plist_id); - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); + /* Call the class callback (if it exists) now that we have the property list ID + * (up through chain of parent classes also) + */ + tclass = new_plist->pclass; + while(NULL != tclass) { + if(NULL != tclass->copy_func) { + if((tclass->copy_func)(new_plist_id, old_plist->plist_id, old_plist->pclass->copy_data) < 0) { + /* Delete ID, ignore return value */ + H5I_remove(new_plist_id); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property") + } /* end if */ } /* end if */ - } /* end if */ + + /* Go up to parent class */ + tclass = tclass->parent; + } /* end while */ /* Set the class initialization flag */ new_plist->class_init=1; @@ -1658,8 +1666,9 @@ done: hid_t H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref) { - H5P_genplist_t *plist=NULL; /* Property list created */ - hid_t plist_id=FAIL; /* Property list ID */ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genplist_t *plist = NULL; /* Property list created */ + hid_t plist_id = FAIL; /* Property list ID */ hid_t ret_value; /* return value */ FUNC_ENTER_NOAPI(H5P_create_id, FAIL); @@ -1677,14 +1686,22 @@ H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref) /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */ plist->plist_id=plist_id; - /* Call the class callback (if it exists) now that we have the property list ID */ - if(plist->pclass->create_func!=NULL) { - if((plist->pclass->create_func)(plist_id,plist->pclass->create_data) < 0) { - /* Delete ID, ignore return value */ - H5I_remove(plist_id); - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); + /* Call the class callback (if it exists) now that we have the property list ID + * (up through chain of parent classes also) + */ + tclass = plist->pclass; + while(NULL != tclass) { + if(NULL != tclass->create_func) { + if((tclass->create_func)(plist_id, tclass->create_data) < 0) { + /* Delete ID, ignore return value */ + H5I_remove(plist_id); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property") + } /* end if */ } /* end if */ - } /* end if */ + + /* Go up to parent class */ + tclass = tclass->parent; + } /* end while */ /* Set the class initialization flag */ plist->class_init=1; @@ -4058,10 +4075,20 @@ H5P_close(void *_plist) assert(plist); - /* Make call to property list class close callback, if needed */ - if(plist->class_init!=0 && plist->pclass->close_func!=NULL) { - /* Call user's "close" callback function, ignoring return value */ - (plist->pclass->close_func)(plist->plist_id,plist->pclass->close_data); + /* Make call to property list class close callback, if needed + * (up through chain of parent classes also) + */ + if(plist->class_init !=0) { + tclass = plist->pclass; + while(NULL != tclass) { + if(NULL != tclass->close_func) { + /* Call user's "close" callback function, ignoring return value */ + (tclass->close_func)(plist->plist_id, tclass->close_data); + } /* end if */ + + /* Go up to parent class */ + tclass = tclass->parent; + } /* end while */ } /* end if */ /* Create the skip list to hold names of properties already seen diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index a28eeb3..9f144f1 100755 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -52,6 +52,9 @@ #define H5O_CRT_ATTR_MIN_DENSE_SIZE sizeof(unsigned) /* Definitions for object header flags */ #define H5O_CRT_OHDR_FLAGS_SIZE sizeof(uint8_t) +/* Definitions for filter pipeline */ +#define H5O_CRT_PIPELINE_SIZE sizeof(H5O_pline_t) +#define H5O_CRT_PIPELINE_CMP H5P_ocrt_pipeline_cmp /******************/ @@ -70,6 +73,11 @@ /* Property class callbacks */ static herr_t H5P_ocrt_reg_prop(H5P_genclass_t *pclass); +static herr_t H5P_ocrt_copy(hid_t new_plist_t, hid_t old_plist_t, void *copy_data); +static herr_t H5P_ocrt_close(hid_t dxpl_id, void *close_data); + +/* Property callbacks */ +static int H5P_ocrt_pipeline_cmp(const void *value1, const void *value2, size_t size); /*********************/ @@ -85,9 +93,9 @@ const H5P_libclass_t H5P_CLS_OCRT[1] = {{ H5P_ocrt_reg_prop, /* Default property registration routine */ NULL, /* Class creation callback */ NULL, /* Class creation callback info */ - NULL, /* Class copy callback */ + H5P_ocrt_copy, /* Class copy callback */ NULL, /* Class copy callback info */ - NULL, /* Class close callback */ + H5P_ocrt_close, /* Class close callback */ NULL /* Class close callback info */ }}; @@ -121,7 +129,8 @@ H5P_ocrt_reg_prop(H5P_genclass_t *pclass) { unsigned attr_max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF; /* Default max. compact attribute storage settings */ unsigned attr_min_dense = H5O_CRT_ATTR_MIN_DENSE_DEF; /* Default min. dense attribute storage settings */ - uint8_t ohdr_flags = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */ + uint8_t ohdr_flags = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */ + H5O_pline_t pline = H5O_CRT_PIPELINE_DEF; /* Default I/O pipeline setting */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_reg_prop) @@ -141,12 +150,108 @@ H5P_ocrt_reg_prop(H5P_genclass_t *pclass) &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) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_ocrt_reg_prop() */ /*------------------------------------------------------------------------- + * Function: H5P_ocrt_copy + * + * Purpose: Callback routine which is called whenever any object + * creation property list is copied. This routine copies + * the properties from the old list to the new list. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Monday, September 21, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5P_ocrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) +{ + H5O_pline_t src_pline, dst_pline; /* Source & destination pipelines */ + H5P_genplist_t *src_plist; /* Pointer to source property list */ + H5P_genplist_t *dst_plist; /* Pointer to destination property list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_copy) + + /* Verify property list IDs */ + if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list") + if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list") + + /* Get the link pipeline property from the old property list */ + if(H5P_get(src_plist, H5O_CRT_PIPELINE_NAME, &src_pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Make copy of link pipeline */ + if(NULL == H5O_msg_copy(H5O_PLINE_ID, &src_pline, &dst_pline)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy link pipeline") + + /* Set the link pipeline property for the destination property list */ + if(H5P_set(dst_plist, H5O_CRT_PIPELINE_NAME, &dst_pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_ocrt_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_ocrt_close + * + * Purpose: Callback routine which is called whenever any object create + * property list is closed. This routine performs any generic + * cleanup needed on the properties the library put into the list. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Monday, September 21, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5P_ocrt_close(hid_t dcpl_id, void UNUSED *close_data) +{ + H5O_pline_t pline; /* I/O pipeline */ + H5P_genplist_t *plist; /* Property list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_close) + + /* Check arguments */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list") + + /* Get the link pipeline property from the old property list */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Clean up any values set for the link pipeline */ + if(H5O_msg_reset(H5O_PLINE_ID, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release pipeline info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_ocrt_close() */ + + +/*------------------------------------------------------------------------- * Function: H5Pset_attr_phase_change * * Purpose: Sets the cutoff values for indexes storing attributes @@ -437,3 +542,1043 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_obj_track_times() */ + +/*------------------------------------------------------------------------- + * Function: H5P_modify_filter + * + * Purpose: Modifies the specified FILTER in the + * transient or permanent output filter pipeline + * depending on whether PLIST is a dataset creation or dataset + * transfer property list. The FLAGS argument specifies certain + * general properties of the filter and is documented below. + * The CD_VALUES is an array of CD_NELMTS integers which are + * auxiliary data for the filter. The integer vlues will be + * stored in the dataset object header as part of the filter + * information. + * + * The FLAGS argument is a bit vector of the following fields: + * + * H5Z_FLAG_OPTIONAL(0x0001) + * If this bit is set then the filter is optional. If the + * filter fails during an H5Dwrite() operation then the filter + * is just excluded from the pipeline for the chunk for which it + * failed; the filter will not participate in the pipeline + * during an H5Dread() of the chunk. If this bit is clear and + * the filter fails then the entire I/O operation fails. + * If this bit is set but encoding is disabled for a filter, + * attempting to write will generate an error. + * + * Note: This function currently supports only the permanent filter + * pipeline. That is, PLIST_ID must be a dataset creation + * property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, October 17, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned flags, + size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/]) +{ + H5O_pline_t pline; + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI(H5P_modify_filter, FAIL) + + /* Get the pipeline property to modify */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Modify the filter parameters of the I/O pipeline */ + if(H5Z_modify(&pline, filter, flags, cd_nelmts, cd_values) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_modify_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pmodify_filter + * + * Purpose: Modifies the specified FILTER in the + * transient or permanent output filter pipeline + * depending on whether PLIST is a dataset creation or dataset + * transfer property list. The FLAGS argument specifies certain + * general properties of the filter and is documented below. + * The CD_VALUES is an array of CD_NELMTS integers which are + * auxiliary data for the filter. The integer vlues will be + * stored in the dataset object header as part of the filter + * information. + * + * The FLAGS argument is a bit vector of the following fields: + * + * H5Z_FLAG_OPTIONAL(0x0001) + * If this bit is set then the filter is optional. If the + * filter fails during an H5Dwrite() operation then the filter + * is just excluded from the pipeline for the chunk for which it + * failed; the filter will not participate in the pipeline + * during an H5Dread() of the chunk. If this bit is clear and + * the filter fails then the entire I/O operation fails. + * If this bit is set but encoding is disabled for a filter, + * attempting to write will generate an error. + * + * Note: This function currently supports only the permanent filter + * pipeline. That is, PLIST_ID must be a dataset creation + * property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, April 5, 2003 + * + * Modifications: + * + * Neil Fortner + * Thursday, March 26, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, + size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) +{ + H5P_genplist_t *plist; /* Property list */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pmodify_filter, FAIL) + H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); + + /* Check args */ + if (filter<0 || filter>H5Z_FILTER_MAX) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") + if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") + if (cd_nelmts>0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + + /* Modify the filter parameters of the I/O pipeline */ + if(H5P_modify_filter(plist, filter, flags, cd_nelmts, cd_values) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't modify filter") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pmodify_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_filter + * + * Purpose: Adds the specified FILTER and corresponding properties to the + * end of the data or link output filter pipeline + * depending on whether PLIST is a dataset creation or group + * creation property list. The FLAGS argument specifies certain + * general properties of the filter and is documented below. + * The CD_VALUES is an array of CD_NELMTS integers which are + * auxiliary data for the filter. The integer vlues will be + * stored in the dataset object header as part of the filter + * information. + * + * The FLAGS argument is a bit vector of the following fields: + * + * H5Z_FLAG_OPTIONAL(0x0001) + * If this bit is set then the filter is optional. If the + * filter fails during an H5Dwrite() operation then the filter + * is just excluded from the pipeline for the chunk for which it + * failed; the filter will not participate in the pipeline + * during an H5Dread() of the chunk. If this bit is clear and + * the filter fails then the entire I/O operation fails. + * If this bit is set but encoding is disabled for a filter, + * attempting to write will generate an error. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + * Modifications: + * + * Raymond Lu + * Tuesday, October 2, 2001 + * Changed the way to check parameter and set property for + * generic property list. + * + * Neil Fortner + * Wednesday, May 20, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, + size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_filter, FAIL) + H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); + + /* Check args */ + if (filter<0 || filter>H5Z_FILTER_MAX) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") + if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") + if (cd_nelmts>0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to append to */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Add the filter to the I/O pipeline */ + if(H5Z_append(&pline, filter, flags, cd_nelmts, cd_values) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_nfilters + * + * Purpose: Returns the number of filters in the data or link + * pipeline depending on whether PLIST_ID is a dataset creation + * or group creation property list. In each pipeline the + * filters are numbered from zero through N-1 where N is the + * value returned by this function. During output to the file + * the filters of a pipeline are applied in increasing order + * (the inverse is true for input). + * + * Return: Success: Number of filters or zero if there are none. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Tuesday, August 4, 1998 + * + * Modifications: + * + * Neil Fortner + * Wednesday, May 20, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +int +H5Pget_nfilters(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + int ret_value; /* return value */ + + FUNC_ENTER_API(H5Pget_nfilters, FAIL) + H5TRACE1("Is", "i", plist_id); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Set return value */ + ret_value=(int)(pline.nused); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_nfilters */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter2 + * + * Purpose: This is the query counterpart of H5Pset_filter() and returns + * information about a particular filter number in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. FILTER_CONFIG is a bit + * field contaning encode/decode flags from H5Zpublic.h. The IDX + * should be a value between zero and N-1 as described for + * H5Pget_nfilters() and the function will return failure if the + * filter number is out of range. + * + * Return: Success: Filter identification number. + * + * Failure: H5Z_FILTER_ERROR (Negative) + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + * Modifications: + * + * Neil Fortner + * Wednesday, May 20, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +H5Z_filter_t +H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, + unsigned *filter_config /*out*/) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + const H5Z_filter_info_t *filter; /* Pointer to filter information */ + H5Z_filter_t ret_value; /* return value */ + + FUNC_ENTER_API(H5Pget_filter2, H5Z_FILTER_ERROR) + H5TRACE8("Zf", "iIux*zxzxx", plist_id, idx, flags, cd_nelmts, cd_values, + namelen, name, filter_config); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") + + /* Check index */ + if(idx >= pline.nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") + + /* Set pointer to particular filter to query */ + filter = &pline.filter[idx]; + + /* Get filter information */ + if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") + + /* Set return value */ + ret_value = filter->id; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter2() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_get_filter_by_id + * + * Purpose: This is an additional query counterpart of H5Pset_filter() and + * returns information about a particular filter in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. FILTER_CONFIG is a bit + * field contaning encode/decode flags from H5Zpublic.h. The ID + * should be the filter ID to retrieve the parameters for. If the + * filter is not set for the property list, an error will be returned. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Wednesday, October 17, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, unsigned *filter_config) +{ + H5O_pline_t pline; /* Filter pipeline */ + H5Z_filter_info_t *filter; /* Pointer to filter information */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_get_filter_by_id, FAIL) + + /* Get pipeline info */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Get pointer to filter in pipeline */ + if(NULL == (filter = H5Z_filter_info(&pline, id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid") + + /* Get filter information */ + if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_get_filter_by_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter_by_id2 + * + * Purpose: This is an additional query counterpart of H5Pset_filter() and + * returns information about a particular filter in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. FILTER_CONFIG is a bit + * field contaning encode/decode flags from H5Zpublic.h. The ID + * should be the filter ID to retrieve the parameters for. If the + * filter is not set for the property list, an error will be returned. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, April 5, 2003 + * + * Modifications: + * + * Neil Fortner + * Thursday, May 21, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, unsigned *filter_config) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + const H5Z_filter_info_t *filter; /* Pointer to filter information */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pget_filter_by_id2, FAIL) + H5TRACE8("e", "iZfx*zxzx*Iu", plist_id, id, flags, cd_nelmts, cd_values, + namelen, name, filter_config); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Get pointer to filter in pipeline */ + if(NULL == (filter = H5Z_filter_info(&pline, id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid") + + /* Get filter information */ + if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, + name, filter_config) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter_by_id2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pall_filters_avail + * + * Purpose: This is a query routine to verify that all the filters set + * in the dataset creation property list are available currently. + * + * Return: Success: TRUE if all filters available, FALSE if one or + * more filters not currently available. + * Failure: FAIL on error + * + * Programmer: Quincey Koziol + * Tuesday, April 8, 2003 + * + * Modifications: + * + * Neil Fortner + * Thursday, May 21, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +htri_t +H5Pall_filters_avail(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Pall_filters_avail, FAIL) + H5TRACE1("t", "i", plist_id); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Check if all filters are available */ + if((ret_value = H5Z_all_filters_avail(&pline)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't check pipeline information") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pall_filters_avail() */ + + +/*------------------------------------------------------------------------- + * Function: H5Premove_filter + * + * Purpose: Deletes a filter from the dataset creation property list; + * deletes all filters if FILTER is H5Z_FILTER_NONE + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Pedro Vicente + * January 26, 2004 + * + * Modifications: + * + * Neil Fortner + * Thursday, May 21, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Premove_filter(hid_t plist_id, H5Z_filter_t filter) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Premove_filter, FAIL) + H5TRACE2("e", "iZf", plist_id, filter); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to modify */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Check if there are any filters */ + if (pline.filter) { + /* Delete filter */ + if(H5Z_delete(&pline, filter) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't delete filter") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Premove_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_deflate + * + * Purpose: Sets the compression method for a dataset or group link + * filter pipeline (depending on whether PLIST_ID is a dataset + * creation or group creation property list) to H5Z_FILTER_DEFLATE + * and the compression level to LEVEL which should be a value + * between zero and nine, inclusive. Lower compression levels + * are faster but result in less compression. This is the same + * algorithm as used by the GNU gzip program. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + * Modifications: + * + * Raymond Lu + * Tuesday, October 2, 2001 + * Changed the way to check parameter and set property for + * generic property list. + * + * Neil Fortner + * Thursday, March 26, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_deflate(hid_t plist_id, unsigned level) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_deflate, FAIL) + H5TRACE2("e", "iIu", plist_id, level); + + /* Check arguments */ + if(level > 9) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to append to */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Add the filter */ + if(H5Z_append(&pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &level) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_deflate() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fletcher32 + * + * Purpose: Sets Fletcher32 checksum of EDC for a dataset creation + * property list or group creation property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Dec 19, 2002 + * + * Modifications: + * + * Neil Fortner + * Wednesday, May 6, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fletcher32(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_fletcher32, FAIL) + H5TRACE1("e", "i", plist_id); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to append to */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Add the Fletcher32 checksum as a filter */ + if(H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_fletcher32() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_get_filter + * + * Purpose: Internal component of H5Pget_filter & H5Pget_filter_id + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, October 23, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_get_filter(const H5Z_filter_info_t *filter, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, + unsigned *filter_config /*out*/) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_filter) + + /* Check arguments */ + HDassert(filter); + + /* Filter flags */ + if(flags) + *flags = filter->flags; + + /* Filter parameters */ + if(cd_values) { + size_t i; /* Local index variable */ + + for(i = 0; i < filter->cd_nelmts && i < *cd_nelmts; i++) + cd_values[i] = filter->cd_values[i]; + } /* end if */ + + /* Number of filter parameters */ + if(cd_nelmts) + *cd_nelmts = filter->cd_nelmts; + + /* Filter name */ + if(namelen > 0 && name) { + const char *s = filter->name; + + /* If there's no name on the filter, use the class's filter name */ + if(!s) { + H5Z_class2_t *cls = H5Z_find(filter->id); + + if(cls) + s = cls->name; + } /* end if */ + + /* Check for actual name */ + if(s) { + HDstrncpy(name, s, namelen); + name[namelen - 1] = '\0'; + } /* end if */ + else { + /* Check for unknown library filter */ + /* (probably from a future version of the library) */ + if(filter->id < 256) { + HDstrncpy(name, "Unknown library filter", namelen); + name[namelen - 1] = '\0'; + } /* end if */ + else + name[0] = '\0'; + } /* end if */ + } /* end if */ + + /* Filter configuration (assume filter ID has already been checked) */ + if(filter_config) + H5Zget_filter_info(filter->id, filter_config); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P_get_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_ocrt_pipeline_cmp + * + * Purpose: Callback routine which is called whenever a filter pipeline + * property in a property list is compared. + * + * Return: positive if VALUE1 is greater than VALUE2, negative if + * VALUE2 is greater than VALUE1 and zero if VALUE1 and + * VALUE2 are equal. + * + * Programmer: Quincey Koziol + * Wednesday, January 7, 2004 + * + *------------------------------------------------------------------------- + */ +int +H5P_ocrt_pipeline_cmp(const void *_pline1, const void *_pline2, size_t UNUSED size) +{ + const H5O_pline_t *pline1 = (const H5O_pline_t *)_pline1, /* Create local aliases for values */ + *pline2 = (const H5O_pline_t *)_pline2; + int cmp_value; /* Value from comparison */ + herr_t ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI_NOFUNC(H5P_ocrt_pipeline_cmp) + + /* Sanity check */ + HDassert(pline1); + HDassert(pline2); + HDassert(size == sizeof(H5O_pline_t)); + + /* Check the number of allocated pipeline entries */ + if(pline1->nalloc < pline2->nalloc) HGOTO_DONE(-1); + if(pline1->nalloc > pline2->nalloc) HGOTO_DONE(1); + + /* Check the number of used pipeline entries */ + if(pline1->nused < pline2->nused) HGOTO_DONE(-1); + if(pline1->nused > pline2->nused) HGOTO_DONE(1); + + /* Check the filter entry information */ + if(pline1->filter == NULL && pline2->filter != NULL) HGOTO_DONE(-1); + if(pline1->filter != NULL && pline2->filter == NULL) HGOTO_DONE(1); + if(pline1->filter != NULL && pline1->nused > 0) { + size_t u; /* Local index variable */ + + /* Loop through all filters, comparing them */ + for(u = 0; u < pline1->nused; u++) { + /* Check the ID of the filter */ + if(pline1->filter[u].id < pline2->filter[u].id) HGOTO_DONE(-1); + if(pline1->filter[u].id > pline2->filter[u].id) HGOTO_DONE(1); + + /* Check the flags for the filter */ + if(pline1->filter[u].flags < pline2->filter[u].flags) HGOTO_DONE(-1); + if(pline1->filter[u].flags > pline2->filter[u].flags) HGOTO_DONE(1); + + /* Check the name of the filter */ + if(pline1->filter[u].name == NULL && pline2->filter[u].name != NULL) HGOTO_DONE(-1); + if(pline1->filter[u].name != NULL && pline2->filter[u].name == NULL) HGOTO_DONE(1); + if(pline1->filter[u].name != NULL) + if((cmp_value = HDstrcmp(pline1->filter[u].name, pline2->filter[u].name)) != 0) + HGOTO_DONE(cmp_value); + + /* Check the number of parameters for the filter */ + if(pline1->filter[u].cd_nelmts < pline2->filter[u].cd_nelmts) HGOTO_DONE(-1); + if(pline1->filter[u].cd_nelmts > pline2->filter[u].cd_nelmts) HGOTO_DONE(1); + + /* Check the filter parameter information */ + if(pline1->filter[u].cd_values == NULL && pline2->filter[u].cd_values != NULL) HGOTO_DONE(-1); + if(pline1->filter[u].cd_values != NULL && pline2->filter[u].cd_values == NULL) HGOTO_DONE(1); + if(pline1->filter[u].cd_values != NULL && pline1->filter[u].cd_nelmts > 0) { + size_t v; /* Local index variable */ + + /* Loop through all parameters, comparing them */ + for(v = 0; v < pline1->filter[u].cd_nelmts; v++) { + /* Check each parameter for the filter */ + if(pline1->filter[u].cd_values[v] < pline2->filter[u].cd_values[v]) HGOTO_DONE(-1); + if(pline1->filter[u].cd_values[v] > pline2->filter[u].cd_values[v]) HGOTO_DONE(1); + } /* end for */ + } /* end if */ + } /* end for */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_ocrt_pipeline_cmp() */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter1 + * + * Purpose: This is the query counterpart of H5Pset_filter() and returns + * information about a particular filter number in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. The IDX + * should be a value between zero and N-1 as described for + * H5Pget_nfilters() and the function will return failure if the + * filter number is out of range. + * + * Return: Success: Filter identification number. + * + * Failure: H5Z_FILTER_ERROR (Negative) + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + *------------------------------------------------------------------------- + */ +H5Z_filter_t +H5Pget_filter1(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/) +{ + H5O_pline_t pline; /* Filter pipeline */ + const H5Z_filter_info_t *filter; /* Pointer to filter information */ + H5P_genplist_t *plist; /* Property list pointer */ + H5Z_filter_t ret_value; /* return value */ + + FUNC_ENTER_API(H5Pget_filter1, H5Z_FILTER_ERROR) + H5TRACE7("Zf", "iIux*zxzx", plist_id, idx, flags, cd_nelmts, cd_values, namelen, + name); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") + + /* Get pipeline info */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") + + /* Check more args */ + if(idx >= pline.nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") + + /* Set pointer to particular filter to query */ + filter = &pline.filter[idx]; + + /* Get filter information */ + if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") + + /* Set return value */ + ret_value = filter->id; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter_by_id1 + * + * Purpose: This is an additional query counterpart of H5Pset_filter() and + * returns information about a particular filter in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. The ID + * should be the filter ID to retrieve the parameters for. If the + * filter is not set for the property list, an error will be returned. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, April 5, 2003 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pget_filter_by_id1, FAIL) + H5TRACE7("e", "iZfx*zxzx", plist_id, id, flags, cd_nelmts, cd_values, namelen, + name); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get filter info */ + if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter_by_id1() */ + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index 2959ddc..fd9c65a 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -178,6 +178,9 @@ H5_DLL char *H5P_get_class_path(H5P_genclass_t *pclass); H5_DLL H5P_genclass_t *H5P_open_class_path(const char *path); H5_DLL H5P_genclass_t *H5P_get_class_parent(const H5P_genclass_t *pclass); H5_DLL herr_t H5P_close_class(void *_pclass); +H5_DLL herr_t H5P_get_filter(const H5Z_filter_info_t *filter, + unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[], + size_t namelen, char name[], unsigned *filter_config); /* Testing functions */ #ifdef H5P_TESTING diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 885249d..0b37938 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -86,6 +86,11 @@ H5_DLL herr_t H5P_is_fill_value_defined(const H5O_fill_t *fill, H5D_fill_value_t *status); H5_DLL int H5P_fill_value_cmp(const void *value1, const void *value2, size_t size); +H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, + unsigned flags, size_t cd_nelmts, const unsigned cd_values[]); +H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, + unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[], + size_t namelen, char name[], unsigned *filter_config); /* *SPECIAL* Don't make more of these! -QAK */ H5_DLL htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id); @@ -98,12 +103,6 @@ H5_DLL void *H5P_peek_voidp(H5P_genplist_t *plist, const char *name); H5_DLL size_t H5P_peek_size_t(H5P_genplist_t *plist, const char *name); /* Private DCPL routines */ -H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, - unsigned flags, size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/]); -H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, - unsigned int *flags/*out*/, size_t *cd_nelmts/*in_out*/, - unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/, - unsigned *filter_config); H5_DLL herr_t H5P_fill_value_defined(H5P_genplist_t *plist, H5D_fill_value_t *status); H5_DLL herr_t H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type, diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 495ba42..1c0bb61 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -206,11 +206,29 @@ H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flag H5_DLL herr_t H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags); H5_DLL herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times); H5_DLL herr_t H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times); +H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, + unsigned int flags, size_t cd_nelmts, + const unsigned int cd_values[/*cd_nelmts*/]); +H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, + unsigned int flags, size_t cd_nelmts, + const unsigned int c_values[]); +H5_DLL int H5Pget_nfilters(hid_t plist_id); +H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter, + unsigned int *flags/*out*/, + size_t *cd_nelmts/*out*/, + unsigned cd_values[]/*out*/, + size_t namelen, char name[], + unsigned *filter_config /*out*/); +H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, + unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/, + unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/, + unsigned *filter_config/*out*/); +H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id); +H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter); +H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression); +H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id); /* File creation property list (FCPL) routines */ -H5_DLL herr_t H5Pget_version(hid_t plist_id, unsigned *boot/*out*/, - unsigned *freelist/*out*/, unsigned *stab/*out*/, - unsigned *shhdr/*out*/); H5_DLL herr_t H5Pset_userblock(hid_t plist_id, hsize_t size); H5_DLL herr_t H5Pget_userblock(hid_t plist_id, hsize_t *size); H5_DLL herr_t H5Pset_sizes(hid_t plist_id, size_t sizeof_addr, @@ -227,6 +245,8 @@ H5_DLL herr_t H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsig H5_DLL herr_t H5Pget_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned *mesg_type_flags, unsigned *min_mesg_size); H5_DLL herr_t H5Pset_shared_mesg_phase_change(hid_t plist_id, unsigned max_list, unsigned min_btree); H5_DLL herr_t H5Pget_shared_mesg_phase_change(hid_t plist_id, unsigned *max_list, unsigned *min_btree); +H5_DLL herr_t H5Pset_file_space(hid_t plist_id, H5F_file_space_type_t strategy, hsize_t threshold); +H5_DLL herr_t H5Pget_file_space(hid_t plist_id, H5F_file_space_type_t *strategy, hsize_t *threshold); /* File access property list (FAPL) routines */ @@ -279,31 +299,10 @@ H5_DLL int H5Pget_external_count(hid_t plist_id); H5_DLL herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name/*out*/, off_t *offset/*out*/, hsize_t *size/*out*/); -H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, - unsigned int flags, size_t cd_nelmts, - const unsigned int cd_values[/*cd_nelmts*/]); -H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, - unsigned int flags, size_t cd_nelmts, - const unsigned int c_values[]); -H5_DLL int H5Pget_nfilters(hid_t plist_id); -H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter, - unsigned int *flags/*out*/, - size_t *cd_nelmts/*out*/, - unsigned cd_values[]/*out*/, - size_t namelen, char name[], - unsigned *filter_config /*out*/); -H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, - unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/, - unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/, - unsigned *filter_config/*out*/); -H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id); -H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter); -H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression); H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block); H5_DLL herr_t H5Pset_shuffle(hid_t plist_id); H5_DLL herr_t H5Pset_nbit(hid_t plist_id); H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor); -H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id); H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value); H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, @@ -422,7 +421,9 @@ H5_DLL H5Z_filter_t H5Pget_filter1(hid_t plist_id, unsigned filter, H5_DLL herr_t H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/, unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/); - +H5_DLL herr_t H5Pget_version(hid_t plist_id, unsigned *boot/*out*/, + unsigned *freelist/*out*/, unsigned *stab/*out*/, + unsigned *shhdr/*out*/); #endif /* H5_NO_DEPRECATED_SYMBOLS */ #ifdef __cplusplus @@ -141,31 +141,31 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d /* Get information from fcpl */ if(H5P_get(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &num_indexes)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get number of indexes") if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, &index_type_flags)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM type flags") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM type flags") if(H5P_get(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &list_max)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM list maximum") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM list maximum") if(H5P_get(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &btree_min)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM btree minimum") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM btree minimum") if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, &minsizes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM message min sizes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get SOHM message min sizes") /* Verify that values are valid */ if(num_indexes > H5O_SHMESG_MAX_NINDEXES) - HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "number of indexes in property list is too large") + HGOTO_ERROR(H5E_SOHM, H5E_BADRANGE, FAIL, "number of indexes in property list is too large") /* Check that type flags weren't duplicated anywhere */ type_flags_used = 0; for(x = 0; x < num_indexes; ++x) { if(index_type_flags[x] & type_flags_used) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index") type_flags_used |= index_type_flags[x]; } /* end for */ /* Initialize master table */ if(NULL == (table = H5FL_MALLOC(H5SM_master_table_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM table") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM table") /* Set version and number of indexes in table and in superblock. * Right now we just use one byte to hold the number of indexes. @@ -183,7 +183,7 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d /* Allocate the SOHM indexes as an array. */ if(NULL == (table->indexes = (H5SM_index_header_t *)H5FL_ARR_MALLOC(H5SM_index_header_t, (size_t)table->num_indexes))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM indexes") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM indexes") /* Initialize all of the indexes, but don't allocate space for them to * hold messages until we actually need to write to them. @@ -206,13 +206,13 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d } /* end for */ /* Allocate space for the table on disk */ - table_size = (hsize_t) H5SM_TABLE_SIZE(f) + (hsize_t) (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); + table_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); if(HADDR_UNDEF == (table_addr = H5MF_alloc(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for SOHM table") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "file allocation failed for SOHM table") /* Cache the new table */ if(H5AC_set(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "can't add SOHM table to cache") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINS, FAIL, "can't add SOHM table to cache") /* Record the address of the master table in the file */ f->shared->sohm_addr = table_addr; @@ -276,7 +276,7 @@ H5SM_type_to_flag(unsigned type_id, unsigned *type_flag) break; default: - HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unknown message type ID") + HGOTO_ERROR(H5E_SOHM, H5E_BADTYPE, FAIL, "unknown message type ID") } /* end switch */ done: @@ -311,7 +311,7 @@ H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id) /* Translate the H5O type_id into an H5SM type flag */ if(H5SM_type_to_flag(type_id, &type_flag) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't map message type to flag") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't map message type to flag") /* Search the indexes until we find one that matches this flag or we've * searched them all. @@ -352,12 +352,12 @@ H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id) /* Translate the H5O type_id into an H5SM type flag */ if(H5SM_type_to_flag(type_id, &type_flag) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't map message type to flag") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't map message type to flag") /* Look up the master SOHM table */ if(H5F_addr_defined(f->shared->sohm_addr)) { if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") } /* end if */ else /* No shared messages of any type */ @@ -373,7 +373,7 @@ H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id) done: /* Release the master SOHM table */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_type_shared() */ @@ -407,7 +407,7 @@ H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_ad /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Look up index for message type */ if((index_num = H5SM_get_index(table, type_id)) < 0) @@ -419,7 +419,7 @@ H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_ad done: /* Release the master SOHM table */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_get_fheap_addr() */ @@ -440,36 +440,50 @@ done: static herr_t H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) { - haddr_t list_addr=HADDR_UNDEF; /* Address of SOHM list */ - haddr_t tree_addr=HADDR_UNDEF; /* Address of SOHM B-tree */ - H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */ - H5HF_t *fheap = NULL; + H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5SM_create_index) + /* Sanity check */ HDassert(header); HDassert(header->index_addr == HADDR_UNDEF); HDassert(header->btree_min <= header->list_max + 1); /* In most cases, the index starts as a list */ if(header->list_max > 0) { - header->index_type = H5SM_LIST; + haddr_t list_addr = HADDR_UNDEF; /* Address of SOHM list */ + /* Create the list index */ if((list_addr = H5SM_create_list(f, header, dxpl_id)) == HADDR_UNDEF) HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "list creation failed for SOHM index") + /* Set the index type & address */ + header->index_type = H5SM_LIST; header->index_addr = list_addr; } /* end if */ /* index is a B-tree */ else { + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ + haddr_t tree_addr = HADDR_UNDEF; /* Address of SOHM B-tree */ + + /* Create the v2 B-tree index */ + bt2_cparam.cls = H5SM_INDEX; + bt2_cparam.node_size = (size_t)H5SM_B2_NODE_SIZE; + bt2_cparam.rrec_size = (size_t)H5SM_SOHM_ENTRY_SIZE(f); + bt2_cparam.split_percent = H5SM_B2_SPLIT_PERCENT; + bt2_cparam.merge_percent = H5SM_B2_MERGE_PERCENT; + if(NULL == (bt2 = H5B2_create(f, dxpl_id, &bt2_cparam))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2, &tree_addr) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for SOHM index") + + /* Set the index type & address */ header->index_type = H5SM_BTREE; - - if(H5B2_create(f, dxpl_id, H5SM_INDEX, (size_t)H5SM_B2_NODE_SIZE, - (size_t)H5SM_SOHM_ENTRY_SIZE(f), H5SM_B2_SPLIT_PERCENT, - H5SM_B2_MERGE_PERCENT, &tree_addr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") - header->index_addr = tree_addr; } /* end else */ @@ -484,10 +498,10 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) fheap_cparam.id_len = 0; fheap_cparam.max_man_size = H5O_FHEAP_MAX_MAN_SIZE; if(NULL == (fheap = H5HF_create(f, dxpl_id, &fheap_cparam))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to create fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "unable to create fractal heap") if(H5HF_get_heap_addr(fheap, &(header->heap_addr)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap address") #ifndef NDEBUG { @@ -495,15 +509,17 @@ H5SM_create_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) /* Sanity check ID length */ if(H5HF_get_id_len(fheap, &fheap_id_len) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, FAIL, "can't get fractal heap ID length") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGETSIZE, FAIL, "can't get fractal heap ID length") HDassert(fheap_id_len == H5O_FHEAP_ID_LEN); } #endif /* NDEBUG */ done: - /* Close the fractal heap if one has been created */ + /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_create_index */ @@ -542,7 +558,7 @@ H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id, /* Check the index list's status in the metadata cache */ if(H5AC_get_entry_status(f, header->index_addr, &index_status) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to check metadata cache status for direct block") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "unable to check metadata cache status for direct block") /* If the index list is in the cache, expunge it now */ if(index_status & H5AC_ES__IN_CACHE) { @@ -552,15 +568,15 @@ H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id, /* Evict the index list from the metadata cache */ if(H5AC_expunge_entry(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove list index from cache") + HGOTO_ERROR(H5E_SOHM, H5E_CANTREMOVE, FAIL, "unable to remove list index from cache") } /* end if */ } /* end if */ else { HDassert(header->index_type == H5SM_BTREE); - /* Delete from the B-tree. */ - if(H5B2_delete(f, dxpl_id, H5SM_INDEX, header->index_addr, NULL, NULL) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree") + /* Delete the B-tree. */ + if(H5B2_delete(f, dxpl_id, header->index_addr, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete B-tree") /* Revert to list unless B-trees can have zero records */ if(header->btree_min > 0) @@ -617,9 +633,9 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) /* Allocate list in memory */ if((list = H5FL_MALLOC(H5SM_list_t)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") if((list->messages = (H5SM_sohm_t *)H5FL_ARR_MALLOC(H5SM_sohm_t, num_entries)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") /* Initialize messages in list */ HDmemset(list->messages, 0, sizeof(H5SM_sohm_t) * num_entries); @@ -632,11 +648,11 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) /* Allocate space for the list on disk */ size = H5SM_LIST_SIZE(f, num_entries); if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_SOHM_INDEX, dxpl_id, size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") /* Put the list into the cache */ if(H5AC_set(f, dxpl_id, H5AC_SOHM_LIST, addr, list, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, HADDR_UNDEF, "can't add SOHM list to cache") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINS, HADDR_UNDEF, "can't add SOHM list to cache") /* Set return value */ ret_value = addr; @@ -683,11 +699,13 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, { H5SM_list_t *list; /* Pointer to the existing message list */ H5SM_mesg_key_t key; /* Key for inserting records in v2 B-tree */ + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ haddr_t tree_addr; /* New v2 B-tree's address */ size_t num_messages; /* Number of messages being tracked */ size_t x; void * encoding_buf = NULL; - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5SM_convert_list_to_btree) @@ -698,10 +716,17 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, list = *_list; /* Create the new v2 B-tree for tracking the messages */ - if(H5B2_create(f, dxpl_id, H5SM_INDEX, (size_t)H5SM_B2_NODE_SIZE, - (size_t)H5SM_SOHM_ENTRY_SIZE(f), H5SM_B2_SPLIT_PERCENT, - H5SM_B2_MERGE_PERCENT, &tree_addr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") + bt2_cparam.cls = H5SM_INDEX; + bt2_cparam.node_size = (size_t)H5SM_B2_NODE_SIZE; + bt2_cparam.rrec_size = (size_t)H5SM_SOHM_ENTRY_SIZE(f); + bt2_cparam.split_percent = H5SM_B2_SPLIT_PERCENT; + bt2_cparam.merge_percent = H5SM_B2_MERGE_PERCENT; + if(NULL == (bt2 = H5B2_create(f, dxpl_id, &bt2_cparam))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(bt2, &tree_addr) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get v2 B-tree address for SOHM index") /* Set up key values that all messages will use. Since these messages * are in the heap, they have a heap ID and no encoding or type_id. @@ -725,8 +750,8 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, key.encoding = encoding_buf; /* Insert the message into the B-tree */ - if(H5B2_insert(f, dxpl_id, H5SM_INDEX, tree_addr, &key) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") + if(H5B2_insert(bt2, dxpl_id, &key) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") /* Free buffer from H5SM_read_mesg */ if(encoding_buf) @@ -736,7 +761,7 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, /* Unprotect list in cache and release heap */ if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") *_list = list = NULL; /* Delete the old list index (but not its heap, which the new index is @@ -752,7 +777,9 @@ H5SM_convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, header->num_messages = num_messages; done: - /* Free the buffer, if it hasn't already been freed (because of error) */ + /* Release resources */ + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") if(encoding_buf) encoding_buf = H5MM_xfree(encoding_buf); @@ -801,13 +828,13 @@ H5SM_convert_btree_to_list(H5F_t * f, H5SM_index_header_t * header, hid_t dxpl_i /* Delete the B-tree and have messages copy themselves to the * list as they're deleted */ - if(H5B2_delete(f, dxpl_id, H5SM_INDEX, btree_addr, H5SM_btree_convert_to_list_op, list) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree") + if(H5B2_delete(f, dxpl_id, btree_addr, H5SM_btree_convert_to_list_op, list) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete B-tree") done: /* Release the SOHM list from the cache */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to unprotect SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to unprotect SOHM index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_convert_btree_to_list() */ @@ -912,7 +939,7 @@ H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table, /* If the message isn't big enough, don't bother sharing it */ if(0 == (mesg_size = H5O_msg_raw_size(f, type_id, TRUE, mesg))) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to get OH message size") + HGOTO_ERROR(H5E_SOHM, H5E_BADMESG, FAIL, "unable to get OH message size") if(mesg_size < my_table->indexes[index_num].min_mesg_size) HGOTO_DONE(FALSE) @@ -923,7 +950,7 @@ H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table, done: /* Release the master SOHM table, if we protected it */ if(my_table && my_table != table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, my_table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SOHM, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_can_share() */ @@ -1005,7 +1032,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id, /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* "complex" sharing checks */ if((tri_ret = H5SM_can_share(f, dxpl_id, table, &index_num, type_id, mesg)) < 0) @@ -1042,7 +1069,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id, done: /* Release the master SOHM table */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_try_share() */ @@ -1086,7 +1113,7 @@ H5SM_incr_ref(void *record, void *_op_data, hbool_t *changed) /* Put the message in the heap and record its new heap ID */ if(H5HF_insert(op_data->key->fheap, op_data->dxpl_id, op_data->key->encoding_size, op_data->key->encoding, &message->u.heap_loc.fheap_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") message->location = H5SM_IN_HEAP; message->u.heap_loc.ref_count = 2; @@ -1142,6 +1169,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t shared; /* Shared H5O message */ hbool_t found = FALSE; /* Was the message in the index? */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ size_t buf_size; /* Size of the encoded message */ void * encoding_buf = NULL; /* Buffer for encoded message */ size_t empty_pos = UFAIL; /* Empty entry in list */ @@ -1156,15 +1184,15 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Encode the message to be written */ if((buf_size = H5O_msg_raw_size(f, type_id, TRUE, mesg)) == 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADSIZE, FAIL, "can't find message size") + HGOTO_ERROR(H5E_SOHM, H5E_BADSIZE, FAIL, "can't find message size") if(NULL == (encoding_buf = H5MM_malloc(buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate buffer for encoding") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't allocate buffer for encoding") if(H5O_msg_encode(f, type_id, TRUE, (unsigned char *)encoding_buf, mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "can't encode message to be shared") + HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, FAIL, "can't encode message to be shared") /* Open the fractal heap for this index */ if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up a key for the message to be written */ key.dxpl_id = dxpl_id; @@ -1184,7 +1212,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* The index is a list; get it from the cache */ if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, NULL, header, H5AC_WRITE))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") /* See if the message is already in the index and get its location. * Also record the first empty list position we find in case we need it @@ -1198,7 +1226,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, if(list->messages[list_pos].location == H5SM_IN_OH) { /* Put the message in the heap and record its new heap ID */ if(H5HF_insert(fheap, dxpl_id, key.encoding_size, key.encoding, &shared.u.heap_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap") list->messages[list_pos].location = H5SM_IN_HEAP; list->messages[list_pos].u.heap_loc.fheap_id = shared.u.heap_id; @@ -1221,6 +1249,11 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, HDassert(header->index_type == H5SM_BTREE); + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + + /* Set up callback info */ op_data.key = &key; op_data.dxpl_id = dxpl_id; @@ -1229,10 +1262,12 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, * return a heap ID, since a message with a reference count greater * than 1 is always shared in the heap. */ - if(H5B2_modify(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_incr_ref, &op_data) >= 0) { + if(H5B2_modify(bt2, dxpl_id, &key, H5SM_incr_ref, &op_data) >= 0) { shared.u.heap_id = op_data.fheap_id; found = TRUE; } /* end if */ + else + H5E_clear_stack(NULL); /*ignore error*/ } /* end else */ if(found) @@ -1307,8 +1342,14 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, else { HDassert(header->index_type == H5SM_BTREE); - if(H5B2_insert(f, dxpl_id, H5SM_INDEX, header->index_addr, &key) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") + /* Open the index v2 B-tree, if it isn't already */ + if(NULL == bt2) { + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + } /* end if */ + + if(H5B2_insert(bt2, dxpl_id, &key) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree") } /* end else */ ++(header->num_messages); @@ -1321,16 +1362,18 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Update the original message's shared component */ if(H5O_msg_set_share(type_id, &shared, mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "unable to set sharing information") + HGOTO_ERROR(H5E_SOHM, H5E_BADMESG, FAIL, "unable to set sharing information") done: - /* Release the fractal heap if we opened it */ + /* Release the fractal heap & v2 B-tree if we opened them */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") /* If we got a list out of the cache, release it (it is always dirty after writing a message) */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") if(encoding_buf) encoding_buf = H5MM_xfree(encoding_buf); @@ -1379,7 +1422,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg) /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_WRITE))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index and try to delete from it */ if((index_num = H5SM_get_index(table, type_id)) < 0) @@ -1394,7 +1437,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg) /* Release the master SOHM table */ if(H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") table = NULL; /* If buf was allocated, delete the message it holds. This message may @@ -1403,16 +1446,16 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg) */ if(mesg_buf) { if(NULL == (native_mesg = H5O_msg_decode(f, dxpl_id, open_oh, type_id, (const unsigned char *)mesg_buf))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode shared message.") + HGOTO_ERROR(H5E_SOHM, H5E_CANTDECODE, FAIL, "can't decode shared message.") if(H5O_msg_delete(f, dxpl_id, open_oh, type_id, native_mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "can't delete shared message.") + HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "can't delete shared message.") } /* end if */ done: /* Release the master SOHM table (should only happen on error) */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, cache_flags) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") /* Release any native message we decoded */ if(native_mesg) @@ -1588,6 +1631,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5SM_sohm_t message; /* Deleted message returned from index */ H5SM_sohm_t *message_ptr; /* Pointer to deleted message returned from index */ H5HF_t *fheap = NULL; /* Fractal heap that contains the message */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ size_t buf_size; /* Size of the encoded message (out) */ void *encoding_buf = NULL; /* The encoded message (out) */ unsigned type_id; /* Message type to operate on */ @@ -1607,7 +1651,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Open the heap for this type of message. */ if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Get the message size and encoded message for the message to be deleted, * either from its OH or from the heap. @@ -1626,7 +1670,7 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Get the encoded message */ if(H5SM_read_mesg(f, &key.message, fheap, open_oh, dxpl_id, &buf_size, &encoding_buf) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up key for message to be deleted. */ key.file = f; @@ -1658,9 +1702,14 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Index is a B-tree */ HDassert(header->index_type == H5SM_BTREE); + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + /* If this returns failure, it means that the message wasn't found. - * If it succeeds, a copy of the modified message will be returned. */ - if(H5B2_modify(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_decr_ref, &message) <0) + * If it succeeds, a copy of the modified message will be returned. + */ + if(H5B2_modify(bt2, dxpl_id, &key, H5SM_decr_ref, &message) <0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") /* Point to the message */ @@ -1682,8 +1731,14 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, if(header->index_type == H5SM_LIST) message_ptr->location = H5SM_NO_LOC; else { - if(H5B2_remove(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, NULL, NULL) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTREMOVE, FAIL, "unable to delete message") + /* Open the index v2 B-tree, if it isn't already */ + if(NULL == bt2) { + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + } /* end if */ + + if(H5B2_remove(bt2, dxpl_id, &key, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTREMOVE, FAIL, "unable to delete message from index") } /* end else */ /* Remove the message from the heap if it was stored in the heap*/ @@ -1700,12 +1755,12 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, /* Unprotect cache and release heap */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release SOHM list") list = NULL; HDassert(fheap); if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") fheap = NULL; /* Delete the index and its heap */ @@ -1724,11 +1779,13 @@ H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, done: /* Release the SOHM list */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") - /* Release the fractal heap if we opened it */ + /* Release the fractal heap & v2 B-tree if we opened them */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") /* Free the message encoding, if we're not returning it in encoded_mesg * or if there's been an error. @@ -1771,7 +1828,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Check for the extension having a 'shared message info' message */ if((status = H5O_msg_exists(ext_loc, H5O_SHMESG_ID, dxpl_id)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to read object header") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "unable to read object header") if(status) { unsigned index_flags[H5O_SHMESG_MAX_NINDEXES]; /* Message flags for each index */ unsigned minsizes[H5O_SHMESG_MAX_NINDEXES]; /* Minimum message size for each index */ @@ -1781,7 +1838,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Retrieve the 'shared message info' structure */ if(NULL == H5O_msg_read(ext_loc, H5O_SHMESG_ID, &sohm_table, dxpl_id)) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "shared message info message not present") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "shared message info message not present") /* Portably initialize the arrays */ HDmemset(index_flags, 0, sizeof(index_flags)); @@ -1796,7 +1853,7 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Read the rest of the SOHM table information from the cache */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Get index conversion limits */ sohm_l2b = table->indexes[0].list_max; @@ -1821,15 +1878,15 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Set values in the property list */ if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") if(H5P_set(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, index_flags) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set type flags for indexes") if(H5P_set(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, minsizes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set type flags for indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set type flags for indexes") if(H5P_set(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &sohm_l2b) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") if(H5P_set(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &sohm_b2l) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't set SOHM cutoff in property list") } /* end if */ else { /* No SOHM info in file */ @@ -1839,13 +1896,13 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Shared object header messages are disabled */ if(H5P_set(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &shared->sohm_nindexes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") + HGOTO_ERROR(H5E_SOHM, H5E_CANTSET, FAIL, "can't set number of SOHM indexes") } /* end else */ done: /* Release the master SOHM table if we took it out of the cache */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_get_info() */ @@ -1882,7 +1939,7 @@ H5SM_message_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord) HDassert(message->location == H5SM_IN_OH); *raw++ = 0; /* reserved (possible flags byte) */ - *raw++ = message->msg_type_id; + *raw++ = (uint8_t)message->msg_type_id; UINT16ENCODE(raw, message->u.mesg_loc.index); H5F_addr_encode(f, &raw, message->u.mesg_loc.oh_addr); } /* end else */ @@ -2013,6 +2070,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *sh_mesg, hsize_t *ref_count) { H5HF_t *fheap = NULL; /* Fractal heap that contains shared messages */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ H5SM_master_table_t *table = NULL; /* SOHM master table */ H5SM_list_t *list = NULL; /* SOHM index list for message type (if in list form) */ H5SM_index_header_t *header=NULL; /* Index header for message type */ @@ -2032,7 +2090,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index and find the message in it */ if((index_num = H5SM_get_index(table, type_id)) < 0) @@ -2041,7 +2099,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Open the heap for this message type */ if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up a SOHM message to correspond to the shared message passed in */ key.message.location = H5SM_IN_HEAP; @@ -2050,7 +2108,7 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Get the encoded message */ if(H5SM_read_mesg(f, &key.message, fheap, NULL, dxpl_id, &buf_size, &encoding_buf) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Set up key for message to locate */ key.file = f; @@ -2081,8 +2139,12 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Index is a B-tree */ HDassert(header->index_type == H5SM_BTREE); + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + /* Look up the message in the v2 B-tree */ - if((msg_exists = H5B2_find(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_get_refcount_bt2_cb, &message)) < 0) + if((msg_exists = H5B2_find(bt2, dxpl_id, &key, H5SM_get_refcount_bt2_cb, &message)) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "error finding message in index") if(!msg_exists) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") @@ -2095,11 +2157,13 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, done: /* Release resources */ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") if(encoding_buf) encoding_buf = H5MM_xfree(encoding_buf); @@ -2147,7 +2211,7 @@ H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence, /* Check if the message is dirty & flush it to the object header if so */ if(mesg->dirty) if(H5O_msg_flush(udata->file, oh, mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message") + HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message") /* Get the message's encoded size */ udata->buf_size = mesg->raw_size; @@ -2155,7 +2219,7 @@ H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence, /* Allocate buffer to return the message in */ if(NULL == (udata->encoding_buf = H5MM_malloc(udata->buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") /* Copy the encoded message into the buffer to return */ HDmemcpy(udata->encoding_buf, mesg->raw, udata->buf_size); @@ -2193,7 +2257,7 @@ H5SM_read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata) /* Allocate a buffer to hold the message */ if(NULL == (udata->encoding_buf = H5MM_malloc(obj_len))) - HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "memory allocation failed") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy the message from the heap */ HDmemcpy(udata->encoding_buf, obj, obj_len); @@ -2252,18 +2316,18 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, /* Reset object location for operation */ if(H5O_loc_reset(&oloc) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize location") + HGOTO_ERROR(H5E_SOHM, H5E_CANTRESET, FAIL, "unable to initialize location") if(NULL == open_oh || mesg->u.mesg_loc.oh_addr != H5O_OH_GET_ADDR(open_oh)) { /* Open the object in the file */ oloc.file = f; oloc.addr = mesg->u.mesg_loc.oh_addr; if(H5O_open(&oloc) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to open object header") + HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "unable to open object header") /* Load the object header from the cache */ if(NULL == (oh = (H5O_t *)H5AC_protect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "unable to load object header") } /* end if */ else oh = open_oh; @@ -2272,14 +2336,14 @@ H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, op.op_type = H5O_MESG_OP_LIB; op.u.lib_op = H5SM_read_iter_op; if((ret_value = H5O_msg_iterate_real(f, oh, type, &op, &udata, dxpl_id)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages") + HGOTO_ERROR(H5E_SOHM, H5E_BADITER, FAIL, "unable to iterate over object header messages") } /* end if */ else { HDassert(mesg->location == H5SM_IN_HEAP); /* Copy the message from the heap */ if(H5HF_op(fheap, dxpl_id, &(mesg->u.heap_loc.fheap_id), H5SM_read_mesg_fh_cb, &udata) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "can't read message from fractal heap.") + HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, FAIL, "can't read message from fractal heap.") } /* end else */ HDassert(udata.encoding_buf); HDassert(udata.buf_size); @@ -2292,10 +2356,9 @@ done: /* Close the object header if we opened one and had an error */ if(oh && oh != open_oh) { if(H5AC_unprotect(oloc.file, dxpl_id, H5AC_OHDR, oloc.addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") - + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to release object header") if(H5O_close(&oloc) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object header") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "unable to close object header") } /* end if */ /* Release the encoding buffer on error */ @@ -2352,13 +2415,13 @@ H5SM_table_debug(H5F_t *f, hid_t dxpl_id, haddr_t table_addr, /* Check arguments. Version must be 0, the only version implemented so far */ if(table_vers > HDF5_SHAREDHEADER_VERSION) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown shared message table version") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "unknown shared message table version") if(num_indexes == 0 || num_indexes > H5O_SHMESG_MAX_NINDEXES) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") HDfprintf(stream, "%*sShared Message Master Table...\n", indent, ""); for(x = 0; x < num_indexes; ++x) { @@ -2386,7 +2449,7 @@ H5SM_table_debug(H5F_t *f, hid_t dxpl_id, haddr_t table_addr, done: if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_table_debug() */ @@ -2427,9 +2490,9 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr, /* Check arguments. Version must be 0, the only version implemented so far */ if(table_vers > H5SM_LIST_VERSION) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown shared message list version") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "unknown shared message list version") if(num_messages == 0 || num_messages > H5O_SHMESG_MAX_LIST_SIZE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") + HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "number of indexes must be between 1 and H5O_SHMESG_MAX_NINDEXES") /* Create a temporary header using the arguments. The cache needs this to load the list. */ HDmemset(&header, 0, sizeof(H5SM_index_header_t)); @@ -2439,7 +2502,7 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr, /* Get the list from the cache */ if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, list_addr, NULL, &header, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") HDfprintf(stream, "%*sShared Message List Index...\n", indent, ""); for(x = 0; x < num_messages; ++x) { @@ -2471,7 +2534,7 @@ H5SM_list_debug(H5F_t *f, hid_t dxpl_id, haddr_t list_addr, done: if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, list_addr, list, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_list_debug() */ @@ -2494,10 +2557,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) +H5SM_ih_size(H5F_t *f, hid_t dxpl_id, hsize_t *hdr_size, H5_ih_info_t *ih_info) { H5SM_master_table_t *table = NULL; /* SOHM master table */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2506,40 +2570,52 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) /* Sanity check */ HDassert(f); HDassert(H5F_addr_defined(f->shared->sohm_addr)); - HDassert(finfo); + HDassert(hdr_size); + HDassert(ih_info); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Get SOHM header size */ - finfo->sohm.hdr_size = (hsize_t) H5SM_TABLE_SIZE(f) + - (hsize_t)(table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); + *hdr_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); /* Loop over all the indices for shared messages */ for(u = 0; u < table->num_indexes; u++) { /* Get index storage size (for either B-tree or list) */ if(table->indexes[u].index_type == H5SM_BTREE) { - if(H5F_addr_defined(table->indexes[u].index_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5SM_INDEX, table->indexes[u].index_addr, &(finfo->sohm.msgs_info.index_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + if(H5F_addr_defined(table->indexes[u].index_addr)) { + /* Open the index v2 B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, table->indexes[u].index_addr))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") + + if(H5B2_size(bt2, dxpl_id, &(ih_info->index_size)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + + /* Close the v2 B-tree */ + if(H5B2_close(bt2, dxpl_id) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") + bt2 = NULL; + } /* end if */ } /* end if */ - else if(table->indexes[u].index_type == H5SM_LIST) - finfo->sohm.msgs_info.index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max); + else { + HDassert(table->indexes[u].index_type == H5SM_LIST); + ih_info->index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max); + } /* end else */ /* Check for heap for this index */ if(H5F_addr_defined(table->indexes[u].heap_addr)) { /* Open the fractal heap for this index */ if(NULL == (fheap = H5HF_open(f, dxpl_id, table->indexes[u].heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Get heap storage size */ - if(H5HF_size(fheap, dxpl_id, &(finfo->sohm.msgs_info.heap_size)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info") + if(H5HF_size(fheap, dxpl_id, &(ih_info->heap_size)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't retrieve fractal heap storage info") - /* Release the fractal heap */ + /* Close the fractal heap */ if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HGOTO_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") fheap = NULL; } /* end if */ } /* end for */ @@ -2547,9 +2623,11 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) + HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index") if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_ih_size() */ diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c index 3ddd3f2..2be7745 100755 --- a/src/H5SMbtree2.c +++ b/src/H5SMbtree2.c @@ -63,6 +63,7 @@ static herr_t H5SM_btree_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, /* v2 B-tree class for SOHM indexes*/ const H5B2_class_t H5SM_INDEX[1]={{ /* B-tree class information */ H5B2_SOHM_INDEX_ID, /* Type of B-tree */ + "H5B2_SOHM_INDEX_ID", /* Name of B-tree class */ sizeof(H5SM_sohm_t), /* Size of native record */ H5SM_btree_store, /* Record storage callback */ H5SM_message_compare, /* Record comparison callback */ @@ -159,7 +160,7 @@ H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence, /* Check if the message is dirty & flush it to the object header if so */ if(mesg->dirty) if(H5O_msg_flush(udata->key->file, oh, mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message") + HGOTO_ERROR(H5E_SOHM, H5E_CANTENCODE, H5_ITER_ERROR, "unable to encode object header message") HDassert(udata->key->encoding_size <= mesg->raw_size); udata->ret = HDmemcmp(udata->key->encoding, mesg->raw, udata->key->encoding_size); diff --git a/src/H5SMcache.c b/src/H5SMcache.c index e2aa732..9048b9f 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -138,7 +138,7 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 /* Allocate space for the master table in memory */ if(NULL == (table = H5FL_CALLOC(H5SM_master_table_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "memory allocation failed") /* Read number of indexes and version from file superblock */ table->num_indexes = f->shared->sohm_nindexes; @@ -179,13 +179,13 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 /* Allocate space for the index headers in memory*/ if(NULL == (table->indexes = (H5SM_index_header_t *)H5FL_ARR_MALLOC(H5SM_index_header_t, (size_t)table->num_indexes))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes") /* Read in the index headers */ for(x = 0; x < table->num_indexes; ++x) { /* Verify correct version of index list */ if(H5SM_LIST_VERSION != *p++) - HGOTO_ERROR(H5E_FILE, H5E_VERSION, NULL, "bad shared message list version number") + HGOTO_ERROR(H5E_SOHM, H5E_VERSION, NULL, "bad shared message list version number") /* Type of the index (list or B-tree) */ table->indexes[x].index_type= (H5SM_index_type_t)*p++; @@ -479,12 +479,12 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, /* Allocate space for the SOHM list data structure */ if(NULL == (list = H5FL_MALLOC(H5SM_list_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "memory allocation failed") HDmemset(&list->cache_info, 0, sizeof(H5AC_info_t)); /* Allocate list in memory as an array*/ if((list->messages = (H5SM_sohm_t *)H5FL_ARR_MALLOC(H5SM_sohm_t, header->list_max)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for SOHM list") + HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "file allocation failed for SOHM list") list->header = header; diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h index dc69b2b..093fb04 100755 --- a/src/H5SMpkg.h +++ b/src/H5SMpkg.h @@ -44,42 +44,42 @@ #define H5SM_SIZEOF_CHECKSUM 4 #define H5SM_HEAP_LOC_SIZE ( \ - 4 /* Reference count */ \ + (unsigned)4 /* Reference count */ \ + sizeof(H5O_fheap_id_t) /* size of heap ID on disk */ \ ) #define H5SM_OH_LOC_SIZE(f) ( \ - 1 /* reserved (possible flags?) */ \ - + 1 /* message type ID */ \ - + 2 /* creation index of message in OH */ \ + (unsigned)1 /* reserved (possible flags?) */ \ + + (unsigned)1 /* message type ID */ \ + + (unsigned)2 /* creation index of message in OH */ \ + H5F_SIZEOF_ADDR(f) /* address of OH */ \ ) #define H5SM_SOHM_ENTRY_SIZE(f) ( \ - 1 /* Message location */ \ - + 4 /* Hash value */ \ + (unsigned)1 /* Message location */ \ + + (unsigned)4 /* Hash value */ \ + MAX(H5SM_HEAP_LOC_SIZE, H5SM_OH_LOC_SIZE(f)) /* Entry */ \ ) #define H5SM_TABLE_SIZE(f) ( \ - H5_SIZEOF_MAGIC /* Signature */ \ - + H5SM_SIZEOF_CHECKSUM /* Checksum */ \ + (unsigned)H5_SIZEOF_MAGIC /* Signature */ \ + + (unsigned)H5SM_SIZEOF_CHECKSUM /* Checksum */ \ ) #define H5SM_INDEX_HEADER_SIZE(f) ( \ - 1 /* Whether index is a list or B-tree */ \ - + 1 /* Version of index format */ \ - + 2 /* Type of messages stored in the index */ \ - + 4 /* Minimum size of messages to share */ \ - + (3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \ + (unsigned)1 /* Whether index is a list or B-tree */ \ + + (unsigned)1 /* Version of index format */ \ + + (unsigned)2 /* Type of messages stored in the index */ \ + + (unsigned)4 /* Minimum size of messages to share */ \ + + (unsigned)(3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \ + H5F_SIZEOF_ADDR(f) /* Location of list or B-tree */ \ + H5F_SIZEOF_ADDR(f) /* Address of heap */ \ ) #define H5SM_LIST_SIZE(f, num_mesg) ( \ - H5_SIZEOF_MAGIC /* Signature */ \ + (unsigned) H5_SIZEOF_MAGIC /* Signature */ \ + (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) /* Message entries */ \ - + H5SM_SIZEOF_CHECKSUM /* Checksum */ \ + + (unsigned)H5SM_SIZEOF_CHECKSUM /* Checksum */ \ ) #define H5SM_B2_NODE_SIZE 512 diff --git a/src/H5SMprivate.h b/src/H5SMprivate.h index 1465357..46a43ad 100755 --- a/src/H5SMprivate.h +++ b/src/H5SMprivate.h @@ -56,7 +56,7 @@ H5_DLL herr_t H5SM_reconstitute(H5O_shared_t *sh_mesg, H5F_t *f, unsigned msg_type_id, H5O_fheap_id_t heap_id); H5_DLL herr_t H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *sh_mesg, hsize_t *ref_count); -H5_DLL herr_t H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *bh_info); +H5_DLL herr_t H5SM_ih_size(H5F_t *f, hid_t dxpl_id, hsize_t *hdr_size, H5_ih_info_t *ih_info); /* Debugging routines */ diff --git a/src/H5SMtest.c b/src/H5SMtest.c index 8412a89..582bc0e 100644 --- a/src/H5SMtest.c +++ b/src/H5SMtest.c @@ -95,7 +95,7 @@ H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index for this message type */ if((index_num = H5SM_get_index(table, type_id)) < 0) @@ -112,7 +112,7 @@ H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, done: /* Release resources */ if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM master table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_get_mesg_count_test() */ @@ -2976,8 +2976,8 @@ H5T_create(H5T_class_t type, size_t size) dt->shared->type = type; if(type==H5T_COMPOUND) { - dt->shared->u.compnd.packed=TRUE; /* Start out packed */ - dt->shared->u.compnd.sorted=H5T_SORT_VALUE; /* Start out sorted by value */ + dt->shared->u.compnd.packed=FALSE; /* Start out unpacked */ + dt->shared->u.compnd.memb_size=0; } /* end if */ else if(type==H5T_OPAQUE) /* Initialize the tag in case it's not set later. A null tag will @@ -3678,7 +3678,13 @@ H5T_set_size(H5T_t *dt, size_t size) if(size<(max_offset+max_size)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size shrinking will cut off last member "); + + /* Compound must not have been packed previously */ + /* We will check if resizing changed the packed state of + * this type at the end of this function */ + HDassert(!dt->shared->u.compnd.packed); } + break; case H5T_STRING: @@ -3754,6 +3760,10 @@ H5T_set_size(H5T_t *dt, size_t size) dt->shared->u.atomic.prec = prec; } } /* end if */ + + /* Check if the new compound type is packed */ + if(dt->shared->type == H5T_COMPOUND) + H5T_update_packed(dt); } done: diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index f580c15..dea6bed 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -334,6 +334,10 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id) HDassert(type); HDassert(tcpl_id != H5P_DEFAULT); + /* Check if we are allowed to write to this file */ + if(0 == (H5F_INTENT(file) & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "no write intent on file") + /* * Check arguments. We cannot commit an immutable type because H5Tclose() * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c index 02d6bd1..db7a701b 100644 --- a/src/H5Tcompound.c +++ b/src/H5Tcompound.c @@ -45,11 +45,6 @@ /******************/ /* Local Typedefs */ /******************/ -/* "Key" (+ user data) for bsearch callback */ -typedef struct{ - size_t offset; /* Offset of member to be added */ - const H5T_cmemb_t *max_under; /* Member with maximum offset seen that is not above "offset" */ -} H5T_insert_compar_t; /********************/ @@ -421,48 +416,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5T_insert_compar - * - * Purpose: Callback function for bsearch called from H5T_insert. - * Reports whether obj has a lower of higher offset than - * that stored in key. Also keeps track of the highest - * offset seen that is not higher than that in key. - * - * Return: -1 if key < obj - * 0 if key == obj - * 1 if key > obj - * - * Programmer: Neil Fortner - * Wednesday, January 7, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static int -H5T_insert_compar(const void *_key, const void *_obj) -{ - H5T_insert_compar_t *key = *(H5T_insert_compar_t * const *)_key; /* User data */ - const H5T_cmemb_t *memb = (const H5T_cmemb_t *)_obj; /* Compound member being examined */ - int ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_insert_compar) - - if(key->offset > memb->offset) { - if(key->max_under == NULL || memb->offset > key->max_under->offset) - key->max_under = memb; - ret_value = 1; - } /* end if */ - else if(key->offset < memb->offset) - ret_value = -1; - else - ret_value = 0; /* Should not happen */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_insert_compar() */ - - -/*------------------------------------------------------------------------- * Function: H5T_insert * * Purpose: Adds a new MEMBER to the compound datatype PARENT. The new @@ -482,8 +435,6 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) { unsigned idx; /* Index of member to insert */ size_t total_size; - H5T_insert_compar_t key; /* Key for bsearch compare function */ - H5T_insert_compar_t *keyptr = &key; /* Pointer to key */ unsigned i; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -500,39 +451,20 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) if(!HDstrcmp(parent->shared->u.compnd.memb[i].name, name)) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique") + /* Does the new member overlap any existing member ? */ total_size = member->shared->size; + for(i = 0; i < parent->shared->u.compnd.nmembs; i++) + if((offset <= parent->shared->u.compnd.memb[i].offset && + (offset + total_size) > parent->shared->u.compnd.memb[i].offset) || + (parent->shared->u.compnd.memb[i].offset <= offset && + (parent->shared->u.compnd.memb[i].offset + + parent->shared->u.compnd.memb[i].size) > offset)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") /* Does the new member overlap the end of the compound type? */ if((offset + total_size) > parent->shared->size) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type") - if(parent->shared->u.compnd.sorted != H5T_SORT_VALUE) - if(H5T_sort_value(parent, NULL) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOMPARE, FAIL, "value sort failed") - - /* Find the position to insert the new member */ - if(parent->shared->u.compnd.nmembs == 0) - idx = 0; - else { - /* Key value (including user data) for compar callback */ - key.offset = offset; - key.max_under = NULL; - - /* Do a binary search on the offsets of the (now sorted) members. We do - * not expect to find an exact match (if we do it is an error), rely on - * the user data in the key to keep track of the closest member below - * the new member. */ - if(NULL != HDbsearch(&keyptr, parent->shared->u.compnd.memb, parent->shared->u.compnd.nmembs, - sizeof(parent->shared->u.compnd.memb[0]), H5T_insert_compar)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") - idx = (key.max_under == NULL) ? 0 : (unsigned) (key.max_under - parent->shared->u.compnd.memb + 1); - } /* end else */ - - /* Does the new member overlap any existing member ? */ - if((idx < parent->shared->u.compnd.nmembs && (offset + total_size) > parent->shared->u.compnd.memb[idx].offset) || - (idx && (parent->shared->u.compnd.memb[idx-1].offset + parent->shared->u.compnd.memb[idx-1].size) > offset)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") - /* Increase member array if necessary */ if(parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) { unsigned na = MAX(1, parent->shared->u.compnd.nalloc * 2); @@ -544,68 +476,23 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) parent->shared->u.compnd.memb = x; } /* end if */ - /* Determine if the compound datatype stays packed */ - if(parent->shared->u.compnd.packed) { - /* Check if the member type is packed */ - if(H5T_is_packed(member) > 0) { - if(idx == 0) { - /* If the is the first member, the datatype is not packed - * if the first member isn't at offset 0 - */ - if(offset > 0) - parent->shared->u.compnd.packed = FALSE; - } /* end if */ - else { - /* If the is not the first member, the datatype is not - * packed if the new member isn't adjoining the previous member - */ - if(offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size)) - parent->shared->u.compnd.packed = FALSE; - } /* end else */ - } /* end if */ - else - parent->shared->u.compnd.packed = FALSE; - } /* end if */ - else - /* Check if inserting this member causes the parent to become packed */ - /* First check if it completely closes a gap */ - /* No need to check if it's being appended to the end */ - if(idx != parent->shared->u.compnd.nmembs - && (offset + total_size) == parent->shared->u.compnd.memb[idx].offset - && (idx == 0 ? offset == 0 : (parent->shared->u.compnd.memb[idx-1].offset - + parent->shared->u.compnd.memb[idx-1].size) == offset) - && H5T_is_packed(member) > 0) { - - /* Start out packed */ - parent->shared->u.compnd.packed = TRUE; - - /* Check if the entire type is now packed */ - if((idx != 0 && parent->shared->u.compnd.memb[0].offset != 0) - || !H5T_is_packed(parent->shared->u.compnd.memb[0].type)) - parent->shared->u.compnd.packed = FALSE; - else - for(i = 1; i < parent->shared->u.compnd.nmembs; i++) - if((i != idx && parent->shared->u.compnd.memb[i].offset - != (parent->shared->u.compnd.memb[i - 1].offset - + parent->shared->u.compnd.memb[i - 1].size)) - || !H5T_is_packed(parent->shared->u.compnd.memb[i].type)) { - parent->shared->u.compnd.packed = FALSE; - break; - } /* end if */ - } /* end if */ - - /* Reshape the memb array to accomodate the new member */ - if(idx != parent->shared->u.compnd.nmembs) - HDmemmove(&parent->shared->u.compnd.memb[idx+1], &parent->shared->u.compnd.memb[idx], - (parent->shared->u.compnd.nmembs - idx) * sizeof(parent->shared->u.compnd.memb[0])); - - /* Add member to member array */ + /* Add member to end of member array */ + idx = parent->shared->u.compnd.nmembs; parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name); parent->shared->u.compnd.memb[idx].offset = offset; parent->shared->u.compnd.memb[idx].size = total_size; parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL); + parent->shared->u.compnd.sorted = H5T_SORT_NONE; parent->shared->u.compnd.nmembs++; + parent->shared->u.compnd.memb_size+=total_size; + + /* It should not be possible to get this far if the type is already packed + * - the new member would overlap something */ + HDassert(!(parent->shared->u.compnd.packed)); + + /* Determine if the compound datatype becomes packed */ + H5T_update_packed(parent); /* Set the "force conversion" flag if the field's datatype indicates */ if(member->shared->force_conv == TRUE) @@ -730,13 +617,55 @@ H5T_is_packed(const H5T_t *dt) /* If this is a compound datatype, check if it is packed */ if(dt->shared->type == H5T_COMPOUND) { - H5T_compnd_t *compnd = &(dt->shared->u.compnd); /* Convenience pointer to compound info */ - ret_value = (htri_t)(compnd->packed && compnd->nmembs > 0 - && compnd->memb[compnd->nmembs - 1].offset - + compnd->memb[compnd->nmembs - 1].size - == dt->shared->size); + ret_value = (htri_t)(dt->shared->u.compnd.packed); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_is_packed() */ + +/*------------------------------------------------------------------------- + * Function: H5T_update_packed + * + * Purpose: Checks whether a datatype which is compound became packed + * after recent changes. This function does not assume that + * the status of the "packed" field is correct, and sets + * this field to the correct value. + * + * Return: void + * + * Programmer: Neil Fortner + * Monday, October 19, 2009 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +H5T_update_packed(const H5T_t *dt) +{ + unsigned i; /* Index */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_update_packed) + + HDassert(dt); + HDassert(dt->shared->type == H5T_COMPOUND); + + /* First check if all space is used in the "top level" type */ + if(dt->shared->size == dt->shared->u.compnd.memb_size) { + /* Set the packed flag to TRUE */ + dt->shared->u.compnd.packed = TRUE; + + /* Now check if all members are packed */ + for(i = 0; i < dt->shared->u.compnd.nmembs; i++) + if(!H5T_is_packed(dt->shared->u.compnd.memb[i].type)) { + dt->shared->u.compnd.packed = FALSE; + break; + } /* end if */ + } /* end if */ + else + dt->shared->u.compnd.packed = FALSE; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5T_update_packed() */ + diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 08e7fa1..ab9e703 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1935,51 +1935,48 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) } /* end if */ } /* end for */ - /* Check if we need a background buffer */ - if(H5T_detect_class(src, H5T_COMPOUND) == TRUE || H5T_detect_class(dst, H5T_COMPOUND) == TRUE) { - cdata->need_bkg = H5T_BKG_YES; - - if(src_nmembs < dst_nmembs) { - priv->subset_info.subset = H5T_SUBSET_SRC; - for(i = 0; i < src_nmembs; i++) { - /* If any of source members doesn't have counterpart in the same - * order or there's conversion between members, don't do the - * optimization. - */ - if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) { - priv->subset_info.subset = H5T_SUBSET_FALSE; - break; - } /* end if */ - } /* end for */ - /* Compute the size of the data to be copied for each element. It - * may be smaller than either src or dst if there is extra space at - * the end of src. - */ - if(priv->subset_info.subset == H5T_SUBSET_SRC) - priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset - + src->shared->u.compnd.memb[src_nmembs-1].size; - } else if(dst_nmembs < src_nmembs) { - priv->subset_info.subset = H5T_SUBSET_DST; - for(i = 0; i < dst_nmembs; i++) { - /* If any of source members doesn't have counterpart in the same order or - * there's conversion between members, don't do the optimization. */ - if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) { - priv->subset_info.subset = H5T_SUBSET_FALSE; - break; - } - } /* end for */ - /* Compute the size of the data to be copied for each element. It - * may be smaller than either src or dst if there is extra space at - * the end of dst. - */ - if(priv->subset_info.subset == H5T_SUBSET_DST) - priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs-1].offset - + dst->shared->u.compnd.memb[dst_nmembs-1].size; - } else /* If the numbers of source and dest members are equal and no conversion is needed, - * the case should have been handled as noop earlier in H5Dio.c. */ - ; + /* The compound conversion functions need a background buffer */ + cdata->need_bkg = H5T_BKG_YES; - } /* end if */ + if(src_nmembs < dst_nmembs) { + priv->subset_info.subset = H5T_SUBSET_SRC; + for(i = 0; i < src_nmembs; i++) { + /* If any of source members doesn't have counterpart in the same + * order or there's conversion between members, don't do the + * optimization. + */ + if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) { + priv->subset_info.subset = H5T_SUBSET_FALSE; + break; + } /* end if */ + } /* end for */ + /* Compute the size of the data to be copied for each element. It + * may be smaller than either src or dst if there is extra space at + * the end of src. + */ + if(priv->subset_info.subset == H5T_SUBSET_SRC) + priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset + + src->shared->u.compnd.memb[src_nmembs-1].size; + } else if(dst_nmembs < src_nmembs) { + priv->subset_info.subset = H5T_SUBSET_DST; + for(i = 0; i < dst_nmembs; i++) { + /* If any of source members doesn't have counterpart in the same order or + * there's conversion between members, don't do the optimization. */ + if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) { + priv->subset_info.subset = H5T_SUBSET_FALSE; + break; + } + } /* end for */ + /* Compute the size of the data to be copied for each element. It + * may be smaller than either src or dst if there is extra space at + * the end of dst. + */ + if(priv->subset_info.subset == H5T_SUBSET_DST) + priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs-1].offset + + dst->shared->u.compnd.memb[dst_nmembs-1].size; + } else /* If the numbers of source and dest members are equal and no conversion is needed, + * the case should have been handled as noop earlier in H5Dio.c. */ + ; cdata->recalc = FALSE; diff --git a/src/H5Toh.c b/src/H5Toh.c index 24fc0f1..886acc1 100644 --- a/src/H5Toh.c +++ b/src/H5Toh.c @@ -76,7 +76,8 @@ const H5O_obj_class_t H5O_OBJ_DATATYPE[1] = {{ H5O_dtype_isa, /* "isa" */ H5O_dtype_open, /* open an object of this class */ H5O_dtype_create, /* create an object of this class */ - H5O_dtype_get_oloc /* get an object header location for an object */ + H5O_dtype_get_oloc, /* get an object header location for an object */ + NULL /* get the index & heap info for an object */ }}; diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 18bf7cf..45b0e7f 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -307,6 +307,7 @@ typedef struct H5T_compnd_t { H5T_sort_t sorted; /*how are members sorted? */ hbool_t packed; /*are members packed together? */ H5T_cmemb_t *memb; /*array of struct members */ + size_t memb_size; /*total of all member sizes */ } H5T_compnd_t; /* An enumeration datatype */ @@ -1388,6 +1389,7 @@ H5_DLL herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); H5_DLL size_t H5T_get_member_size(const H5T_t *dt, unsigned membno); H5_DLL htri_t H5T_is_packed(const H5T_t *dt); +H5_DLL void H5T_update_packed(const H5T_t *dt); H5_DLL H5T_subset_info_t *H5T_conv_struct_subset(const H5T_cdata_t *cdata); /* Enumerated type functions */ @@ -284,7 +284,7 @@ H5WB_unwrap(H5WB_t *wb) } /* end if */ /* Release the buffer wrapper info */ - H5FL_FREE(H5WB_t, wb); + wb = H5FL_FREE(H5WB_t, wb); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5WB_unwrap() */ @@ -490,17 +490,103 @@ done: * of passing in the dataset's dataspace, since the chunk * dimensions are what the I/O filter will actually see * - * Modifications: + *------------------------------------------------------------------------- + */ +static herr_t +H5Z_prelude_callback(const H5O_pline_t *pline, hid_t dcpl_id, hid_t type_id, + hid_t space_id, H5Z_prelude_type_t prelude_type) +{ + H5Z_class2_t *fclass; /* Individual filter information */ + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5Z_prelude_callback) + + HDassert(pline->nused > 0); + + /* Iterate over filters */ + for(u = 0; u < pline->nused; u++) { + /* Get filter information */ + if(NULL == (fclass = H5Z_find(pline->filter[u].id))) { + /* Ignore errors from optional filters */ + if(pline->filter[u].flags & H5Z_FLAG_OPTIONAL) + H5E_clear_stack(NULL); + else + HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located") + } /* end if */ + else { + /* Make correct callback */ + switch(prelude_type) { + case H5Z_PRELUDE_CAN_APPLY: + /* Check if filter is configured to be able to encode */ + if(!fclass->encoder_present) + HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled."); + + + /* Check if there is a "can apply" callback */ + if(fclass->can_apply) { + /* Make callback to filter's "can apply" function */ + herr_t status = (fclass->can_apply)(dcpl_id, type_id, space_id); + + /* Check return value */ + if(status <= 0) { + /* Indicate filter can't apply to this combination of parameters */ + if(status == 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate") + /* Indicate error during filter callback */ + else + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback") + } /* end if */ + } /* end if */ + break; + + case H5Z_PRELUDE_SET_LOCAL: + /* Check if there is a "set local" callback */ + if(fclass->set_local) { + /* Make callback to filter's "set local" function */ + if((fclass->set_local)(dcpl_id, type_id, space_id) < 0) + /* Indicate error during filter callback */ + HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback") + } /* end if */ + break; + + default: + HDassert("invalid prelude type" && 0); + } /* end switch */ + } /* end else */ + } /* end for */ + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_prelude_callback() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_prepare_prelude_callback_dcpl + * + * Purpose: Prepares to make a dataset creation "prelude" callback + * for the "can_apply" or "set_local" routines. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, April 4, 2003 + * + * Notes: + * The chunk dimensions are used to create a dataspace, instead + * of passing in the dataset's dataspace, since the chunk + * dimensions are what the I/O filter will actually see * *------------------------------------------------------------------------- */ static herr_t -H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type) +H5Z_prepare_prelude_callback_dcpl(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type) { hid_t space_id = -1; /* ID for dataspace describing chunk */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5Z_prelude_callback) + FUNC_ENTER_NOAPI_NOINIT(H5Z_prepare_prelude_callback_dcpl) HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id)); HDassert(H5I_DATATYPE == H5I_get_type(type_id)); @@ -520,10 +606,10 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty /* Check if the dataset is chunked */ if(H5D_CHUNKED == dcpl_layout.type) { - H5O_pline_t dcpl_pline; /* Dataset's I/O pipeline information */ + H5O_pline_t dcpl_pline; /* Object's I/O pipeline information */ /* Get I/O pipeline information */ - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0) + if(H5P_get(dc_plist, H5O_CRT_PIPELINE_NAME, &dcpl_pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter") /* Check if the chunks have filters */ @@ -544,59 +630,9 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") } /* end if */ - /* Iterate over filters */ - for(u = 0; u < dcpl_pline.nused; u++) { - H5Z_class2_t *fclass; /* Individual filter information */ - - /* Get filter information */ - if(NULL == (fclass = H5Z_find(dcpl_pline.filter[u].id))) { - /* Ignore errors from optional filters */ - if(dcpl_pline.filter[u].flags & H5Z_FLAG_OPTIONAL) - H5E_clear_stack(NULL); - else - HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located") - } /* end if */ - else { - /* Make correct callback */ - switch(prelude_type) { - case H5Z_PRELUDE_CAN_APPLY: - /* Check if filter is configured to be able to encode */ - if(!fclass->encoder_present) - HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled."); - - - /* Check if there is a "can apply" callback */ - if(fclass->can_apply) { - /* Make callback to filter's "can apply" function */ - herr_t status = (fclass->can_apply)(dcpl_id, type_id, space_id); - - /* Check return value */ - if(status <= 0) { - /* Indicate filter can't apply to this combination of parameters */ - if(status == 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate") - /* Indicate error during filter callback */ - else - HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback") - } /* end if */ - } /* end if */ - break; - - case H5Z_PRELUDE_SET_LOCAL: - /* Check if there is a "set local" callback */ - if(fclass->set_local) { - /* Make callback to filter's "set local" function */ - if((fclass->set_local)(dcpl_id, type_id, space_id) < 0) - /* Indicate error during filter callback */ - HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback") - } /* end if */ - break; - - default: - HDassert("invalid prelude type" && 0); - } /* end switch */ - } /* end else */ - } /* end for */ + /* Make the callbacks */ + if(H5Z_prelude_callback(&dcpl_pline, dcpl_id, type_id, space_id, prelude_type) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter") } /* end if */ } /* end if */ } /* end if */ @@ -606,7 +642,7 @@ done: HDONE_ERROR(H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5Z_prelude_callback() */ +} /* end H5Z_prepare_prelude_callback_dcpl() */ /*------------------------------------------------------------------------- @@ -635,11 +671,8 @@ H5Z_can_apply(hid_t dcpl_id, hid_t type_id) FUNC_ENTER_NOAPI(H5Z_can_apply, FAIL) - HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id)); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); - /* Make "can apply" callbacks for filters in pipeline */ - if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY) < 0) + if(H5Z_prepare_prelude_callback_dcpl(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter") done: @@ -673,11 +706,8 @@ H5Z_set_local(hid_t dcpl_id, hid_t type_id) FUNC_ENTER_NOAPI(H5Z_set_local, FAIL) - HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id)); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); - /* Make "set local" callbacks for filters in pipeline */ - if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL) < 0) + if(H5Z_prepare_prelude_callback_dcpl(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL) < 0) HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set") done: @@ -686,6 +716,75 @@ done: /*------------------------------------------------------------------------- + * Function: H5Z_can_apply_direct + * + * Purpose: Checks if all the filters defined in the pipeline can be + * applied to an opaque byte stream (currently only a group). + * The pipeline is assumed to have at least one filter. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Tuesday, September 22, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Z_can_apply_direct(const H5O_pline_t *pline) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_can_apply_direct, FAIL) + + HDassert(pline->nused > 0); + + /* Make "can apply" callbacks for filters in pipeline */ + if(H5Z_prelude_callback(pline, -1, -1, -1, H5Z_PRELUDE_CAN_APPLY) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_can_apply_direct() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_set_local_direct + * + * Purpose: Makes callbacks to modify local settings for filters on a + * new opaque object. The pipeline is assumed to have at + * least one filter. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Tuesday, September 22, 2009 + * + * Notes: + * This callback will almost certainly not do anything + * useful, other than to make certain that the filter will + * accept opque data. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Z_set_local_direct(const H5O_pline_t *pline) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_set_local_direct, FAIL) + + HDassert(pline->nused > 0); + + /* Make "set local" callbacks for filters in pipeline */ + if(H5Z_prelude_callback(pline, -1, -1, -1, H5Z_PRELUDE_SET_LOCAL) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_set_local_direct() */ + + +/*------------------------------------------------------------------------- * Function: H5Z_modify * * Purpose: Modify filter parameters for specified pipeline. @@ -1286,33 +1385,3 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Zget_filter_info() */ - -/*------------------------------------------------------------------------- - * Function: H5Z_set_latest_version - * - * Purpose: Set the encoding for a I/O filter pipeline to the latest version. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, July 24, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Z_set_latest_version(H5O_pline_t *pline) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5Z_set_latest_version, FAIL) - - /* Sanity check */ - HDassert(pline); - - /* Set encoding of I/O pipeline to latest version */ - pline->version = H5O_PLINE_VERSION_LATEST; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5Z_set_latest_version() */ - diff --git a/src/H5Zpkg.h b/src/H5Zpkg.h index ae33def..959ec28 100644 --- a/src/H5Zpkg.h +++ b/src/H5Zpkg.h @@ -24,20 +24,6 @@ #include "H5Zprivate.h" /* Filter functions */ -/* The initial version of the format */ -#define H5O_PLINE_VERSION_1 1 - -/* This version encodes the message fields more efficiently */ -/* (Drops the reserved bytes, doesn't align the name and doesn't encode the - * filter name at all if it's a filter provided by the library) - */ -#define H5O_PLINE_VERSION_2 2 - -/* The latest version of the format. Look through the 'encode' and 'size' - * callbacks for places to change when updating this. */ -#define H5O_PLINE_VERSION_LATEST H5O_PLINE_VERSION_2 - - #ifdef H5_HAVE_FILTER_DEFLATE /* * Deflate filter diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h index 3ce0a0c..c2d6f7e 100644 --- a/src/H5Zprivate.h +++ b/src/H5Zprivate.h @@ -87,11 +87,12 @@ H5_DLL herr_t H5Z_pipeline(const struct H5O_pline_t *pline, H5_DLL H5Z_class2_t *H5Z_find(H5Z_filter_t id); H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id); H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id); +H5_DLL herr_t H5Z_can_apply_direct(const struct H5O_pline_t *pline); +H5_DLL herr_t H5Z_set_local_direct(const struct H5O_pline_t *pline); H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline, H5Z_filter_t filter); H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline); H5_DLL herr_t H5Z_delete(struct H5O_pline_t *pline, H5Z_filter_t filter); -H5_DLL herr_t H5Z_set_latest_version(struct H5O_pline_t *pline); /* Data Transform Functions */ typedef struct H5Z_data_xform_t H5Z_data_xform_t; /* Defined in H5Ztrans.c */ diff --git a/src/H5detect.c b/src/H5detect.c index d5801ef..f76f159 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -823,7 +823,7 @@ done:\n\ if(dt != NULL) {\n\ if(dt->shared != NULL)\n\ H5FL_FREE(H5T_shared_t, dt->shared);\n\ - H5FL_FREE(H5T_t, dt);\n\ + dt = H5FL_FREE(H5T_t, dt);\n\ } /* end if */\n\ } /* end if */\n\ \n\ diff --git a/src/H5private.h b/src/H5private.h index 2c4576f..65800fc 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -460,6 +460,11 @@ typedef enum { H5_COPY_DEEP /* Deep copy from source to destination, including duplicating fields pointed to */ } H5_copy_depth_t; +/* Common object copying udata (right now only used for groups and datasets) */ +typedef struct H5O_copy_file_ud_common_t { + struct H5O_pline_t *src_pline; /* Copy of filter pipeline for object */ +} H5O_copy_file_ud_common_t; + /* Unique object "position" */ typedef struct { unsigned long fileno; /* The unique identifier for the file of the object */ @@ -1743,10 +1748,14 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); #define FUNC_ENTER_COMMON_NOFUNC(func_name,asrt) #endif /* NDEBUG */ -#define FUNC_ENTER_COMMON(func_name,asrt) \ - static const char FUNC[]=#func_name; \ +#define FUNC_ENTER_COMMON(func_name, asrt) \ + static const char FUNC[] = #func_name; \ hbool_t err_occurred = FALSE; \ - FUNC_ENTER_COMMON_NOFUNC(func_name,asrt); + FUNC_ENTER_COMMON_NOFUNC(func_name, asrt); + +#define FUNC_ENTER_COMMON_NOERR(func_name, asrt) \ + static const char FUNC[] = #func_name; \ + FUNC_ENTER_COMMON_NOFUNC(func_name, asrt); /* Threadsafety initialization code for API routines */ #define FUNC_ENTER_API_THREADSAFE \ @@ -1757,22 +1766,37 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); H5_API_UNSET_CANCEL \ H5_API_LOCK -/* Threadsafety termination code for API routines */ -#define FUNC_LEAVE_API_THREADSAFE \ - H5_API_UNLOCK \ - H5_API_SET_CANCEL - /* Local variables for API routines */ #define FUNC_ENTER_API_VARS(func_name) \ MPE_LOG_VARS(func_name) \ H5TRACE_DECL +#define FUNC_ENTER_API_COMMON(func_name) \ + FUNC_ENTER_API_VARS(func_name) \ + FUNC_ENTER_COMMON(func_name, H5_IS_API(#func_name)); \ + FUNC_ENTER_API_THREADSAFE; + +#define FUNC_ENTER_API_INIT(func_name,err) \ + /* Initialize the library */ \ + if(!(H5_INIT_GLOBAL)) { \ + H5_INIT_GLOBAL = TRUE; \ + if(H5_init_library() < 0) \ + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, err, \ + "library initialization failed") \ + } \ + \ + /* Initialize the interface, if appropriate */ \ + H5_INTERFACE_INIT(err) \ + \ + /* Push the name of this function on the function stack */ \ + H5_PUSH_FUNC(#func_name) \ + \ + BEGIN_MPE_LOG(func_name) + /* Use this macro for all "normal" API functions */ #define FUNC_ENTER_API(func_name,err) {{ \ - FUNC_ENTER_API_VARS(func_name) \ - FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \ - FUNC_ENTER_API_THREADSAFE; \ - FUNC_ENTER_API_COMMON(func_name,err); \ + FUNC_ENTER_API_COMMON(func_name) \ + FUNC_ENTER_API_INIT(func_name,err); \ /* Clear thread error stack entering public functions */ \ H5E_clear_stack(NULL); \ { @@ -1782,10 +1806,8 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); * like H5Eprint and H5Ewalk. */ #define FUNC_ENTER_API_NOCLEAR(func_name,err) {{ \ - FUNC_ENTER_API_VARS(func_name) \ - FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \ - FUNC_ENTER_API_THREADSAFE; \ - FUNC_ENTER_API_COMMON(func_name,err); \ + FUNC_ENTER_API_COMMON(func_name) \ + FUNC_ENTER_API_INIT(func_name,err); \ { /* @@ -1795,9 +1817,7 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); * */ #define FUNC_ENTER_API_NOINIT(func_name) {{ \ - FUNC_ENTER_API_VARS(func_name) \ - FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \ - FUNC_ENTER_API_THREADSAFE; \ + FUNC_ENTER_API_COMMON(func_name) \ H5_PUSH_FUNC(#func_name) \ BEGIN_MPE_LOG(func_name); \ { @@ -1809,16 +1829,30 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); * are: H5close, H5check_version, etc. * */ -#define FUNC_ENTER_API_NOINIT_NOFS(func_name) {{ \ +#define FUNC_ENTER_API_NOINIT_NOERR_NOFS(func_name) {{ \ FUNC_ENTER_API_VARS(func_name) \ - FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \ - FUNC_ENTER_API_THREADSAFE; \ + FUNC_ENTER_COMMON_NOERR(func_name, H5_IS_API(#func_name)); \ + FUNC_ENTER_API_THREADSAFE; \ BEGIN_MPE_LOG(func_name); \ { +/* Note: this macro only works when there's _no_ interface initialization routine for the module */ +#define FUNC_ENTER_NOAPI_INIT(func_name,err) \ + /* Initialize the interface, if appropriate */ \ + H5_INTERFACE_INIT(err) \ + \ + /* Push the name of this function on the function stack */ \ + H5_PUSH_FUNC(#func_name) + /* Use this macro for all "normal" non-API functions */ #define FUNC_ENTER_NOAPI(func_name,err) { \ - FUNC_ENTER_COMMON(func_name,!H5_IS_API(#func_name)); \ + FUNC_ENTER_COMMON(func_name, !H5_IS_API(#func_name)); \ + FUNC_ENTER_NOAPI_INIT(func_name,err) \ + { + +/* Use this macro for all non-API functions, which propagate errors, but don't issue them */ +#define FUNC_ENTER_NOAPI_NOERR(func_name,err) { \ + FUNC_ENTER_COMMON_NOERR(func_name, !H5_IS_API(#func_name)); \ FUNC_ENTER_NOAPI_INIT(func_name,err) \ { @@ -1836,8 +1870,22 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); * - functions which are called during library shutdown, since we don't * want to re-initialize the library. */ -#define FUNC_ENTER_NOAPI_NOINIT(func_name) { \ - FUNC_ENTER_COMMON(func_name,!H5_IS_API(#func_name)); \ +#define FUNC_ENTER_NOAPI_NOINIT(func_name) { \ + FUNC_ENTER_COMMON(func_name, !H5_IS_API(#func_name)); \ + H5_PUSH_FUNC(#func_name) \ + { + +/* + * Use this macro for non-API functions which fall into these categories: + * - static functions, since they must be called from a function in the + * interface, the library and interface must already be + * initialized. + * - functions which are called during library shutdown, since we don't + * want to re-initialize the library. + * - functions that propagate, but don't issue errors + */ +#define FUNC_ENTER_NOAPI_NOINIT_NOERR(func_name) { \ + FUNC_ENTER_COMMON_NOERR(func_name, !H5_IS_API(#func_name)); \ H5_PUSH_FUNC(#func_name) \ { @@ -1871,31 +1919,6 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); FUNC_ENTER_COMMON_NOFUNC(func_name,!H5_IS_API(#func_name)); \ { -#define FUNC_ENTER_API_COMMON(func_name,err) \ - /* Initialize the library */ \ - if (!(H5_INIT_GLOBAL)) { \ - H5_INIT_GLOBAL = TRUE; \ - if (H5_init_library()<0) \ - HGOTO_ERROR (H5E_FUNC, H5E_CANTINIT, err, \ - "library initialization failed") \ - } \ - \ - /* Initialize the interface, if appropriate */ \ - H5_INTERFACE_INIT(err) \ - \ - /* Push the name of this function on the function stack */ \ - H5_PUSH_FUNC(#func_name) \ - \ - BEGIN_MPE_LOG(func_name) - -/* Note: this macro only works when there's _no_ interface initialization routine for the module */ -#define FUNC_ENTER_NOAPI_INIT(func_name,err) \ - /* Initialize the interface, if appropriate */ \ - H5_INTERFACE_INIT(err) \ - \ - /* Push the name of this function on the function stack */ \ - H5_PUSH_FUNC(#func_name) - /*------------------------------------------------------------------------- * Purpose: Register function exit for code profiling. This should be * the last statement executed by a function. @@ -1912,6 +1935,11 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); * *------------------------------------------------------------------------- */ +/* Threadsafety termination code for API routines */ +#define FUNC_LEAVE_API_THREADSAFE \ + H5_API_UNLOCK \ + H5_API_SET_CANCEL + #define FUNC_LEAVE_API(ret_value) \ FINISH_MPE_LOG; \ H5TRACE_RETURN(ret_value); \ @@ -1919,28 +1947,26 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); if(err_occurred) \ (void)H5E_dump_api_stack(TRUE); \ FUNC_LEAVE_API_THREADSAFE \ - return (ret_value); \ + return(ret_value); \ } /*end scope from end of FUNC_ENTER*/ \ }} /*end scope from beginning of FUNC_ENTER*/ #define FUNC_LEAVE_API_NOFS(ret_value) \ FINISH_MPE_LOG; \ H5TRACE_RETURN(ret_value); \ - if(err_occurred) \ - (void)H5E_dump_api_stack(TRUE); \ FUNC_LEAVE_API_THREADSAFE \ - return (ret_value); \ + return(ret_value); \ } /*end scope from end of FUNC_ENTER*/ \ }} /*end scope from beginning of FUNC_ENTER*/ #define FUNC_LEAVE_NOAPI(ret_value) \ - H5_POP_FUNC \ - return (ret_value); \ + H5_POP_FUNC \ + return(ret_value); \ } /*end scope from end of FUNC_ENTER*/ \ } /*end scope from beginning of FUNC_ENTER*/ #define FUNC_LEAVE_NOAPI_VOID \ - H5_POP_FUNC \ + H5_POP_FUNC \ return; \ } /*end scope from end of FUNC_ENTER*/ \ } /*end scope from beginning of FUNC_ENTER*/ @@ -1951,7 +1977,7 @@ static herr_t H5_INTERFACE_INIT_FUNC(void); * (so far, just the H5CS routines themselves) */ #define FUNC_LEAVE_NOAPI_NOFS(ret_value) \ - return (ret_value); \ + return(ret_value); \ } /*end scope from end of FUNC_ENTER*/ \ } /*end scope from beginning of FUNC_ENTER*/ diff --git a/src/H5public.h b/src/H5public.h index 2808b01..9422968 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 47 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 51 /* 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.47-FA_a4" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.51-FA_a4" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5trace.c b/src/H5trace.c index 5f1e128..b554b80 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -658,6 +658,81 @@ H5_trace (const double *returning, const char *func, const char *type, ...) } break; + case 'f': + if(ptr) { + if(vp) + fprintf(out, "0x%lx", (unsigned long)vp); + else + fprintf(out, "NULL"); + } /* end if */ + else { + H5F_file_space_type_t fs_type = va_arg(ap, H5F_file_space_type_t); /*lint !e64 Type mismatch not really occuring */ + + switch(fs_type) { + case H5F_FILE_SPACE_DEFAULT: + fprintf(out, "H5F_FILE_SPACE_DEFAULT"); + break; + case H5F_FILE_SPACE_ALL_PERSIST: + fprintf(out, "H5F_FILE_SPACE_ALL_PERSIST"); + break; + case H5F_FILE_SPACE_ALL: + fprintf(out, "H5F_FILE_SPACE_ALL"); + break; + case H5F_FILE_SPACE_AGGR_VFD: + fprintf(out, "H5F_FILE_SPACE_AGGR_VFD"); + break; + case H5F_FILE_SPACE_VFD: + fprintf(out, "H5F_FILE_SPACE_VFD"); + break; + default: + fprintf(out, "%ld", (long)fs_type); + break; + } /* end switch */ + } /* end else */ + break; + + case 'm': + if(ptr) { + if(vp) + fprintf(out, "0x%lx", (unsigned long)vp); + else + fprintf(out, "NULL"); + } /* end if */ + else { + H5F_mem_t mem_type = va_arg(ap, H5F_mem_t); /*lint !e64 Type mismatch not really occuring */ + + switch(mem_type) { + case H5FD_MEM_NOLIST: + fprintf(out, "H5FD_MEM_NOLIST"); + break; + case H5FD_MEM_DEFAULT: + fprintf(out, "H5FD_MEM_DEFAULT"); + break; + case H5FD_MEM_SUPER: + fprintf(out, "H5FD_MEM_SUPER"); + break; + case H5FD_MEM_BTREE: + fprintf(out, "H5FD_MEM_BTREE"); + break; + case H5FD_MEM_DRAW: + fprintf(out, "H5FD_MEM_DRAW"); + break; + case H5FD_MEM_GHEAP: + fprintf(out, "H5FD_MEM_GHEAP"); + break; + case H5FD_MEM_LHEAP: + fprintf(out, "H5FD_MEM_LHEAP"); + break; + case H5FD_MEM_OHDR: + fprintf(out, "H5FD_MEM_OHDR"); + break; + default: + fprintf(out, "%ld", (long)mem_type); + break; + } /* end switch */ + } /* end else */ + break; + case 's': if(ptr) { if(vp) @@ -1379,7 +1454,7 @@ H5_trace (const double *returning, const char *func, const char *type, ...) /* This may generate recursive call to the library... -QAK */ if(NULL != (pclass = (H5P_genclass_t *)H5I_object(pclass_id)) && (class_name = H5P_get_class_name(pclass))!=NULL) { - fprintf (out, class_name); + fprintf(out, "%s", class_name); H5MM_xfree(class_name); } /* end if */ else { diff --git a/src/H5vers.txt b/src/H5vers.txt index 18a88d9..89f7bc6 100644 --- a/src/H5vers.txt +++ b/src/H5vers.txt @@ -55,6 +55,7 @@ FUNCTION: H5Eprint; ; v10, v18 FUNCTION: H5Epush; ; v14, v18 FUNCTION: H5Eset_auto; ; v10, v18 FUNCTION: H5Ewalk; H5E_walk, H5E_error; v10, v18 +FUNCTION: H5Fget_info; H5F_info; v18, v110 FUNCTION: H5Gcreate; ; v10, v18 FUNCTION: H5Gopen; ; v10, v18 FUNCTION: H5Pget_filter; ; v10, v18 diff --git a/src/H5version.h b/src/H5version.h index 58de2ab..296768e 100644 --- a/src/H5version.h +++ b/src/H5version.h @@ -21,9 +21,9 @@ #define _H5version_H /* Issue error if contradicting macros have been defined. */ -#if defined(H5_USE_16_API) && defined(H5_NO_DEPRECATED_SYMBOLS) +#if (defined(H5_USE_16_API) || defined(H5_USE_18_API)) && defined(H5_NO_DEPRECATED_SYMBOLS) #error "Can't choose old API versions when deprecated APIs are disabled" -#endif /* defined(H5_USE_16_API) && defined(H5_NO_DEPRECATED_SYMBOLS) */ +#endif /* (defined(H5_USE_16_API) || defined(H5_USE_18_API)) && defined(H5_NO_DEPRECATED_SYMBOLS) */ /* If a particular "global" version of the library's interfaces is chosen, @@ -36,6 +36,11 @@ #define H5_USE_16_API 1 #endif /* H5_USE_16_API_DEFAULT && !H5_USE_16_API */ +#if defined(H5_USE_18_API_DEFAULT) && !defined(H5_USE_18_API) +#define H5_USE_18_API 1 +#endif /* H5_USE_18_API_DEFAULT && !H5_USE_18_API */ + + #ifdef H5_USE_16_API /*************/ @@ -140,6 +145,114 @@ #endif /* H5_USE_16_API */ +#ifdef H5_USE_18_API + +/*************/ +/* Functions */ +/*************/ + +#if !defined(H5Acreate_vers) +#define H5Acreate_vers 2 +#endif /* !defined(H5Acreate_vers) */ + +#if !defined(H5Aiterate_vers) +#define H5Aiterate_vers 2 +#endif /* !defined(H5Aiterate_vers) */ + +#if !defined(H5Dcreate_vers) +#define H5Dcreate_vers 2 +#endif /* !defined(H5Dcreate_vers) */ + +#if !defined(H5Dopen_vers) +#define H5Dopen_vers 2 +#endif /* !defined(H5Dopen_vers) */ + +#if !defined(H5Eclear_vers) +#define H5Eclear_vers 2 +#endif /* !defined(H5Eclear_vers) */ + +#if !defined(H5Eget_auto_vers) +#define H5Eget_auto_vers 2 +#endif /* !defined(H5Eget_auto_vers) */ + +#if !defined(H5Eprint_vers) +#define H5Eprint_vers 2 +#endif /* !defined(H5Eprint_vers) */ + +#if !defined(H5Epush_vers) +#define H5Epush_vers 2 +#endif /* !defined(H5Epush_vers) */ + +#if !defined(H5Eset_auto_vers) +#define H5Eset_auto_vers 2 +#endif /* !defined(H5Eset_auto_vers) */ + +#if !defined(H5Ewalk_vers) +#define H5Ewalk_vers 2 +#endif /* !defined(H5Ewalk_vers) */ + +#if !defined(H5Fget_info_vers) +#define H5Fget_info_vers 1 +#endif /* !defined(H5Fget_info_vers) */ + +#if !defined(H5Gcreate_vers) +#define H5Gcreate_vers 2 +#endif /* !defined(H5Gcreate_vers) */ + +#if !defined(H5Gopen_vers) +#define H5Gopen_vers 2 +#endif /* !defined(H5Gopen_vers) */ + +#if !defined(H5Pget_filter_vers) +#define H5Pget_filter_vers 2 +#endif /* !defined(H5Pget_filter_vers) */ + +#if !defined(H5Pget_filter_by_id_vers) +#define H5Pget_filter_by_id_vers 2 +#endif /* !defined(H5Pget_filter_by_id_vers) */ + +#if !defined(H5Pinsert_vers) +#define H5Pinsert_vers 2 +#endif /* !defined(H5Pinsert_vers) */ + +#if !defined(H5Pregister_vers) +#define H5Pregister_vers 2 +#endif /* !defined(H5Pregister_vers) */ + +#if !defined(H5Rget_obj_type_vers) +#define H5Rget_obj_type_vers 2 +#endif /* !defined(H5Rget_obj_type_vers) */ + +#if !defined(H5Tarray_create_vers) +#define H5Tarray_create_vers 2 +#endif /* !defined(H5Tarray_create_vers) */ + +#if !defined(H5Tcommit_vers) +#define H5Tcommit_vers 2 +#endif /* !defined(H5Tcommit_vers) */ + +#if !defined(H5Tget_array_dims_vers) +#define H5Tget_array_dims_vers 2 +#endif /* !defined(H5Tget_array_dims_vers) */ + +#if !defined(H5Topen_vers) +#define H5Topen_vers 2 +#endif /* !defined(H5Topen_vers) */ + +/************/ +/* Typedefs */ +/************/ + +#if !defined(H5E_auto_t_vers) +#define H5E_auto_t_vers 2 +#endif /* !defined(H5E_auto_t_vers) */ + +#if !defined(H5Z_class_t_vers) +#define H5Z_class_t_vers 2 +#endif /* !defined(H5Z_class_t_vers) */ + +#endif /* H5_USE_18_API */ + /* Choose the correct version of each API symbol, defaulting to the latest * version of each. The "best" name for API parameters/data structures @@ -267,6 +380,19 @@ #error "H5Ewalk_vers set to invalid value" #endif /* H5Ewalk_vers */ +#if !defined(H5Fget_info_vers) || H5Fget_info_vers == 2 +#ifndef H5Fget_info_vers +#define H5Fget_info_vers 2 +#endif /* H5Fget_info_vers */ +#define H5Fget_info H5Fget_info2 +#define H5F_info_t H5F_info2_t +#elif H5Fget_info_vers == 1 +#define H5Fget_info H5Fget_info1 +#define H5F_info_t H5F_info1_t +#else /* H5Fget_info_vers */ +#error "H5Fget_info_vers set to invalid value" +#endif /* H5Fget_info_vers */ + #if !defined(H5Gcreate_vers) || H5Gcreate_vers == 2 #ifndef H5Gcreate_vers #define H5Gcreate_vers 2 diff --git a/src/Makefile.am b/src/Makefile.am index ce84332..58902fa 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,13 +27,13 @@ include $(top_srcdir)/config/lt_vers.am # 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 -H5detect_CFLAGS = -g +H5detect_CFLAGS = -g $(AM_CFLAGS) # Our main target, the HDF5 library lib_LTLIBRARIES=libhdf5.la # Add libtool numbers to the HDF5 library (from config/lt_vers.am) -libhdf5_la_LDFLAGS= -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE) +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 @@ -44,7 +44,7 @@ DISTCLEANFILES=H5pubconf.h libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \ H5AC.c H5B.c H5Bcache.c H5Bdbg.c \ - H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \ + H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c \ H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \ @@ -53,7 +53,8 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ + H5F.c H5Faccum.c H5Fdbg.c H5Fdeprec.c H5Ffake.c H5Fio.c H5Fmount.c \ + H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAstat.c H5FAtest.c \ @@ -77,7 +78,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \ H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c \ H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \ - H5Ofill.c H5Oginfo.c \ + H5Ofill.c H5Ofsinfo.c H5Oginfo.c \ H5Olayout.c \ H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \ @@ -130,7 +131,7 @@ settings_DATA=libhdf5.settings H5Tinit.c: H5detect$(EXEEXT) LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) | \ sed -e 's/-L/:/g' -e 's/ //g'`" \ - $(RUNSERIAL) ./H5detect > H5Tinit.c || \ + $(RUNSERIAL) ./H5detect$(EXEEXT) > H5Tinit.c || \ (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ ($(RM) $@ ; exit 1) diff --git a/src/Makefile.in b/src/Makefile.in index 341baee..f56cab5 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -98,38 +98,39 @@ libhdf5_la_LIBADD = am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5timer.lo H5trace.lo H5A.lo H5Abtree2.lo H5Adense.lo \ H5Adeprec.lo H5Aint.lo H5Atest.lo H5AC.lo H5B.lo H5Bcache.lo \ - H5Bdbg.lo H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2int.lo \ - H5B2stat.lo H5B2test.lo H5C.lo H5CS.lo H5D.lo H5Dbtree.lo \ - H5Dchunk.lo H5Dcompact.lo H5Dcontig.lo H5Ddbg.lo H5Ddeprec.lo \ - H5Dearray.lo H5Defl.lo H5Dfarray.lo H5Dfill.lo H5Dint.lo \ - H5Dio.lo H5Dlayout.lo H5Dmpio.lo H5Doh.lo H5Dproxy.lo \ - H5Dscatgath.lo H5Dselect.lo H5Dtest.lo H5E.lo H5Edeprec.lo \ - H5Eint.lo H5EA.lo H5EAcache.lo H5EAdbg.lo H5EAdblkpage.lo \ - H5EAdblock.lo H5EAhdr.lo H5EAiblock.lo H5EAint.lo \ - H5EAsblock.lo H5EAstat.lo H5EAtest.lo H5F.lo H5Faccum.lo \ - H5Fdbg.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ - H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo \ - H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo \ - H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5FD.lo \ - H5FDcore.lo H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo \ - H5FDmpi.lo H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo \ - H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo \ - H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \ - H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ - H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ - H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.lo H5Gstab.lo \ - H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \ - H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ - H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \ - H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \ - H5HGcache.lo H5HGdbg.lo H5HL.lo H5HLcache.lo H5HLdbg.lo \ - H5HP.lo H5I.lo H5L.lo H5Lexternal.lo H5MF.lo H5MFaggr.lo \ - H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ - H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \ - H5Obtreek.lo H5Ocache.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo \ - H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \ - H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo \ - H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ + H5Bdbg.lo H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2hdr.lo \ + H5B2int.lo H5B2stat.lo H5B2test.lo H5C.lo H5CS.lo H5D.lo \ + H5Dbtree.lo H5Dchunk.lo H5Dcompact.lo H5Dcontig.lo H5Ddbg.lo \ + H5Ddeprec.lo H5Dearray.lo H5Defl.lo H5Dfarray.lo H5Dfill.lo \ + H5Dint.lo H5Dio.lo H5Dlayout.lo H5Dmpio.lo H5Doh.lo \ + H5Dproxy.lo H5Dscatgath.lo H5Dselect.lo H5Dtest.lo H5E.lo \ + H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo H5EAdbg.lo \ + H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo H5EAiblock.lo \ + H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo H5F.lo \ + H5Faccum.lo H5Fdbg.lo H5Fdeprec.lo H5Ffake.lo H5Fio.lo \ + H5Fmount.lo H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.lo \ + H5Fsuper_cache.lo H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo \ + H5FAdblock.lo H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo \ + H5FAtest.lo H5FD.lo H5FDcore.lo H5FDdirect.lo H5FDfamily.lo \ + H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo H5FDmpiposix.lo \ + H5FDmulti.lo H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo \ + H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo H5FSsection.lo \ + H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo H5Gcache.lo \ + H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo H5Gint.lo \ + H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo \ + H5Groot.lo H5Gstab.lo H5Gtest.lo H5Gtraverse.lo H5HF.lo \ + H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \ + H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo H5HFiblock.lo H5HFiter.lo \ + H5HFman.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \ + H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HL.lo \ + H5HLcache.lo H5HLdbg.lo H5HP.lo H5I.lo H5L.lo H5Lexternal.lo \ + H5MF.lo H5MFaggr.lo H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo \ + H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ + H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ + H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo \ + H5Oefl.lo H5Ofill.lo H5Ofsinfo.lo H5Oginfo.lo H5Olayout.lo \ + H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo H5Oname.lo \ + H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ H5Oshared.lo H5Oshmesg.lo H5Ostab.lo H5Ostorage.lo H5Otest.lo \ H5Ounknown.lo H5P.lo H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo \ H5Pdeprec.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo \ @@ -182,6 +183,16 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = /home1/packages/automake/automake-1.9.6/bin/aclocal-1.9 -I /afs/ncsa/projects/hdf/packages/libtool_1.5.14/Linux_2.4/share/aclocal ADD_PARALLEL_FILES = @ADD_PARALLEL_FILES@ AMTAR = @AMTAR@ + +# H5_CFLAGS holds flags that should be used when building hdf5, +# but which should not be exported to h5cc for building other programs. +# AM_CFLAGS is an automake construct which should be used by Makefiles +# instead of CFLAGS, as CFLAGS is reserved solely for the user to define. +AM_CFLAGS = @AM_CFLAGS@ @H5_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ @H5_CPPFLAGS@ +AM_CXXFLAGS = @AM_CXXFLAGS@ @H5_CXXFLAGS@ +AM_FCFLAGS = @AM_FCFLAGS@ @H5_FCFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ AR = @AR@ @@ -195,21 +206,18 @@ BYTESEX = @BYTESEX@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CC_VERSION = @CC_VERSION@ - -# H5_CFLAGS holds flags that should be used as CFLAGS when building hdf5, -# but which shouldn't be exported to h5cc for building other programs. -CFLAGS = @CFLAGS@ @H5_CFLAGS@ +CFLAGS = @CFLAGS@ CLEARFILEBUF = @CLEARFILEBUF@ CODESTACK = @CODESTACK@ CONFIG_DATE = @CONFIG_DATE@ CONFIG_MODE = @CONFIG_MODE@ CONFIG_USER = @CONFIG_USER@ CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ @H5_CPPFLAGS@ +CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ @H5_CXXFLAGS@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_PKG = @DEBUG_PKG@ DEFAULT_API_VERSION = @DEFAULT_API_VERSION@ @@ -232,7 +240,7 @@ F9XMODEXT = @F9XMODEXT@ F9XMODFLAG = @F9XMODFLAG@ F9XSUFFIXFLAG = @F9XSUFFIXFLAG@ FC = @FC@ -FCFLAGS = @FCFLAGS@ @H5_FCFLAGS@ +FCFLAGS = @FCFLAGS@ FCFLAGS_f90 = @FCFLAGS_f90@ FCLIBS = @FCLIBS@ FGREP = @FGREP@ @@ -433,15 +441,15 @@ 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 = 37 +LT_VERS_REVISION = 41 LT_VERS_AGE = 0 -H5detect_CFLAGS = -g +H5detect_CFLAGS = -g $(AM_CFLAGS) # Our main target, the HDF5 library lib_LTLIBRARIES = libhdf5.la # Add libtool numbers to the HDF5 library (from config/lt_vers.am) -libhdf5_la_LDFLAGS = -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE) +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 @@ -452,7 +460,7 @@ DISTCLEANFILES = H5pubconf.h libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \ H5AC.c H5B.c H5Bcache.c H5Bdbg.c \ - H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \ + H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c \ H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \ @@ -461,7 +469,8 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ + H5F.c H5Faccum.c H5Fdbg.c H5Fdeprec.c H5Ffake.c H5Fio.c H5Fmount.c \ + H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAstat.c H5FAtest.c \ @@ -485,7 +494,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \ H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c \ H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \ - H5Ofill.c H5Oginfo.c \ + H5Ofill.c H5Ofsinfo.c H5Oginfo.c \ H5Olayout.c \ H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \ @@ -664,6 +673,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2dbg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2hdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2int.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2stat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5B2test.Plo@am__quote@ @@ -737,6 +747,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FStest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Faccum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdeprec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ffake.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@ @@ -812,6 +823,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Odtype.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oefl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ofill.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ofsinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oginfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Olayout.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Olinfo.Plo@am__quote@ @@ -1230,7 +1242,7 @@ help: H5Tinit.c: H5detect$(EXEEXT) LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) | \ sed -e 's/-L/:/g' -e 's/ //g'`" \ - $(RUNSERIAL) ./H5detect > H5Tinit.c || \ + $(RUNSERIAL) ./H5detect$(EXEEXT) > H5Tinit.c || \ (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ ($(RM) $@ ; exit 1) diff --git a/src/libhdf5.settings.in b/src/libhdf5.settings.in index 51406de..a3032e5 100644 --- a/src/libhdf5.settings.in +++ b/src/libhdf5.settings.in @@ -17,15 +17,21 @@ Compiling Options: ------------------ Compilation Mode: @CONFIG_MODE@ C Compiler: @CC_VERSION@ - CFLAGS/H5_CFLAGS: @CFLAGS@/@H5_CFLAGS@ - CPPFLAGS/H5_CPPFLAGS: @CPPFLAGS@/@H5_CPPFLAGS@ + CFLAGS: @CFLAGS@ + H5_CFLAGS: @H5_CFLAGS@ + AM_CFLAGS: @AM_CFLAGS@ + CPPFLAGS: @CPPFLAGS@ + H5_CPPFLAGS: @H5_CPPFLAGS@ + AM_CPPFLAGS: @AM_CPPFLAGS@ Shared Libraries: @enable_shared@ Static Libraries: @enable_static@ Statically Linked Executables: @STATIC_EXEC@ - Extra libraries: @LDFLAGS@ @LIBS@ - Archiver: @AR@ - Ranlib: @RANLIB@ - Debugged Packages: @DEBUG_PKG@ + LDFLAGS: @LDFLAGS@ + AM_LDFLAGS: @AM_LDFLAGS@ + Extra libraries: @LIBS@ + Archiver: @AR@ + Ranlib: @RANLIB@ + Debugged Packages: @DEBUG_PKG@ API Tracing: @TRACE_API@ Languages: @@ -33,9 +39,13 @@ Languages: Fortran: @HDF_FORTRAN@ @BUILD_FORTRAN_CONDITIONAL_TRUE@ Fortran Compiler: @FC@ @BUILD_FORTRAN_CONDITIONAL_TRUE@ Fortran Flags: @FCFLAGS@ +@BUILD_FORTRAN_CONDITIONAL_TRUE@ H5 Fortran Flags: @H5_FCFLAGS@ +@BUILD_FORTRAN_CONDITIONAL_TRUE@ AM Fortran Flags: @AM_FCFLAGS@ C++: @HDF_CXX@ @BUILD_CXX_CONDITIONAL_TRUE@ C++ Compiler: @CXX@ @BUILD_CXX_CONDITIONAL_TRUE@ C++ Flags: @CXXFLAGS@ +@BUILD_CXX_CONDITIONAL_TRUE@ H5 C++ Flags: @H5_CXXFLAGS@ +@BUILD_CXX_CONDITIONAL_TRUE@ AM C++ Flags: @AM_CXXFLAGS@ Features: --------- |