summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-08-14 02:50:11 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-08-14 02:50:11 (GMT)
commit89f36d62b776ef955eed82a109b83a187ef115bb (patch)
tree4a8276f4a9ef5e614e9b829931d1094b9346e6d9
parentc4a5b8e16cdf66d1cf4b70587a6747f03557b2ef (diff)
downloadhdf5-89f36d62b776ef955eed82a109b83a187ef115bb.zip
hdf5-89f36d62b776ef955eed82a109b83a187ef115bb.tar.gz
hdf5-89f36d62b776ef955eed82a109b83a187ef115bb.tar.bz2
[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)
-rw-r--r--src/H5HF.c5
-rw-r--r--src/H5HFcache.c6
-rw-r--r--src/H5HFhdr.c116
-rw-r--r--src/H5HFhuge.c3
-rw-r--r--src/H5HFpkg.h14
-rw-r--r--src/H5HFprivate.h4
-rw-r--r--test/fheap.c184
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");