diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2009-10-29 14:54:08 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2009-10-29 14:54:08 (GMT) |
commit | ac0778592ae832ccd2b3ec4a6ed62d5340d8ea2a (patch) | |
tree | 54c6ad6ea49eb560abfa7cdd3e105426b184bf4b | |
parent | 7abd8c4d3003d56f6564a79dd0eaa4d97604a769 (diff) | |
download | hdf5-ac0778592ae832ccd2b3ec4a6ed62d5340d8ea2a.zip hdf5-ac0778592ae832ccd2b3ec4a6ed62d5340d8ea2a.tar.gz hdf5-ac0778592ae832ccd2b3ec4a6ed62d5340d8ea2a.tar.bz2 |
[svn-r17786] Description:
Bring r17749 & 17785 from trunk to 1.8 branch:
17749:
Refactor v2 B-tree code to bring it further in line with how the fractal
heap code works, to make forthcoming modificaions easier. Also minor tweaks to
the fractal heap code to clean it up a bit more also.
17785:
Further refactor v2 B-tree code to bring it closer to modern data
structure designed in the library, mainly by introducing a H5B2_t type so that
the v2 B-tree could be held open, but not require the B-tree header to be
protected the whole time. A few other minor tweaks as well.
Also, remove unused 'dirty' flag from fractal heap header.
Tested on:
FreeBSD/32 6.3 (duty) in debug mode
FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
w/C++ & FORTRAN, w/threadsafe, in debug mode
Linux/64-amd64 2.6 (smirom) w/Intel compilers, w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode
Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
Mac OS X/32 10.6.1 (amazon) in debug mode
Mac OS X/32 10.6.1 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
-rw-r--r-- | src/H5B2.c | 473 | ||||
-rw-r--r-- | src/H5B2cache.c | 17 | ||||
-rw-r--r-- | src/H5B2hdr.c | 263 | ||||
-rw-r--r-- | src/H5B2pkg.h | 23 | ||||
-rw-r--r-- | src/H5B2private.h | 4 | ||||
-rw-r--r-- | src/H5B2stat.c | 6 | ||||
-rw-r--r-- | src/H5B2test.c | 33 | ||||
-rw-r--r-- | src/H5HF.c | 18 | ||||
-rw-r--r-- | src/H5HFcache.c | 18 | ||||
-rw-r--r-- | src/H5HFhdr.c | 69 | ||||
-rw-r--r-- | src/H5HFpkg.h | 5 | ||||
-rw-r--r-- | test/btree2.c | 285 |
12 files changed, 794 insertions, 420 deletions
@@ -41,7 +41,6 @@ #include "H5private.h" /* Generic Functions */ #include "H5B2pkg.h" /* v2 B-trees */ #include "H5Eprivate.h" /* Error handling */ -#include "H5MFprivate.h" /* File memory management */ /****************/ @@ -62,18 +61,15 @@ /********************/ /* Local Prototypes */ /********************/ -static H5B2_hdr_t *H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, - haddr_t addr, H5AC_protect_t rw); -static herr_t H5B2_close(H5B2_hdr_t *hdr, hid_t dxpl_id); +static H5B2_t *H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, + haddr_t addr); +static herr_t H5B2_close(H5B2_t *bt2, hid_t dxpl_id); /*********************/ /* Package Variables */ /*********************/ -/* Declare a free list to manage the H5B2_hdr_t struct */ -H5FL_DEFINE(H5B2_hdr_t); - /*****************************/ /* Library Private Variables */ @@ -84,6 +80,10 @@ H5FL_DEFINE(H5B2_hdr_t); /* Local Variables */ /*******************/ +/* Declare a free list to manage the H5B2_t struct */ +H5FL_DEFINE_STATIC(H5B2_t); + + /*------------------------------------------------------------------------- * Function: H5B2_create @@ -103,7 +103,7 @@ herr_t H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, haddr_t *addr_p) { - H5B2_hdr_t *hdr = NULL; /* The new B-tree header information */ + haddr_t hdr_addr; /* The new v2 B-tree header address */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_create, FAIL) @@ -115,36 +115,14 @@ H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, HDassert(cparam); HDassert(addr_p); - /* - * Allocate file and memory data structures. - */ - if(NULL == (hdr = H5FL_CALLOC(H5B2_hdr_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree header") - - /* Assign non-zero information */ - hdr->root.addr = HADDR_UNDEF; - - /* Initialize shared B-tree info */ - if(H5B2_hdr_init(f, hdr, cparam, 0) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "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(f)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "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_CANTINIT, FAIL, "can't add B-tree header to cache") + /* Create shared v2 B-tree header */ + if(HADDR_UNDEF == (hdr_addr = H5B2_hdr_create(f, dxpl_id, cparam))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't create v2 B-tree header") /* Set the B-tree's address to return */ - *addr_p = hdr->addr; + *addr_p = hdr_addr; done: - if(ret_value < 0) { - if(hdr) - (void)H5B2_cache_hdr_dest(f, hdr); - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_create() */ @@ -163,35 +141,53 @@ done: * *------------------------------------------------------------------------- */ -static H5B2_hdr_t * -H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, - H5AC_protect_t rw) +static H5B2_t * +H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr) { + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ - H5B2_hdr_t *ret_value; /* Return value */ + H5B2_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_open) /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); 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, type, NULL, rw))) + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, cls, NULL, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header") - /* Set file pointer for this B-tree operation */ - hdr->f = f; + /* 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 = hdr; + ret_value = bt2; done: - if(!ret_value) { - if(hdr && H5B2_close(hdr, dxpl_id) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close B-tree") - } /* end if */ + 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() */ @@ -211,23 +207,30 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, void *udata) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + 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(cls); HDassert(H5F_addr_defined(addr)); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Check if the root node is allocated yet */ if(!H5F_addr_defined(hdr->root.addr)) { /* Create root node as leaf node in B-tree */ @@ -257,7 +260,7 @@ H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -282,24 +285,31 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, H5B2_operator_t op, void *op_data) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_iterate, FAIL) /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); HDassert(op); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Iterate through records */ if(hdr->root.node_nrec > 0) { /* Iterate through nodes */ @@ -309,7 +319,7 @@ H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -340,10 +350,11 @@ done: *------------------------------------------------------------------------- */ htri_t -H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, void *udata, H5B2_found_t op, void *op_data) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + 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 */ @@ -354,13 +365,19 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Make copy of the root node pointer to start search with */ curr_node_ptr = hdr->root; @@ -455,7 +472,7 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -481,10 +498,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_found_t op, void *op_data) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + 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; /* Return value */ @@ -493,14 +511,20 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); HDassert(op); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Make copy of the root node pointer to start search with */ curr_node_ptr = hdr->root; @@ -620,7 +644,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -641,23 +665,30 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, void *udata, H5B2_remove_t op, void *op_data) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + 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(cls); HDassert(H5F_addr_defined(addr)); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Check for empty B-tree */ if(0 == hdr->root.all_nrec) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree") @@ -697,7 +728,7 @@ H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -718,24 +749,31 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, +H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_remove_t op, void *op_data) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + 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(cls); HDassert(H5F_addr_defined(addr)); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Check for empty B-tree */ if(0 == hdr->root.all_nrec) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree") @@ -783,7 +821,7 @@ H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -804,30 +842,37 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, hsize_t *nrec) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_get_nrec, FAIL) /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); HDassert(nrec); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Get B-tree number of records */ *nrec = hdr->root.all_nrec; done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -860,24 +905,31 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, H5B2_compare_t range, void *udata, H5B2_found_t op, void *op_data) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + 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(cls); HDassert(H5F_addr_defined(addr)); HDassert(op); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Check for empty tree */ if(!H5F_addr_defined(hdr->root.addr)) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records") @@ -894,7 +946,7 @@ H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -902,64 +954,6 @@ done: /*------------------------------------------------------------------------- - * 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_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(type); - HDassert(H5F_addr_defined(addr)); - - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") - - /* Delete all nodes in B-tree */ - if(H5F_addr_defined(hdr->root.addr)) - if(H5B2_delete_node(f, dxpl_id, hdr, hdr->depth, &hdr->root, op, op_data) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes") - - /* Mark B-tree header for deletion */ - if(H5B2_hdr_delete(hdr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to mark B-tree header for deletion") - -done: - /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) - HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5B2_delete() */ - - -/*------------------------------------------------------------------------- * Function: H5B2_modify * * Purpose: Locate the specified information in a B-tree and modify it. @@ -980,10 +974,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, void *udata, H5B2_modify_t op, void *op_data) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + 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 */ @@ -994,14 +989,20 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); HDassert(op); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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; + /* Make copy of the root node pointer to start search with */ curr_node_ptr = hdr->root; @@ -1119,7 +1120,7 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -1140,23 +1141,30 @@ done: *------------------------------------------------------------------------- */ 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_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, hsize_t *btree_size) { - H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ - herr_t ret_value = SUCCEED;/* Return value */ + H5B2_t *bt2 = NULL; /* Pointer to the B-tree */ + H5B2_hdr_t *hdr; /* Pointer to the B-tree header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B2_iterate_size, FAIL) /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); HDassert(btree_size); - /* Open the B-tree header */ - if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ))) + /* Open the B-tree */ + if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree") + /* 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(f); @@ -1173,7 +1181,7 @@ H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t add done: /* Close the B-tree */ - if(hdr && H5B2_close(hdr, dxpl_id) < 0) + if(bt2 && H5B2_close(bt2, dxpl_id) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree") FUNC_LEAVE_NOAPI(ret_value) @@ -1194,27 +1202,136 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2_close(H5B2_hdr_t *hdr, hid_t dxpl_id) +H5B2_close(H5B2_t *bt2, hid_t dxpl_id) { - unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for unprotecting header */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5B2_class_t *cls = NULL; /* Class of v2 B-tree client */ + 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_NOINIT(H5B2_close) /* Check arguments. */ - HDassert(hdr); - HDassert(hdr->f); - HDassert(H5F_addr_defined(hdr->addr)); + 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; + cls = bt2->hdr->cls; + } /* end if */ + } /* end if */ - /* Check if we are supposed to delete the header */ - if(hdr->pending_delete) - hdr_flags = H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; + /* 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") + + /* Check for pending v2 B-tree deletion */ + if(pending_delete) { + H5B2_hdr_t *hdr; /* Another pointer to v2 B-tree header */ + + /* Sanity check */ + HDassert(H5F_addr_defined(bt2_addr)); + HDassert(cls); - /* Release the B-tree header info */ - if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, hdr_flags) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header") + /* 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, cls, NULL, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header") + + /* Set the shared v2 B-tree header's file context for this operation */ + hdr->f = bt2->f; + + /* 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 the v2 B-tree wrapper */ + bt2 = H5FL_FREE(H5B2_t, bt2); 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, const H5B2_class_t *cls, 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(cls); + 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, cls, 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: + /* 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_delete() */ + diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 688bc33..0148777 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -167,9 +167,8 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, voi HDassert(cls); /* Allocate new B-tree header and reset cache info */ - if(NULL == (hdr = H5FL_MALLOC(H5B2_hdr_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemset(&hdr->cache_info, 0, sizeof(H5AC_info_t)); + 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)))) @@ -249,7 +248,8 @@ done: if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") if(!ret_value && hdr) - (void)H5B2_cache_hdr_dest(f, 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 */ @@ -404,9 +404,6 @@ H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr) if(H5B2_hdr_free(hdr) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header info") - /* Free B-tree header info */ - (void)H5FL_FREE(H5B2_hdr_t, hdr); - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_cache_hdr_dest() */ @@ -730,6 +727,7 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) /* * Check arguments. */ + HDassert(f); HDassert(internal); HDassert(internal->hdr); @@ -760,7 +758,7 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") /* Free B-tree internal node info */ - H5FL_FREE(H5B2_internal_t, internal); + internal = H5FL_FREE(H5B2_internal_t, internal); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1052,6 +1050,7 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) /* * Check arguments. */ + HDassert(f); HDassert(leaf); HDassert(leaf->hdr); @@ -1078,7 +1077,7 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") /* Free B-tree leaf node info */ - H5FL_FREE(H5B2_leaf_t, leaf); + leaf = H5FL_FREE(H5B2_leaf_t, leaf); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c index ef57186..95bafdd 100644 --- a/src/H5B2hdr.c +++ b/src/H5B2hdr.c @@ -79,6 +79,9 @@ /* 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); @@ -214,57 +217,104 @@ done: /*------------------------------------------------------------------------- - * Function: H5B2_hdr_free + * Function: H5B2_hdr_alloc * - * Purpose: Free B-tree header info + * 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->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 - * Feb 2 2005 + * Mar 21 2006 * *------------------------------------------------------------------------- */ -herr_t -H5B2_hdr_free(H5B2_hdr_t *hdr) +haddr_t +H5B2_hdr_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam) { - herr_t ret_value = SUCCEED; + H5B2_hdr_t *hdr = NULL; /* The new v2 B-tree header information */ + haddr_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_free) + FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_create) - /* Sanity check */ - HDassert(hdr); + /* + * Check arguments. + */ + HDassert(f); + HDassert(cparam); - /* Free the B-tree node buffer */ - if(hdr->page) - (void)H5FL_BLK_FREE(node_page, hdr->page); + /* 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") - /* 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); + /* Initialize shared B-tree info */ + if(H5B2_hdr_init(f, hdr, cparam, 0) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, HADDR_UNDEF, "can't create shared B-tree info") - /* Release the node info */ - if(hdr->node_info) { - unsigned u; /* Local index variable */ + /* 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(f)))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, HADDR_UNDEF, "file allocation failed for B-tree header") - /* Destroy free list factories */ - for(u = 0; u < (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_RESOURCE, 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_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory") - } /* end for */ + /* 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") - /* Free the array of node info structs */ - hdr->node_info = H5FL_SEQ_FREE(H5B2_node_info_t, hdr->node_info); - } /* end if */ + /* 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_free() */ +} /* end H5B2_hdr_create() */ /*------------------------------------------------------------------------- @@ -343,6 +393,63 @@ done: /*------------------------------------------------------------------------- + * 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 @@ -376,9 +483,66 @@ done: /*------------------------------------------------------------------------- + * 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 < (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: Mark B-tree header for deletion + * Purpose: Delete a v2 B-tree, starting with the header * * Return: Non-negative on success/Negative on failure * @@ -389,15 +553,42 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_hdr_delete(H5B2_hdr_t *hdr) +H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_delete) + 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); - /* Mark B-tree header as pending deletion */ - hdr->pending_delete = TRUE; +#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->f, dxpl_id, hdr, 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/H5B2pkg.h b/src/H5B2pkg.h index b47cc32..3961fb5 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -158,7 +158,10 @@ typedef struct H5B2_hdr_t { 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 */ + 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 */ @@ -189,6 +192,12 @@ typedef struct H5B2_internal_t { unsigned 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 { H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */ @@ -218,9 +227,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_hdr_t struct */ -H5FL_EXTERN(H5B2_hdr_t); - /* Declare a free list to manage the H5B2_internal_t struct */ H5FL_EXTERN(H5B2_internal_t); @@ -238,13 +244,18 @@ H5_DLLVAR const H5B2_class_t H5B2_TEST[1]; /******************************/ /* 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, unsigned 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_delete(H5B2_hdr_t *hdr); -H5_DLL herr_t H5B2_hdr_init(H5F_t *f, H5B2_hdr_t *hdr, - const H5B2_create_t *cparam, unsigned depth); 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, diff --git a/src/H5B2private.h b/src/H5B2private.h index e99def0..481f910 100644 --- a/src/H5B2private.h +++ b/src/H5B2private.h @@ -116,6 +116,10 @@ typedef struct H5B2_stat_t { 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 */ /*****************************/ diff --git a/src/H5B2stat.c b/src/H5B2stat.c index 4b97e17..5fc7659 100644 --- a/src/H5B2stat.c +++ b/src/H5B2stat.c @@ -85,7 +85,7 @@ *------------------------------------------------------------------------- */ herr_t -H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, H5B2_stat_t *info) { H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ @@ -95,12 +95,12 @@ H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); HDassert(info); /* Look up the B-tree header */ - if(NULL == (hdr = (H5B2_hdr_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, cls, NULL, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") /* Get information about the B-tree */ diff --git a/src/H5B2test.c b/src/H5B2test.c index 2413199..d073322 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,9 +65,11 @@ 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 */ @@ -75,6 +81,7 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */ H5B2_test_debug /* Record debugging callback */ }}; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -84,6 +91,7 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */ /* Local Variables */ /*******************/ + /*------------------------------------------------------------------------- * Function: H5B2_test_store @@ -228,7 +236,7 @@ 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, +H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, haddr_t *root_addr) { H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ @@ -238,12 +246,12 @@ H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); HDassert(root_addr); /* Look up the B-tree header */ - if(NULL == (hdr = (H5B2_hdr_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, cls, NULL, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") /* Get B-tree root addr */ @@ -272,7 +280,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, +H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, void *udata, H5B2_node_info_test_t *ninfo) { H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */ @@ -286,11 +294,11 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); 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, type, NULL, H5AC_READ))) + if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, cls, NULL, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header") /* Set file pointer for this B-tree operation */ @@ -374,11 +382,8 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, done: /* Release 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_CANTUNPROTECT, FAIL, "unable to release B-tree header info") - } /* end if */ + 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 B-tree header info") FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_get_node_info_test() */ @@ -401,7 +406,7 @@ done: *------------------------------------------------------------------------- */ int -H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, +H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, void *udata) { H5B2_node_info_test_t ninfo; /* Node information */ @@ -411,11 +416,11 @@ H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, hadd /* Check arguments. */ HDassert(f); - HDassert(type); + HDassert(cls); HDassert(H5F_addr_defined(addr)); /* 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(f, dxpl_id, cls, addr, udata, &ninfo) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "error looking up node info") /* Set return value */ @@ -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() */ diff --git a/src/H5HFcache.c b/src/H5HFcache.c index bf19044..08ad558 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -431,7 +431,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 */ @@ -479,9 +480,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; @@ -566,7 +564,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 */ @@ -620,16 +617,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() */ diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index d1f2675..c7dada2 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) @@ -457,7 +454,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 +502,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 +678,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 +1487,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 +1539,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/H5HFpkg.h b/src/H5HFpkg.h index 21e2865..a4e7037 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -335,7 +335,6 @@ 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 */ @@ -504,9 +503,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); @@ -564,6 +560,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/test/btree2.c b/test/btree2.c index 88f4f07..1713d15 100644 --- a/test/btree2.c +++ b/test/btree2.c @@ -42,8 +42,35 @@ const char *FILENAME[] = { #define DELETE_MEDIUM 200 #define DELETE_LARGE 2000 -/* B-tree creation parameters */ -static const H5B2_create_t cparam_g = {H5B2_TEST, 512, 8, 100, 40}; + +/*------------------------------------------------------------------------- + * Function: init_cparam + * + * Purpose: Initialize v2 B-tree creation parameter structure + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Thursday, October 29, 2009 + * + *------------------------------------------------------------------------- + */ +static int +init_cparam(H5B2_create_t *cparam) +{ + /* Wipe out background */ + HDmemset(cparam, 0, sizeof(*cparam)); + + /* General parameters */ + cparam->cls = H5B2_TEST; + cparam->node_size = (size_t)512; + cparam->rrec_size = (size_t)8; + cparam->split_percent = 100; + cparam->merge_percent = 40; + + return(0); +} /* init_cparam() */ /*------------------------------------------------------------------------- @@ -223,7 +250,7 @@ remove_cb(const void *_record, void *_op_data) *------------------------------------------------------------------------- */ static unsigned -test_insert_basic(hid_t fapl) +test_insert_basic(hid_t fapl, const H5B2_create_t *cparam) { hid_t file = -1; /* File ID */ char filename[1024]; /* Filename to use */ @@ -248,7 +275,7 @@ test_insert_basic(hid_t fapl) * Test v2 B-tree creation */ TESTING("B-tree creation"); - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(bt2_addr)) FAIL_STACK_ERROR @@ -408,7 +435,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_split_root(hid_t fapl) +test_insert_split_root(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -439,7 +466,7 @@ test_insert_split_root(hid_t fapl) /* * Test v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert records to fill root leaf node */ @@ -584,7 +611,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level1_2leaf_redistrib(hid_t fapl) +test_insert_level1_2leaf_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -613,7 +640,7 @@ test_insert_level1_2leaf_redistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 leaves */ @@ -666,7 +693,7 @@ test_insert_level1_2leaf_redistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 leaves */ @@ -744,7 +771,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level1_side_split(hid_t fapl) +test_insert_level1_side_split(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -773,7 +800,7 @@ test_insert_level1_side_split(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 leaves */ @@ -831,7 +858,7 @@ test_insert_level1_side_split(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 leaves */ @@ -915,7 +942,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level1_3leaf_redistrib(hid_t fapl) +test_insert_level1_3leaf_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -945,7 +972,7 @@ test_insert_level1_3leaf_redistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 leaves */ @@ -1063,7 +1090,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level1_middle_split(hid_t fapl) +test_insert_level1_middle_split(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -1093,7 +1120,7 @@ test_insert_level1_middle_split(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 leaves */ @@ -1187,7 +1214,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_make_level2(hid_t fapl) +test_insert_make_level2(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -1218,7 +1245,7 @@ test_insert_make_level2(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 internal nodes */ @@ -1371,7 +1398,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level2_leaf_redistrib(hid_t fapl) +test_insert_level2_leaf_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -1401,7 +1428,7 @@ test_insert_level2_leaf_redistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 internal nodes */ @@ -1636,7 +1663,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level2_leaf_split(hid_t fapl) +test_insert_level2_leaf_split(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -1666,7 +1693,7 @@ test_insert_level2_leaf_split(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 internal nodes */ @@ -1912,7 +1939,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level2_2internal_redistrib(hid_t fapl) +test_insert_level2_2internal_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -1942,7 +1969,7 @@ test_insert_level2_2internal_redistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 internal nodes */ @@ -2105,7 +2132,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level2_2internal_split(hid_t fapl) +test_insert_level2_2internal_split(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -2135,7 +2162,7 @@ test_insert_level2_2internal_split(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 2 internal nodes */ @@ -2308,7 +2335,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level2_3internal_redistrib(hid_t fapl) +test_insert_level2_3internal_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -2338,7 +2365,7 @@ test_insert_level2_3internal_redistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 3 internal nodes */ @@ -2510,7 +2537,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_level2_3internal_split(hid_t fapl) +test_insert_level2_3internal_split(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -2540,7 +2567,7 @@ test_insert_level2_3internal_split(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert enough records to force root to split into 3 internal nodes */ @@ -2715,7 +2742,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_insert_lots(hid_t fapl) +test_insert_lots(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -2774,7 +2801,7 @@ HDfprintf(stderr,"curr_time=%lu\n",(unsigned long)curr_time); /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert random records */ @@ -2921,7 +2948,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_basic(hid_t fapl) +test_remove_basic(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -2949,7 +2976,7 @@ test_remove_basic(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Query the number of records in the B-tree */ @@ -3206,7 +3233,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_noredistrib(hid_t fapl) +test_remove_level1_noredistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -3236,7 +3263,7 @@ test_remove_level1_noredistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 3 leaves */ @@ -3429,7 +3456,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_redistrib(hid_t fapl) +test_remove_level1_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -3458,7 +3485,7 @@ test_remove_level1_redistrib(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 3 leaves */ @@ -3629,7 +3656,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_2leaf_merge(hid_t fapl) +test_remove_level1_2leaf_merge(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -3658,7 +3685,7 @@ test_remove_level1_2leaf_merge(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 3 leaves */ @@ -3813,7 +3840,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_3leaf_merge(hid_t fapl) +test_remove_level1_3leaf_merge(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -3842,7 +3869,7 @@ test_remove_level1_3leaf_merge(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 3 leaves */ @@ -3941,7 +3968,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_promote(hid_t fapl) +test_remove_level1_promote(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -3970,7 +3997,7 @@ test_remove_level1_promote(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 5 leaves */ @@ -4185,7 +4212,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_promote_2leaf_redistrib(hid_t fapl) +test_remove_level1_promote_2leaf_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -4214,7 +4241,7 @@ test_remove_level1_promote_2leaf_redistrib(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 3 leaves */ @@ -4338,7 +4365,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_promote_3leaf_redistrib(hid_t fapl) +test_remove_level1_promote_3leaf_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -4367,7 +4394,7 @@ test_remove_level1_promote_3leaf_redistrib(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 3 leaves */ @@ -4491,7 +4518,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_promote_2leaf_merge(hid_t fapl) +test_remove_level1_promote_2leaf_merge(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -4520,7 +4547,7 @@ test_remove_level1_promote_2leaf_merge(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 3 leaves */ @@ -4639,7 +4666,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_promote_3leaf_merge(hid_t fapl) +test_remove_level1_promote_3leaf_merge(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -4668,7 +4695,7 @@ test_remove_level1_promote_3leaf_merge(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 leaves */ @@ -4787,7 +4814,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level1_collapse(hid_t fapl) +test_remove_level1_collapse(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -4815,7 +4842,7 @@ test_remove_level1_collapse(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-1 B-tree with 2 leaves */ @@ -4926,7 +4953,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_promote(hid_t fapl) +test_remove_level2_promote(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -4955,7 +4982,7 @@ test_remove_level2_promote(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -5217,7 +5244,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_promote_2internal_redistrib(hid_t fapl) +test_remove_level2_promote_2internal_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -5246,7 +5273,7 @@ test_remove_level2_promote_2internal_redistrib(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -5370,7 +5397,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_promote_3internal_redistrib(hid_t fapl) +test_remove_level2_promote_3internal_redistrib(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -5399,7 +5426,7 @@ test_remove_level2_promote_3internal_redistrib(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -5523,7 +5550,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_promote_2internal_merge(hid_t fapl) +test_remove_level2_promote_2internal_merge(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -5552,7 +5579,7 @@ test_remove_level2_promote_2internal_merge(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -5679,7 +5706,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_promote_3internal_merge(hid_t fapl) +test_remove_level2_promote_3internal_merge(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -5708,7 +5735,7 @@ test_remove_level2_promote_3internal_merge(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -5835,7 +5862,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_2internal_merge_left(hid_t fapl) +test_remove_level2_2internal_merge_left(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -5864,7 +5891,7 @@ test_remove_level2_2internal_merge_left(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -5963,7 +5990,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_2internal_merge_right(hid_t fapl) +test_remove_level2_2internal_merge_right(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -5992,7 +6019,7 @@ test_remove_level2_2internal_merge_right(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -6091,7 +6118,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_3internal_merge(hid_t fapl) +test_remove_level2_3internal_merge(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -6120,7 +6147,7 @@ test_remove_level2_3internal_merge(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -6219,7 +6246,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_level2_collapse_right(hid_t fapl) +test_remove_level2_collapse_right(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -6249,7 +6276,7 @@ test_remove_level2_collapse_right(hid_t fapl) /* * v2 B-tree creation */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -6345,8 +6372,8 @@ error: *------------------------------------------------------------------------- */ static unsigned -gen_l4_btree2(const char *filename, hid_t fapl, haddr_t *bt2_addr, - const hsize_t *records) +gen_l4_btree2(const char *filename, hid_t fapl, const H5B2_create_t *cparam, + haddr_t *bt2_addr, const hsize_t *records) { hid_t file = -1; H5F_t *f = NULL; @@ -6365,7 +6392,7 @@ gen_l4_btree2(const char *filename, hid_t fapl, haddr_t *bt2_addr, /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert random records */ @@ -6412,7 +6439,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_remove_lots(const char *env_h5_drvr, hid_t fapl) +test_remove_lots(const char *env_h5_drvr, hid_t fapl, const H5B2_create_t *cparam) { hid_t file = -1; char filename[1024]; @@ -6465,7 +6492,7 @@ HDfprintf(stderr, "curr_time = %lu\n", (unsigned long)curr_time); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); /* Generate the v2 B-tree to test */ - if(gen_l4_btree2(filename, fapl, &bt2_addr, records)) + if(gen_l4_btree2(filename, fapl, cparam, &bt2_addr, records)) TEST_ERROR /* Check for VFD which stores data in multiple files */ @@ -6572,7 +6599,7 @@ HDfprintf(stderr, "curr_time = %lu\n", (unsigned long)curr_time); } /* end if */ else { /* Re-generate the v2 B-tree to test */ - if(gen_l4_btree2(filename, fapl, &bt2_addr, records)) + if(gen_l4_btree2(filename, fapl, cparam, &bt2_addr, records)) TEST_ERROR } /* end else */ @@ -6646,7 +6673,7 @@ HDfprintf(stderr, "curr_time = %lu\n", (unsigned long)curr_time); } /* end if */ else { /* Re-generate the v2 B-tree to test */ - if(gen_l4_btree2(filename, fapl, &bt2_addr, records)) + if(gen_l4_btree2(filename, fapl, cparam, &bt2_addr, records)) TEST_ERROR } /* end else */ @@ -6718,7 +6745,7 @@ HDfprintf(stderr, "curr_time = %lu\n", (unsigned long)curr_time); } /* end if */ else { /* Re-generate the v2 B-tree to test */ - if(gen_l4_btree2(filename, fapl, &bt2_addr, records)) + if(gen_l4_btree2(filename, fapl, cparam, &bt2_addr, records)) TEST_ERROR } /* end else */ @@ -6808,7 +6835,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_find_neighbor(hid_t fapl) +test_find_neighbor(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -6847,7 +6874,7 @@ test_find_neighbor(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert records */ @@ -7029,7 +7056,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_delete(hid_t fapl) +test_delete(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -7071,7 +7098,7 @@ test_delete(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* @@ -7108,7 +7135,7 @@ test_delete(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert records */ @@ -7158,7 +7185,7 @@ test_delete(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert records */ @@ -7208,7 +7235,7 @@ test_delete(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Insert records */ @@ -7270,7 +7297,7 @@ error: *------------------------------------------------------------------------- */ static unsigned -test_modify(hid_t fapl) +test_modify(hid_t fapl, const H5B2_create_t *cparam) { hid_t file=-1; char filename[1024]; @@ -7302,7 +7329,7 @@ test_modify(hid_t fapl) /* * Create v2 B-tree */ - if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, &cparam_g, &bt2_addr/*out*/) < 0) + if(H5B2_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &bt2_addr/*out*/) < 0) FAIL_STACK_ERROR /* Create level-2 B-tree with 3 internal nodes */ @@ -7493,6 +7520,7 @@ error: int main(void) { + H5B2_create_t cparam; /* Creation parameters for v2 B-tree */ hid_t fapl = -1; /* File access property list for data files */ unsigned nerrors = 0; /* Cumulative error count */ int ExpressMode; @@ -7509,61 +7537,64 @@ main(void) if (ExpressMode > 1) printf("***Express test mode on. Some tests may be skipped\n"); + /* Initialize v2 B-tree creation parameters */ + init_cparam(&cparam); + /* Test B-tree record insertion */ /* Iteration, find & index routines tested in these routines as well */ - nerrors += test_insert_basic(fapl); - nerrors += test_insert_split_root(fapl); - nerrors += test_insert_level1_2leaf_redistrib(fapl); - nerrors += test_insert_level1_side_split(fapl); - nerrors += test_insert_level1_3leaf_redistrib(fapl); - nerrors += test_insert_level1_middle_split(fapl); - nerrors += test_insert_make_level2(fapl); - nerrors += test_insert_level2_leaf_redistrib(fapl); - nerrors += test_insert_level2_leaf_split(fapl); - nerrors += test_insert_level2_2internal_redistrib(fapl); - nerrors += test_insert_level2_2internal_split(fapl); - nerrors += test_insert_level2_3internal_redistrib(fapl); - nerrors += test_insert_level2_3internal_split(fapl); + nerrors += test_insert_basic(fapl, &cparam); + nerrors += test_insert_split_root(fapl, &cparam); + nerrors += test_insert_level1_2leaf_redistrib(fapl, &cparam); + nerrors += test_insert_level1_side_split(fapl, &cparam); + nerrors += test_insert_level1_3leaf_redistrib(fapl, &cparam); + nerrors += test_insert_level1_middle_split(fapl, &cparam); + nerrors += test_insert_make_level2(fapl, &cparam); + nerrors += test_insert_level2_leaf_redistrib(fapl, &cparam); + nerrors += test_insert_level2_leaf_split(fapl, &cparam); + nerrors += test_insert_level2_2internal_redistrib(fapl, &cparam); + nerrors += test_insert_level2_2internal_split(fapl, &cparam); + nerrors += test_insert_level2_3internal_redistrib(fapl, &cparam); + nerrors += test_insert_level2_3internal_split(fapl, &cparam); if (ExpressMode > 1) printf("***Express test mode on. test_insert_lots skipped\n"); else - nerrors += test_insert_lots(fapl); + nerrors += test_insert_lots(fapl, &cparam); /* Test B-tree record removal */ /* Querying the number of records routine also tested in these routines as well */ - nerrors += test_remove_basic(fapl); - nerrors += test_remove_level1_noredistrib(fapl); - nerrors += test_remove_level1_redistrib(fapl); - nerrors += test_remove_level1_2leaf_merge(fapl); - nerrors += test_remove_level1_3leaf_merge(fapl); - nerrors += test_remove_level1_promote(fapl); - nerrors += test_remove_level1_promote_2leaf_redistrib(fapl); - nerrors += test_remove_level1_promote_3leaf_redistrib(fapl); - nerrors += test_remove_level1_promote_2leaf_merge(fapl); - nerrors += test_remove_level1_promote_3leaf_merge(fapl); - nerrors += test_remove_level1_collapse(fapl); - nerrors += test_remove_level2_promote(fapl); - nerrors += test_remove_level2_promote_2internal_redistrib(fapl); - nerrors += test_remove_level2_promote_3internal_redistrib(fapl); - nerrors += test_remove_level2_promote_2internal_merge(fapl); - nerrors += test_remove_level2_promote_3internal_merge(fapl); - nerrors += test_remove_level2_2internal_merge_left(fapl); - nerrors += test_remove_level2_2internal_merge_right(fapl); - nerrors += test_remove_level2_3internal_merge(fapl); - nerrors += test_remove_level2_collapse_right(fapl); + nerrors += test_remove_basic(fapl, &cparam); + nerrors += test_remove_level1_noredistrib(fapl, &cparam); + nerrors += test_remove_level1_redistrib(fapl, &cparam); + nerrors += test_remove_level1_2leaf_merge(fapl, &cparam); + nerrors += test_remove_level1_3leaf_merge(fapl, &cparam); + nerrors += test_remove_level1_promote(fapl, &cparam); + nerrors += test_remove_level1_promote_2leaf_redistrib(fapl, &cparam); + nerrors += test_remove_level1_promote_3leaf_redistrib(fapl, &cparam); + nerrors += test_remove_level1_promote_2leaf_merge(fapl, &cparam); + nerrors += test_remove_level1_promote_3leaf_merge(fapl, &cparam); + nerrors += test_remove_level1_collapse(fapl, &cparam); + nerrors += test_remove_level2_promote(fapl, &cparam); + nerrors += test_remove_level2_promote_2internal_redistrib(fapl, &cparam); + nerrors += test_remove_level2_promote_3internal_redistrib(fapl, &cparam); + nerrors += test_remove_level2_promote_2internal_merge(fapl, &cparam); + nerrors += test_remove_level2_promote_3internal_merge(fapl, &cparam); + nerrors += test_remove_level2_2internal_merge_left(fapl, &cparam); + nerrors += test_remove_level2_2internal_merge_right(fapl, &cparam); + nerrors += test_remove_level2_3internal_merge(fapl, &cparam); + nerrors += test_remove_level2_collapse_right(fapl, &cparam); if (ExpressMode > 1) printf("***Express test mode on. test_remove_lots skipped\n"); else - nerrors += test_remove_lots(envval, fapl); + nerrors += test_remove_lots(envval, fapl, &cparam); /* Test more complex B-tree queries */ - nerrors += test_find_neighbor(fapl); + nerrors += test_find_neighbor(fapl, &cparam); /* Test deleting B-trees */ - nerrors += test_delete(fapl); + nerrors += test_delete(fapl, &cparam); /* Test modifying B-tree records */ - nerrors += test_modify(fapl); + nerrors += test_modify(fapl, &cparam); if(nerrors) goto error; |