From 89f36d62b776ef955eed82a109b83a187ef115bb Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sun, 13 Aug 2006 21:50:11 -0500 Subject: [svn-r12575] Description: Allow the heap ID length to be chosen at heap creation time, to allow for making heap IDs long enough to directly embed the file offset & length of 'huge' objects in the heap ID (which allows them to be retrieved directly from disk, instead of requiring them to be looked up in the B-tree that tracks 'huge' objects) Tested on: FreeBSD/32 4.11 (sleipnir) Linux/64 2.4 (mir) Solaris/64 9 (shanti) --- src/H5HF.c | 5 +- src/H5HFcache.c | 6 ++ src/H5HFhdr.c | 116 ++++++++++++++++++++++++++++++---- src/H5HFhuge.c | 3 + src/H5HFpkg.h | 14 ++--- src/H5HFprivate.h | 4 ++ test/fheap.c | 184 ++++++++++++++++++++++++++++++++++++++++++++---------- 7 files changed, 277 insertions(+), 55 deletions(-) diff --git a/src/H5HF.c b/src/H5HF.c index 7ce115c..20d1aef 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -112,12 +112,11 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) HDassert(f); HDassert(cparam); - /* Initialize shared fractal heap header */ - /* (This routine is only called for newly created heaps) */ + /* Create shared fractal heap header */ if(HADDR_UNDEF == (hdr_addr = H5HF_hdr_create(f, dxpl_id, cparam))) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't create fractal heap header") - /* Create fractal heap wrapper */ + /* 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") diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 4915533..e174260 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -309,6 +309,9 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); if(metadata_chksum != 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap header") + /* Heap ID length */ + UINT16DECODE(p, hdr->id_len); + /* Heap status flags */ /* (bit 0: "huge" object IDs have wrapped) */ heap_flags = *p++; @@ -419,6 +422,9 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a HDmemset(p, 0, (size_t)4); p += 4; + /* Heap ID length */ + UINT16ENCODE(p, hdr->id_len); + /* Heap status flags */ /* (bit 0: "huge" object IDs have wrapped) */ heap_flags = 0; diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index 7d36291..a0af4b1 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -193,25 +193,24 @@ H5HF_hdr_compute_free_space(H5HF_hdr_t *hdr, unsigned iblock_row) /*------------------------------------------------------------------------- - * Function: H5HF_hdr_finish_init + * Function: H5HF_hdr_finish_init_phase1 * - * Purpose: Finish initializing info in shared heap header + * Purpose: First phase to finish initializing info in shared heap header * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 21 2006 + * koziol@hdfgroup.org + * Aug 12 2006 * *------------------------------------------------------------------------- */ herr_t -H5HF_hdr_finish_init(H5HF_hdr_t *hdr) +H5HF_hdr_finish_init_phase1(H5HF_hdr_t *hdr) { - unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_finish_init) + FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_finish_init_phase1) /* * Check arguments. @@ -226,7 +225,37 @@ H5HF_hdr_finish_init(H5HF_hdr_t *hdr) /* Set the size of heap IDs */ hdr->heap_len_size = MIN(hdr->man_dtable.max_dir_blk_off_size, ((H5V_log2_gen((hsize_t)hdr->max_man_size) + 7) / 8)); - hdr->id_len = H5HF_ID_SIZE(hdr); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_hdr_finish_init_phase1() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_hdr_finish_init_pahse2 + * + * Purpose: Second phase to finish initializing info in shared heap header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 12 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_hdr_finish_init_phase2(H5HF_hdr_t *hdr) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_finish_init_phase2) + + /* + * Check arguments. + */ + HDassert(hdr); /* Set the free space in direct blocks */ for(u = 0; u < hdr->man_dtable.max_root_rows; u++) { @@ -256,6 +285,44 @@ HDfprintf(stderr, "%s: row_max_dblock_free[%Zu] = %Zu\n", FUNC, u, hdr->man_dtab done: FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_hdr_finish_init_phase2() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_hdr_finish_init + * + * Purpose: Finish initializing info in shared heap header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 21 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_hdr_finish_init(H5HF_hdr_t *hdr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_finish_init) + + /* + * Check arguments. + */ + HDassert(hdr); + + /* First phase of header final initialization */ + if(H5HF_hdr_finish_init_phase1(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't finish phase #1 of header final initialization") + + /* Second phase of header final initialization */ + if(H5HF_hdr_finish_init_phase2(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't finish phase #2 of header final initialization") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_finish_init() */ @@ -342,9 +409,36 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Note that the shared info is dirty (it's not written to the file yet) */ hdr->dirty = TRUE; - /* Finish fractal heap header initialization */ - if(H5HF_hdr_finish_init(hdr) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "can't create ref-count wrapper for shared fractal heap header") + /* First phase of header final initialization */ + if(H5HF_hdr_finish_init_phase1(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #1 of header final initialization") + + /* Set the length of IDs in the heap */ + /* (This code is not in the "finish init phase" routines because those + * routines are also called from the cache 'load' callback, and the ID + * length is already set in that case (its stored in the header on disk)) + */ + 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; + break; + + case 1: /* Set the length of heap IDs to just enough to hold the file offset & length of 'huge' objects in the heap */ + hdr->id_len = 1 + hdr->sizeof_size + hdr->sizeof_addr; + break; + + default: /* Use the requested size for the heap ID */ +/* XXX: Limit heap ID length to 4096 + 1, due to # of bits required to store + * length of 'tiny' objects (12 bits) + */ +HDfprintf(stderr, "%s: Varying size of heap IDs not supported yet!\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, HADDR_UNDEF, "varying size of heap IDs not supported yet") + break; + } /* end switch */ + + /* Second phase of header final initialization */ + if(H5HF_hdr_finish_init_phase2(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #2 of header final initialization") #ifdef QAK HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c index ca256e6..7a47dba 100644 --- a/src/H5HFhuge.c +++ b/src/H5HFhuge.c @@ -158,6 +158,9 @@ H5HF_huge_init(H5HF_hdr_t *hdr) /* Check if we can completely hold the 'huge' object's offset & length in * the file in the heap ID (which will speed up accessing it) */ +#ifdef QAK +HDfprintf(stderr, "%s: hdr->id_len = %u\n", "H5HF_huge_init", (unsigned)hdr->id_len); +#endif /* QAK */ if((hdr->sizeof_addr + hdr->sizeof_size) <= (hdr->id_len - 1)) { /* Indicate that v2 B-tree doesn't have to be used to locate object */ hdr->huge_ids_direct = TRUE; diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index 209eeed..21e5468 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -79,6 +79,7 @@ /* Fractal Heap Header specific fields */ \ \ /* General heap information */ \ + + 2 /* Heap ID len */ \ + 1 /* Status flags */ \ \ /* "Huge" object fields */ \ @@ -154,13 +155,6 @@ UINT64DECODE_VAR((i), (o), (h)->heap_off_size); \ UINT64DECODE_VAR((i), (l), (h)->heap_len_size) -/* Size of ID for heap */ -#define H5HF_ID_SIZE(h) ( \ - 1 /* ID flag byte */ \ - + (h)->heap_off_size /* Space for managed object offset */ \ - + (h)->heap_len_size /* Space for managed object length */ \ - ) - /* Free space section types for fractal heap */ /* (values stored in free space data structures in file) */ #define H5HF_FSPACE_SECT_SINGLE 0 /* Section is a range of actual bytes in a direct block */ @@ -293,6 +287,9 @@ typedef struct H5HF_hdr_t { /* Information for H5AC cache functions, _must_ be first field in structure */ H5AC_info_t cache_info; + /* General header information (stored in header) */ + unsigned id_len; /* Size of heap IDs (in bytes) */ + /* Flags for heap settings (stored in status byte in header) */ hbool_t debug_objs; /* Is the heap storing objects in 'debug' format */ hbool_t have_io_filter; /* Does the heap have I/O filters for the direct blocks? */ @@ -328,7 +325,6 @@ typedef struct H5HF_hdr_t { H5F_t *f; /* Pointer to file for heap */ size_t sizeof_size; /* Size of file sizes */ size_t sizeof_addr; /* Size of file addresses */ - size_t id_len; /* Size of heap IDs (in bytes) */ H5FS_t *fspace; /* Free space list for objects in heap */ H5HF_block_iter_t next_block; /* Block iterator for searching for next block with space */ H5B2_class_t huge_bt2_class; /* v2 B-tree class information for "huge" object tracking */ @@ -465,6 +461,8 @@ H5FL_SEQ_EXTERN(H5HF_indirect_ent_t); /* Routines for managing shared fractal heap header */ H5_DLL H5HF_hdr_t * H5HF_hdr_alloc(H5F_t *f); H5_DLL haddr_t H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam); +H5_DLL herr_t H5HF_hdr_finish_init_phase1(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_hdr_finish_init_phase2(H5HF_hdr_t *hdr); H5_DLL herr_t H5HF_hdr_finish_init(H5HF_hdr_t *hdr); /* Doubling table routines */ diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h index 3461500..1c9a3ba 100644 --- a/src/H5HFprivate.h +++ b/src/H5HFprivate.h @@ -58,6 +58,10 @@ typedef struct H5HF_create_t { H5HF_dtable_cparam_t managed;/* Mapped object doubling-table creation parameters */ uint32_t max_man_size; /* Max. size of object to manage in doubling table */ /* (i.e. min. size of object to store standalone) */ + uint16_t id_len; /* Length of IDs to use for heap objects */ + /* (0 - make ID just large enough to hold length & offset of object in the heap) */ + /* (1 - make ID just large enough to allow 'huge' objects to hold the file address & length of the 'huge' object) */ + /* (n - make ID 'n' bytes in size) */ } H5HF_create_t; /* Fractal heap metadata statistics info */ diff --git a/test/fheap.c b/test/fheap.c index 05a392d..49baf02 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -45,6 +45,7 @@ #define SMALL_MAN_MAX_DIRECT_SIZE (64 * 1024) /* Managed obj. max. direct block size */ #define SMALL_MAN_MAX_INDEX 32 /* Managed obj. # of bits for total heap size */ #define SMALL_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */ +#define SMALL_ID_LEN 0 /* "Default" heap ID length */ #define SMALL_STAND_SIZE (SMALL_MAN_MAX_DIRECT_SIZE - SMALL_DBLOCK_OVERHEAD) /* Standalone obj. min. size */ /* Define this macro to enable all insertion tests */ @@ -99,6 +100,7 @@ typedef struct fheap_test_param_t { fheap_test_del_dir_t del_dir; /* Whether to delete objects forward or reverse */ fheap_test_del_drain_t drain_half; /* Whether to drain half of the objects & refill, when deleting objects */ fheap_test_fill_t fill; /* How to "bulk" fill heap blocks */ + unsigned actual_id_len; /* The actual length of heap IDs for a test */ } fheap_test_param_t; /* Heap state information */ @@ -158,6 +160,7 @@ init_small_cparam(H5HF_create_t *cparam) HDmemset(cparam, 0, sizeof(H5HF_create_t)); /* General parameters */ + cparam->id_len = SMALL_ID_LEN; cparam->max_man_size = SMALL_STAND_SIZE; /* Managed object doubling-table parameters */ @@ -471,7 +474,7 @@ open_heap(char *filename, hid_t fapl, hid_t dxpl, const H5HF_create_t *cparam, FAIL_STACK_ERROR if(H5HF_get_id_len(*fh, &id_len) < 0) FAIL_STACK_ERROR - if(id_len > HEAP_ID_LEN) + if(id_len > tparam->actual_id_len) TEST_ERROR if(H5HF_get_heap_addr(*fh, fh_addr) < 0) FAIL_STACK_ERROR @@ -511,7 +514,7 @@ open_heap(char *filename, hid_t fapl, hid_t dxpl, const H5HF_create_t *cparam, FAIL_STACK_ERROR if(H5HF_get_id_len(*fh, &id_len) < 0) FAIL_STACK_ERROR - if(id_len > HEAP_ID_LEN) + if(id_len > tparam->actual_id_len) TEST_ERROR if(H5HF_get_heap_addr(*fh, fh_addr) < 0) FAIL_STACK_ERROR @@ -10885,9 +10888,10 @@ test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ - unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */ + unsigned char *heap_id = NULL; /* Heap ID for object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ fheap_heap_state_t state; /* State of fractal heap */ @@ -10901,9 +10905,19 @@ test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR + /* Insert object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -10973,6 +10987,7 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10984,6 +10999,7 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11020,10 +11036,11 @@ test_huge_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ - unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for first object */ - unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ + unsigned char *heap_id = NULL; /* Heap ID for first object */ + unsigned char *heap_id2 = NULL; /* Heap ID for second object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ fheap_heap_state_t state; /* State of fractal heap */ @@ -11037,9 +11054,21 @@ test_huge_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR + /* Insert object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11065,7 +11094,7 @@ test_huge_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Insert second object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id2) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11180,6 +11209,8 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11191,6 +11222,8 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11227,11 +11260,12 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ - unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for first object */ - unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ - unsigned char heap_id3[HEAP_ID_LEN]; /* Heap ID for third object */ + unsigned char *heap_id = NULL; /* Heap ID for first object */ + unsigned char *heap_id2 = NULL; /* Heap ID for second object */ + unsigned char *heap_id3 = NULL; /* Heap ID for third object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ fheap_heap_state_t state; /* State of fractal heap */ @@ -11245,9 +11279,23 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id3 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR + /* Insert first object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11273,7 +11321,7 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp /* Insert second object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 2; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id2) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11299,7 +11347,7 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp /* Insert third object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 3; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id3) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id3) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11454,6 +11502,9 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11465,6 +11516,9 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11501,13 +11555,14 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ - unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for first object */ - unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ - unsigned char heap_id3[HEAP_ID_LEN]; /* Heap ID for third object */ - unsigned char heap_id4[HEAP_ID_LEN]; /* Heap ID for fourth object */ - unsigned char heap_id5[HEAP_ID_LEN]; /* Heap ID for fifth object */ + unsigned char *heap_id = NULL; /* Heap ID for first object */ + unsigned char *heap_id2 = NULL; /* Heap ID for second object */ + unsigned char *heap_id3 = NULL; /* Heap ID for third object */ + unsigned char *heap_id4 = NULL; /* Heap ID for fourth object */ + unsigned char *heap_id5 = NULL; /* Heap ID for fifth object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ fheap_heap_state_t state; /* State of fractal heap */ @@ -11521,9 +11576,27 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id3 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id4 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id5 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR + /* Insert first object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11549,7 +11622,7 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Insert second object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 2; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id2) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11575,7 +11648,7 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Insert third object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 3; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id3) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id3) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11601,7 +11674,7 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Insert fourth object small enough to fit into 'normal' heap blocks */ obj_size = DBLOCK_SIZE(fh, 0) + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id4) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id4) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11634,7 +11707,7 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Insert fifth object small enough to fit into 'normal' heap blocks */ obj_size = DBLOCK_SIZE(fh, 3) + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, &heap_id5) < 0) + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id5) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -11810,6 +11883,11 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); + H5MM_xfree(heap_id4); + H5MM_xfree(heap_id5); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11821,6 +11899,11 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); + H5MM_xfree(heap_id4); + H5MM_xfree(heap_id5); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -12250,6 +12333,7 @@ curr_test = FHEAP_TEST_REOPEN; #endif /* QAK */ /* Clear the testing parameters */ HDmemset(&tparam, 0, sizeof(fheap_test_param_t)); + tparam.actual_id_len = HEAP_ID_LEN; /* Set appropriate testing parameters for each test */ switch(curr_test) { @@ -12460,6 +12544,10 @@ HDfprintf(stderr, "Uncomment tests!\n"); #ifndef QAK2 } /* end for */ } /* end for */ + + /* Reset deletion drain parameter */ + tparam.drain_half = FHEAP_DEL_DRAIN_ALL; + } /* end block */ #endif /* QAK2 */ #else /* QAK */ @@ -12478,18 +12566,48 @@ HDfprintf(stderr, "Uncomment tests!\n"); */ #ifndef QAK { - fheap_test_del_dir_t del_dir; /* Deletion direction */ + fheap_test_del_dir_t del_dir; /* Deletion direction */ + unsigned id_len; /* Length of heap IDs */ + + /* Test "normal" & "direct" storage of 'huge' heap IDs */ + for(id_len = 0; id_len < 2; id_len++) { + /* Set the ID length for this test */ + cparam.id_len = id_len; + + /* Print information about each test */ + switch(id_len) { + /* Use "normal" form for 'huge' object's heap IDs */ + case 0: + puts("Using 'normal' heap ID format for 'huge' objects"); + break; + + /* Use "direct" form for 'huge' object's heap IDs */ + case 1: + puts("Using 'direct' heap ID format for 'huge' objects"); + + /* Adjust actual length of heap IDs for directly storing 'huge' object's file offset & length in heap ID */ + tparam.actual_id_len = 17; /* 1 + 8 (address size) + 8 (length size) */ + break; + + /* An unknown test? */ + default: + goto error; + } /* end switch */ - /* More complex removal patterns */ - tparam.drain_half = FHEAP_DEL_DRAIN_ALL; - for(del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) { - tparam.del_dir = del_dir; + /* Try several different methods of deleting 'huge' objects */ + for(del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) { + tparam.del_dir = del_dir; - nerrors += test_huge_insert_one(fapl, &cparam, &tparam); - nerrors += test_huge_insert_two(fapl, &cparam, &tparam); - nerrors += test_huge_insert_three(fapl, &cparam, &tparam); - nerrors += test_huge_insert_mix(fapl, &cparam, &tparam); + nerrors += test_huge_insert_one(fapl, &cparam, &tparam); + nerrors += test_huge_insert_two(fapl, &cparam, &tparam); + nerrors += test_huge_insert_three(fapl, &cparam, &tparam); + nerrors += test_huge_insert_mix(fapl, &cparam, &tparam); + } /* end for */ } /* end for */ + + /* Reset the "normal" heap ID lengths */ + cparam.id_len = 0; + tparam.actual_id_len = HEAP_ID_LEN; } /* end block */ #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); -- cgit v0.12