hdf5/test/fheap.c
Quincey Koziol 97e1ed4fc8
Refactor allocation of API context (#4942)
Since each API context is local to a thread, use the stack to
store the context instead of allocating & releasing it each time.
This improves performance (slightly), reduces alloc/free calls,
and eliminates the H5FL package from the push & pop operations,
which helps simplify threadsafe operation.

One effect of this change is that the H5VLstart_lib_state /
H5VLfinish_lib_state API routines for pass through connector
authors now require a parameter that can be used to store
the library's context. It was probably a mistake to assume
that these two routines would not do this previously, so this
is essentially a bug fix for them.

Some other minor things:

 * Added API context push+pop operations to cache tests
  (I'm not actually certain why this was working before) and
  a few other places
* Cleaned up a bunch of warnings in test code (calloc args, mainly)
* Made header file inclusions more standard in some source files
2024-10-24 10:09:22 -07:00

16560 lines
586 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the LICENSE file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "h5test.h"
/*
* This file needs to access private datatypes from the H5HF package.
* This file also needs to access the fractal heap testing code.
*/
#define H5HF_FRIEND /*suppress error about including H5HFpkg */
#define H5HF_TESTING
#include "H5HFpkg.h" /* Fractal heaps */
#define H5F_FRIEND /*suppress error about including H5Fpkg */
#define H5F_TESTING
#include "H5Fpkg.h"
/* Other private headers that this test requires */
#include "H5CXprivate.h" /* API Contexts */
#include "H5MMprivate.h" /* Memory management */
#include "H5VLprivate.h" /* Virtual Object Layer */
#include "H5VMprivate.h" /* Vectors and arrays */
/* Max. testfile name length */
#define FHEAP_FILENAME_LEN 1024
/* Object size macros */
#define SMALL_OBJ_SIZE1 10
#define SMALL_OBJ_SIZE2 20
#define NUM_FILL_OBJS 11
/* "Small" heap creation parameters */
#define SMALL_DBLOCK_OVERHEAD 21 /* Overhead for direct blocks */
#define SMALL_CHECKSUM_DBLOCKS true /* Whether to checksum direct blocks */
#define SMALL_MAN_WIDTH 4 /* Managed obj. table width */
#define SMALL_MAN_START_BLOCK_SIZE 512 /* Managed obj. starting block size */
#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 */
/* "Large" heap creation parameters */
#define LARGE_DBLOCK_OVERHEAD 21 /* Overhead for direct blocks */
/* (coincidentally the same size as for small direct blocks) */
#define LARGE_CHECKSUM_DBLOCKS false /* Whether to checksum direct blocks */
#define LARGE_MAN_WIDTH 32 /* Managed obj. table width */
#define LARGE_MAN_START_BLOCK_SIZE 4096 /* Managed obj. starting block size */
#define LARGE_MAN_MAX_DIRECT_SIZE (1024 * 1024) /* Managed obj. max. direct block size */
#define LARGE_MAN_MAX_INDEX 64 /* Managed obj. # of bits for total heap size */
#define LARGE_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */
#define LARGE_ID_LEN 0 /* "Default" heap ID length */
#define LARGE_STAND_SIZE (LARGE_MAN_MAX_DIRECT_SIZE - LARGE_DBLOCK_OVERHEAD) /* Standalone obj. min. size */
/* Define this macro to enable all insertion tests */
/* #define ALL_INSERT_TESTS */
/* Heap metadata macros */
#define MAX_HEAP_ID_LEN 64 /* Max. # of bytes to use for heap ID */
#define HEAP_ID_LEN 7 /* # of bytes to use for heap ID */
#define SMALL_HEAP_ID_LEN 7 /* # of bytes to use for "small" heap's IDs */
#define LARGE_HEAP_ID_LEN 12 /* # of bytes to use for "large" heap's IDs */
/* Max. # of rows in root indirect block */
#define HEAP_MAX_ROOT_ROWS(fh) H5HF_get_max_root_rows(fh)
/* Width of doubling table for heap */
#define DTABLE_WIDTH(fh) H5HF_get_dtable_width_test(fh)
/* Max. # of direct block rows in any indirect block */
#define DTABLE_MAX_DROWS(fh) H5HF_get_dtable_max_drows_test(fh)
/* Max. # of direct block rows in a indirect block */
#define IBLOCK_MAX_DROWS(fh, pos) H5HF_get_iblock_max_drows_test(fh, pos)
/* Size of a direct block in a given row */
#define DBLOCK_SIZE(fh, r) H5HF_get_dblock_size_test(fh, r)
/* Free space in a direct block of a given row */
#define DBLOCK_FREE(fh, r) H5HF_get_dblock_free_test(fh, r)
/* The number of settings for testing: page buffering, file space strategy and persisting free-space */
#define NUM_PB_FS 6
#define PAGE_BUFFER_PAGE_SIZE 4096
static const char *FILENAME[] = {"fheap", NULL};
/* Types of tests to perform */
typedef enum {
FHEAP_TEST_NORMAL, /* "Normal" test, with no testing parameters set */
FHEAP_TEST_REOPEN, /* Set the reopen_heap flag */
FHEAP_TEST_NTESTS /* The number of test types, must be last */
} fheap_test_type_t;
/* Order to delete objects */
typedef enum {
FHEAP_DEL_FORWARD, /* Delete objects from 0 -> nobjs */
FHEAP_DEL_REVERSE, /* Delete objects from nobjs -> 0 */
FHEAP_DEL_HEAP, /* Delete entire heap at once */
FHEAP_DEL_NDIRS /* The number of different deletion orders, must be last */
} fheap_test_del_dir_t;
/* Order to delete objects */
typedef enum {
FHEAP_DEL_DRAIN_ALL, /* Don't drain half of objects first */
FHEAP_DEL_DRAIN_HALF, /* Don't drain half of objects first */
FHEAP_DEL_DRAIN_N /* The number of different ways to drain, must be last */
} fheap_test_del_drain_t;
/* Size of objects for "bulk" filling heap blocks */
typedef enum {
FHEAP_TEST_FILL_LARGE, /* Fill heap blocks with "large" objects */
FHEAP_TEST_FILL_SINGLE, /* Fill heap blocks with single object */
FHEAP_TEST_FILL_N /* The number of different ways to test filling heap blocks, must be last */
} fheap_test_fill_t;
/* Whether to compress blocks (during random tests) */
typedef enum {
FHEAP_TEST_NO_COMPRESS, /* Don't compress direct blocks */
FHEAP_TEST_COMPRESS, /* Compress direct blocks */
FHEAP_TEST_COMP_N /* The number of different ways to test compressing heap blocks, must be last */
} fheap_test_comp_t;
/* Testing parameters */
typedef struct fheap_test_param_t {
fheap_test_type_t reopen_heap; /* Whether to re-open the heap during the test */
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 */
size_t actual_id_len; /* The actual length of heap IDs for a test */
fheap_test_comp_t comp; /* Whether to compress the blocks or not */
hid_t my_fcpl; /* File creation property list with file space strategy setting */
} fheap_test_param_t;
/* Heap state information */
typedef struct fheap_heap_state_t {
size_t man_nobjs; /* # of managed objects within heap */
hsize_t man_size; /* Size of managed object heap */
hsize_t man_alloc_size; /* Size of managed object heap allocated */
hsize_t man_free_space; /* Managed object free space within heap */
size_t huge_nobjs; /* # of 'huge' objects within heap */
hsize_t huge_size; /* Size of 'huge' object heap */
size_t tiny_nobjs; /* # of 'tiny' objects within heap */
hsize_t tiny_size; /* Size of 'tiny' object heap */
} fheap_heap_state_t;
/* Heap IDs to retain */
typedef struct fheap_heap_ids_t {
size_t num_ids; /* # of heap IDs in array */
size_t alloc_ids; /* # of heap IDs allocated in array */
unsigned char *ids; /* Array of object heap IDs */
size_t *lens; /* Array of object lengths */
size_t *offs; /* Array of object offsets (in global shared write buffer) */
} fheap_heap_ids_t;
/* Local variables */
unsigned char *shared_wobj_g; /* Pointer to shared write buffer for objects */
unsigned char *shared_robj_g; /* Pointer to shared read buffer for objects */
size_t shared_obj_size_g; /* Size of shared objects */
unsigned char *shared_ids_g = NULL; /* Array of shared object heap IDs */
size_t *shared_lens_g = NULL; /* Array of shared object lengths */
size_t *shared_offs_g = NULL; /* Array of shared object offsets */
size_t shared_alloc_ids_g = 0; /* # of shared heap IDs allocated in array */
/* Local routines */
static int init_small_cparam(H5HF_create_t *cparam);
static int init_large_cparam(H5HF_create_t *cparam);
static int check_stats(const H5HF_t *fh, const fheap_heap_state_t *state);
static int del_objs(H5F_t *f, H5HF_t **fh, fheap_test_param_t *tparam, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids);
/*-------------------------------------------------------------------------
* Function: init_small_cparam
*
* Purpose: Initialize heap creation parameter structure with small
* settings
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
init_small_cparam(H5HF_create_t *cparam)
{
/* Wipe out background */
memset(cparam, 0, sizeof(H5HF_create_t));
/* General parameters */
cparam->id_len = SMALL_ID_LEN;
cparam->max_man_size = SMALL_STAND_SIZE;
cparam->checksum_dblocks = SMALL_CHECKSUM_DBLOCKS;
/* Managed object doubling-table parameters */
cparam->managed.width = SMALL_MAN_WIDTH;
cparam->managed.start_block_size = SMALL_MAN_START_BLOCK_SIZE;
cparam->managed.max_direct_size = SMALL_MAN_MAX_DIRECT_SIZE;
cparam->managed.max_index = SMALL_MAN_MAX_INDEX;
cparam->managed.start_root_rows = SMALL_MAN_START_ROOT_ROWS;
return (0);
} /* init_small_cparam() */
/*-------------------------------------------------------------------------
* Function: init_large_cparam
*
* Purpose: Initialize heap creation parameter structure with large
* settings
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
init_large_cparam(H5HF_create_t *cparam)
{
/* Wipe out background */
memset(cparam, 0, sizeof(H5HF_create_t));
/* General parameters */
cparam->id_len = LARGE_ID_LEN;
cparam->max_man_size = LARGE_STAND_SIZE;
cparam->checksum_dblocks = LARGE_CHECKSUM_DBLOCKS;
/* Managed object doubling-table parameters */
cparam->managed.width = LARGE_MAN_WIDTH;
cparam->managed.start_block_size = LARGE_MAN_START_BLOCK_SIZE;
cparam->managed.max_direct_size = LARGE_MAN_MAX_DIRECT_SIZE;
cparam->managed.max_index = LARGE_MAN_MAX_INDEX;
cparam->managed.start_root_rows = LARGE_MAN_START_ROOT_ROWS;
return (0);
} /* init_large_cparam() */
/*-------------------------------------------------------------------------
* Function: check_stats
*
* Purpose: Verify stats for a heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
check_stats(const H5HF_t *fh, const fheap_heap_state_t *state)
{
H5HF_stat_t heap_stats; /* Statistics about the heap */
/* Get statistics for heap and verify they are correct */
if (H5HF_stat_info(fh, &heap_stats) < 0)
FAIL_STACK_ERROR;
if (heap_stats.man_nobjs != state->man_nobjs) {
fprintf(stdout, "heap_stats.man_nobjs = %" PRIuHSIZE ", state->man_nobjs = %zu\n",
heap_stats.man_nobjs, state->man_nobjs);
TEST_ERROR;
} /* end if */
if (heap_stats.man_size != state->man_size) {
fprintf(stdout, "heap_stats.man_size = %" PRIuHSIZE ", state->man_size = %" PRIuHSIZE "\n",
heap_stats.man_size, state->man_size);
TEST_ERROR;
} /* end if */
if (heap_stats.man_alloc_size != state->man_alloc_size) {
fprintf(stdout,
"heap_stats.man_alloc_size = %" PRIuHSIZE ", state->man_alloc_size = %" PRIuHSIZE "\n",
heap_stats.man_alloc_size, state->man_alloc_size);
TEST_ERROR;
} /* end if */
if (heap_stats.man_free_space != state->man_free_space) {
fprintf(stdout,
"heap_stats.man_free_space = %" PRIuHSIZE ", state->man_free_space = %" PRIuHSIZE "\n",
heap_stats.man_free_space, state->man_free_space);
TEST_ERROR;
} /* end if */
if (heap_stats.huge_nobjs != state->huge_nobjs) {
fprintf(stdout, "heap_stats.huge_nobjs = %" PRIuHSIZE ", state->huge_nobjs = %zu\n",
heap_stats.huge_nobjs, state->huge_nobjs);
TEST_ERROR;
} /* end if */
if (heap_stats.huge_size != state->huge_size) {
fprintf(stdout, "heap_stats.huge_size = %" PRIuHSIZE ", state->huge_size = %" PRIuHSIZE "\n",
heap_stats.huge_size, state->huge_size);
TEST_ERROR;
} /* end if */
if (heap_stats.tiny_nobjs != state->tiny_nobjs) {
fprintf(stdout, "heap_stats.tiny_nobjs = %" PRIuHSIZE ", state->tiny_nobjs = %zu\n",
heap_stats.tiny_nobjs, state->tiny_nobjs);
TEST_ERROR;
} /* end if */
if (heap_stats.tiny_size != state->tiny_size) {
fprintf(stdout, "heap_stats.tiny_size = %" PRIuHSIZE ", state->tiny_size = %" PRIuHSIZE "\n",
heap_stats.tiny_size, state->tiny_size);
TEST_ERROR;
} /* end if */
/* All tests passed */
return (0);
error:
return (1);
} /* check_stats() */
/*-------------------------------------------------------------------------
* Function: op_memcpy
*
* Purpose: Perform 'memcpy' for an object
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static herr_t
op_memcpy(const void *obj, size_t obj_len, void *op_data)
{
/* Make copy of the object */
memcpy(op_data, obj, obj_len);
return (SUCCEED);
} /* op_memcpy() */
/*-------------------------------------------------------------------------
* Function: add_obj
*
* Purpose: Add an object to heap
*
* Note: The following fields in the 'state' structure are set to
* the values expected _after_ any block created for the object:
* man_size
* man_alloc_size
* man_free_space
*
* The following fields in the 'state' structure are set to
* the current state, before any block has been created:
* nobjs
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
add_obj(H5HF_t *fh, size_t obj_off, size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids)
{
unsigned char heap_id[MAX_HEAP_ID_LEN]; /* Heap ID for object inserted */
unsigned char *obj; /* Buffer for object to insert */
size_t id_len; /* Size of fractal heap IDs */
size_t robj_size; /* Object size read in */
/* Sanity check */
assert(fh);
/* Initialize object buffer */
obj = &shared_wobj_g[obj_off];
/* Get information about heap ID lengths */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > MAX_HEAP_ID_LEN)
TEST_ERROR;
/* Insert object */
memset(heap_id, 0, id_len);
if (H5HF_insert(fh, obj_size, obj, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for tracking the heap's state */
if (state) {
size_t tiny_max_len; /* Max. length of tiny objects */
bool tiny_len_extended; /* Do tiny objects use two bytes for the length? */
/* Check information about tiny objects */
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
/* Adjust state of heap */
if (obj_size <= tiny_max_len) {
state->tiny_nobjs++;
state->tiny_size += obj_size;
} /* end if */
else {
state->man_nobjs++;
state->man_free_space -= obj_size;
} /* end else */
/* Check free space left in heap */
if (check_stats(fh, state))
TEST_ERROR;
} /* end if */
/* Read in object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(obj, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* If the heap IDs are to be retained, append them to the list */
if (keep_ids) {
/* Check for needing to increase size of heap ID array */
if (keep_ids->num_ids + 1 > keep_ids->alloc_ids) {
unsigned char *tmp_ids;
size_t *tmp_lens;
size_t *tmp_offs;
keep_ids->alloc_ids = MAX(1024, (keep_ids->alloc_ids * 2));
if (NULL ==
(tmp_ids = (unsigned char *)H5MM_realloc(keep_ids->ids, id_len * keep_ids->alloc_ids)))
TEST_ERROR;
keep_ids->ids = tmp_ids;
if (NULL ==
(tmp_lens = (size_t *)H5MM_realloc(keep_ids->lens, sizeof(size_t) * keep_ids->alloc_ids)))
TEST_ERROR;
keep_ids->lens = tmp_lens;
if (NULL ==
(tmp_offs = (size_t *)H5MM_realloc(keep_ids->offs, sizeof(size_t) * keep_ids->alloc_ids)))
TEST_ERROR;
keep_ids->offs = tmp_offs;
} /* end if */
/* Append the object info onto the array */
memcpy(&keep_ids->ids[keep_ids->num_ids * id_len], heap_id, id_len);
keep_ids->lens[keep_ids->num_ids] = obj_size;
keep_ids->offs[keep_ids->num_ids] = obj_off;
/* Increment the number of IDs kept */
keep_ids->num_ids++;
} /* end if */
/* Operations succeeded */
return (0);
error:
return (1);
} /* add_obj() */
/* Return a string describing the kind of deletion to perform. */
static const char *
get_del_string(const fheap_test_param_t *tparam)
{
/* Remove half of total objects from heap */
if (tparam->del_dir == FHEAP_DEL_FORWARD)
if (tparam->drain_half == FHEAP_DEL_DRAIN_ALL)
return "(all - forward)";
else
return "(half, refill, all - forward)";
else if (tparam->del_dir == FHEAP_DEL_REVERSE)
if (tparam->drain_half == FHEAP_DEL_DRAIN_ALL)
return "(all - reverse)";
else
return "(half, refill, all - reverse)";
else
return "(all - deleting heap)";
} /* get_del_string() */
/*-------------------------------------------------------------------------
* Function: get_fill_size
*
* Purpose: Retrieve the size of objects to "bulk" fill blocks with
*
* Return: Size of object to pass down to "fill_heap" routine on
* success/can't fail
*
*-------------------------------------------------------------------------
*/
H5_ATTR_PURE static size_t
get_fill_size(const fheap_test_param_t *tparam)
{
switch (tparam->fill) {
case FHEAP_TEST_FILL_LARGE:
return ((size_t)(-1));
case FHEAP_TEST_FILL_SINGLE:
return ((size_t)0);
case FHEAP_TEST_FILL_N:
default:
assert(0 && "Unknown bulk fill type?!?");
} /* end switch */
return (0);
} /* get_fill_size() */
/*-------------------------------------------------------------------------
* Function: begin_test
*
* Purpose: Perform common "test being" operations
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
begin_test(fheap_test_param_t *tparam, const char *base_desc, fheap_heap_ids_t *keep_ids, size_t *fill_size)
{
char *test_desc; /* Test description */
const char *del_str = get_del_string(tparam);
/*
* Test filling & removing all (small) objects from root direct block of absolute heap
*/
size_t test_desc_len = strlen(base_desc) + sizeof(" ") + strlen(del_str);
test_desc = H5MM_malloc(test_desc_len);
(void)snprintf(test_desc, test_desc_len, "%s %s", base_desc, del_str);
TESTING(test_desc);
H5MM_xfree(test_desc);
/* Initialize the heap ID structure */
memset(keep_ids, 0, sizeof(fheap_heap_ids_t));
/* Retrieve "bulk" filling object size */
if (fill_size)
*fill_size = get_fill_size(tparam);
/* Success */
return (0);
} /* end begin_test() */
/*-------------------------------------------------------------------------
* Function: reopen_file
*
* Purpose: Perform common "re-open" operations on file & heap for testing
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
reopen_file(hid_t *file, H5F_t **f, const char *filename, hid_t fapl, H5HF_t **fh, haddr_t fh_addr,
const fheap_test_param_t *tparam)
{
/* Check for closing & re-opening the heap */
/* (actually will close & re-open the file as well) */
if (tparam->reopen_heap) {
/* Close heap */
if (H5HF_close(*fh) < 0)
FAIL_STACK_ERROR;
*fh = NULL;
/* Close file */
if (H5Fclose(*file) < 0)
FAIL_STACK_ERROR;
*file = (-1);
*f = NULL;
/* Re-open the file */
if ((*file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (*f = (H5F_t *)H5VL_object(*file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(*f) < 0)
FAIL_STACK_ERROR;
/* Re-open heap */
if (NULL == (*fh = H5HF_open(*f, fh_addr)))
FAIL_STACK_ERROR;
} /* end if */
/* Success */
return (0);
error:
return (-1);
} /* end reopen_file() */
/*-------------------------------------------------------------------------
* Function: open_heap
*
* Purpose: Perform common "open" operations on file & heap for testing
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
open_heap(char *filename, hid_t fapl, const H5HF_create_t *cparam, const fheap_test_param_t *tparam,
hid_t *file, H5F_t **f, H5HF_t **fh, haddr_t *fh_addr, fheap_heap_state_t *state,
h5_stat_size_t *empty_size)
{
size_t id_len; /* Size of fractal heap IDs */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, (size_t)FHEAP_FILENAME_LEN);
/* Create the file to work on */
if ((*file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Check for deleting the entire heap */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Get a pointer to the internal file object */
if (NULL == (*f = (H5F_t *)H5VL_object(*file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(*f) < 0)
FAIL_STACK_ERROR;
/* Create absolute heap */
if (NULL == (*fh = H5HF_create(*f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(*fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > tparam->actual_id_len)
TEST_ERROR;
if (H5HF_get_heap_addr(*fh, fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(*fh_addr))
TEST_ERROR;
memset(state, 0, sizeof(fheap_heap_state_t));
if (check_stats(*fh, state))
TEST_ERROR;
/* Prepare for querying the size of a file with an empty heap */
/* Close (empty) heap */
if (H5HF_close(*fh) < 0)
FAIL_STACK_ERROR;
*fh = NULL;
} /* end if */
/* Close file */
if (H5Fclose(*file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((*empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((*file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (*f = (H5F_t *)H5VL_object(*file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(*f) < 0)
FAIL_STACK_ERROR;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Create absolute heap */
if (NULL == (*fh = H5HF_create(*f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(*fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > tparam->actual_id_len)
TEST_ERROR;
if (H5HF_get_heap_addr(*fh, fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(*fh_addr))
TEST_ERROR;
memset(state, 0, sizeof(fheap_heap_state_t));
if (check_stats(*fh, state))
TEST_ERROR;
} /* end if */
else {
/* Re-open heap */
if (NULL == (*fh = H5HF_open(*f, *fh_addr)))
FAIL_STACK_ERROR;
} /* end else */
/* Success */
return (0);
error:
return (-1);
} /* end open_heap() */
/*-------------------------------------------------------------------------
* Function: reopen_heap
*
* Purpose: Perform common "re-open" operations on heap for testing
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
reopen_heap(H5F_t *f, H5HF_t **fh, haddr_t fh_addr, const fheap_test_param_t *tparam)
{
/* Check for closing & re-opening the heap */
if (tparam->reopen_heap) {
/* Close (empty) heap */
if (H5HF_close(*fh) < 0)
FAIL_STACK_ERROR;
*fh = NULL;
/* Re-open heap */
if (NULL == (*fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
} /* end if */
/* Success */
return 0;
error:
return -1;
} /* end reopen_heap() */
/*-------------------------------------------------------------------------
* Function: close_heap
*
* Purpose: Perform common "close" operations on file & heap for testing
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
close_heap(char *filename, hid_t fapl, fheap_test_param_t *tparam, hid_t file, H5F_t *f, H5HF_t **fh,
haddr_t fh_addr, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids, h5_stat_size_t empty_size)
{
h5_stat_size_t file_size; /* Size of file currently */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
if (check_stats(*fh, state))
TEST_ERROR;
/* Check for deleting the objects in the heap */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Delete objects inserted (either forward or reverse order) */
if (del_objs(f, fh, tparam, state, keep_ids))
FAIL_STACK_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(*fh) < 0)
FAIL_STACK_ERROR;
*fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* Success */
return (0);
error:
return (-1);
} /* end close_heap() */
/*-------------------------------------------------------------------------
* Function: del_objs_half_refill
*
* Purpose: Remove half of objects from heap and refill
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
del_objs_half_refill(H5F_t *f, H5HF_t **fh, fheap_test_param_t *tparam, fheap_heap_ids_t *keep_ids)
{
unsigned char *wobj; /* Buffer for object to insert */
haddr_t fh_addr = HADDR_UNDEF; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t half_nobjs; /* Half of total # of objects */
size_t obj_idx; /* Index of the object to remove */
size_t u; /* Local index variable */
/* Sanity check */
assert(fh);
assert(*fh);
assert(keep_ids);
/* Check for closing & re-opening the heap */
if (tparam->reopen_heap) {
if (H5HF_get_heap_addr(*fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
} /* end if */
/* Get information about heap ID lengths */
if (H5HF_get_id_len(*fh, &id_len) < 0)
FAIL_STACK_ERROR;
/* Remove half of total objects from heap */
if (tparam->del_dir == FHEAP_DEL_FORWARD)
obj_idx = 0;
else
obj_idx = keep_ids->num_ids - 1;
half_nobjs = keep_ids->num_ids / 2;
for (u = 0; u < half_nobjs; u++) {
/* Remove object from heap */
if (H5HF_remove(*fh, &keep_ids->ids[id_len * obj_idx]) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Adjust index of object to delete next */
if (tparam->del_dir == FHEAP_DEL_FORWARD)
obj_idx++;
else
obj_idx--;
} /* end for */
/* Re-insert half of total objects back into heap */
if (tparam->del_dir == FHEAP_DEL_FORWARD)
obj_idx = 0;
else
obj_idx = keep_ids->num_ids - 1;
for (u = 0; u < half_nobjs; u++) {
/* Re-insert object */
wobj = &shared_wobj_g[keep_ids->offs[obj_idx]];
if (H5HF_insert(*fh, keep_ids->lens[obj_idx], wobj, &keep_ids->ids[id_len * obj_idx]) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Adjust index of object to delete next */
if (tparam->del_dir == FHEAP_DEL_FORWARD)
obj_idx++;
else
obj_idx--;
} /* end for */
/* Operations succeeded */
return (0);
error:
return (1);
} /* del_objs_half_refill() */
/*-------------------------------------------------------------------------
* Function: del_objs
*
* Purpose: Remove objects from heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
del_objs(H5F_t *f, H5HF_t **fh, fheap_test_param_t *tparam, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
haddr_t fh_addr = HADDR_UNDEF; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t obj_idx; /* Index of the object to remove */
size_t u; /* Local index variable */
/* Sanity check */
assert(fh);
assert(*fh);
assert(state);
assert(keep_ids);
/* Check for first deleting half of objects & then re-inserting them */
if (tparam->drain_half == FHEAP_DEL_DRAIN_HALF)
if (del_objs_half_refill(f, fh, tparam, keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (tparam->reopen_heap) {
if (H5HF_get_heap_addr(*fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
} /* end if */
/* Get information about heap ID lengths */
if (H5HF_get_id_len(*fh, &id_len) < 0)
FAIL_STACK_ERROR;
/* Remove all objects from heap */
if (tparam->del_dir == FHEAP_DEL_FORWARD)
obj_idx = 0;
else
obj_idx = keep_ids->num_ids - 1;
for (u = 0; u < keep_ids->num_ids; u++) {
/* Remove object from heap */
if (H5HF_remove(*fh, &keep_ids->ids[id_len * obj_idx]) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Adjust index of object to delete next */
if (tparam->del_dir == FHEAP_DEL_FORWARD)
obj_idx++;
else
obj_idx--;
} /* end for */
/* Heap should be completely empty now, reset our state */
memset(state, 0, sizeof(fheap_heap_state_t));
/* Check up on heap... */
if (check_stats(*fh, state))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* del_objs() */
/*-------------------------------------------------------------------------
* Function: fill_heap
*
* Purpose: Insert (small) objects to fill up the free space in a heap block
*
* Note: The following fields in the 'state' structure are set to
* the values expected _after_ the block has been created:
* man_size
* man_alloc_size
* man_free_space
*
* The following fields in the 'state' structure are set to
* the current state, before the block has been created:
* nobjs
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_heap(H5HF_t *fh, unsigned block_row, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
unsigned char *wobj; /* Buffer for object to insert */
unsigned char *curr_id_ptr; /* Pointer into shared ID array */
size_t *curr_len_ptr; /* Pointer into shared length array */
size_t *curr_off_ptr; /* Pointer into shared offset array */
size_t num_ids = 0; /* # of heap IDs in array */
size_t data_size; /* Size of data portion of heap block */
size_t last_obj_len; /* Size of last object inserted into heap */
size_t obj_off; /* Offset of object in shared write buffer */
size_t id_len; /* Size of fractal heap IDs */
unsigned u; /* Local index variable */
/* Sanity check */
assert(fh);
assert(state);
assert(obj_size + 256 < shared_obj_size_g);
/* Initialize starting information */
data_size = (size_t)DBLOCK_FREE(fh, block_row);
wobj = shared_wobj_g;
curr_id_ptr = shared_ids_g;
curr_len_ptr = shared_lens_g;
curr_off_ptr = shared_offs_g;
obj_off = 0;
/* Get information about heap ID lengths */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
/* Check for some "magic" object sizes */
if (obj_size == 0)
obj_size = data_size;
else if (obj_size == (size_t)(-1))
obj_size = (data_size / NUM_FILL_OBJS) + 1;
/* Loop over inserting objects into the root direct block, until there's no more space */
while (data_size >= obj_size) {
/* Increment object count */
num_ids++;
/* Check for needing to increase size of heap ID array */
if (num_ids > shared_alloc_ids_g) {
shared_alloc_ids_g = MAX(1024, (shared_alloc_ids_g * 2));
if (NULL ==
(shared_ids_g = (unsigned char *)H5MM_realloc(shared_ids_g, id_len * shared_alloc_ids_g)))
TEST_ERROR;
if (NULL ==
(shared_lens_g = (size_t *)H5MM_realloc(shared_lens_g, sizeof(size_t) * shared_alloc_ids_g)))
TEST_ERROR;
if (NULL ==
(shared_offs_g = (size_t *)H5MM_realloc(shared_offs_g, sizeof(size_t) * shared_alloc_ids_g)))
TEST_ERROR;
curr_id_ptr = &shared_ids_g[(num_ids - 1) * id_len];
curr_len_ptr = &shared_lens_g[(num_ids - 1)];
curr_off_ptr = &shared_offs_g[(num_ids - 1)];
} /* end if */
/* Insert object */
if (H5HF_insert(fh, obj_size, wobj, curr_id_ptr) < 0)
FAIL_STACK_ERROR;
*curr_len_ptr = obj_size;
*curr_off_ptr = obj_off;
/* Adjust state of heap */
state->man_nobjs++;
state->man_free_space -= obj_size;
/* Check stats for heap */
if (check_stats(fh, state))
TEST_ERROR;
/* Adjust object & ID pointers */
wobj++;
obj_off++;
if (obj_off > 255) {
wobj = shared_wobj_g;
obj_off = 0;
} /* end if */
curr_id_ptr += id_len;
curr_len_ptr++;
curr_off_ptr++;
/* Decrement space left in block */
data_size -= obj_size;
} /* end while */
/* Check for adding smaller last object to heap block */
if (data_size > 0) {
/* Set size of last object in block */
last_obj_len = data_size;
/* Increment object count */
num_ids++;
/* Check for needing to increase size of heap ID array */
if (num_ids > shared_alloc_ids_g) {
shared_alloc_ids_g = MAX(1024, (shared_alloc_ids_g * 2));
if (NULL ==
(shared_ids_g = (unsigned char *)H5MM_realloc(shared_ids_g, id_len * shared_alloc_ids_g)))
TEST_ERROR;
if (NULL ==
(shared_lens_g = (size_t *)H5MM_realloc(shared_lens_g, sizeof(size_t) * shared_alloc_ids_g)))
TEST_ERROR;
if (NULL ==
(shared_offs_g = (size_t *)H5MM_realloc(shared_offs_g, sizeof(size_t) * shared_alloc_ids_g)))
TEST_ERROR;
curr_id_ptr = &shared_ids_g[(num_ids - 1) * id_len];
curr_len_ptr = &shared_lens_g[(num_ids - 1)];
curr_off_ptr = &shared_offs_g[(num_ids - 1)];
} /* end if */
/* Insert last object into the heap, using the remaining free space */
if (H5HF_insert(fh, last_obj_len, wobj, curr_id_ptr) < 0)
FAIL_STACK_ERROR;
*curr_len_ptr = last_obj_len;
*curr_off_ptr = obj_off;
/* Adjust state of heap */
state->man_nobjs++;
state->man_free_space -= last_obj_len;
/* Verify that the heap is full */
if (check_stats(fh, state))
TEST_ERROR;
} /* end if */
else
last_obj_len = obj_size; /* Normal sized last object */
/* Verify reading the objects written out */
/* Verify all the objects */
wobj = shared_wobj_g;
curr_id_ptr = shared_ids_g;
curr_len_ptr = shared_lens_g;
curr_off_ptr = shared_offs_g;
for (u = 0; u < num_ids; u++) {
/* Read in object */
if (H5HF_read(fh, curr_id_ptr, shared_robj_g) < 0)
FAIL_STACK_ERROR;
/* Check that object is correct */
wobj = &shared_wobj_g[*curr_off_ptr];
if (memcmp(wobj, shared_robj_g, *curr_len_ptr) != 0)
TEST_ERROR;
/* Adjust object & ID pointers */
curr_id_ptr += id_len;
curr_len_ptr++;
curr_off_ptr++;
} /* end for */
/* If the heap IDs are to be retained, append them to the list */
if (keep_ids) {
/* Check for needing to increase size of heap ID array */
if (keep_ids->num_ids + num_ids > keep_ids->alloc_ids) {
keep_ids->alloc_ids = MAX(1024, (keep_ids->alloc_ids * 2));
if (NULL ==
(keep_ids->ids = (unsigned char *)H5MM_realloc(keep_ids->ids, id_len * keep_ids->alloc_ids)))
TEST_ERROR;
if (NULL == (keep_ids->lens =
(size_t *)H5MM_realloc(keep_ids->lens, sizeof(size_t) * keep_ids->alloc_ids)))
TEST_ERROR;
if (NULL == (keep_ids->offs =
(size_t *)H5MM_realloc(keep_ids->offs, sizeof(size_t) * keep_ids->alloc_ids)))
TEST_ERROR;
} /* end if */
/* Append the IDs onto the array */
memcpy(&keep_ids->ids[keep_ids->num_ids * id_len], shared_ids_g, (num_ids * id_len));
memcpy(&keep_ids->lens[keep_ids->num_ids], shared_lens_g, (num_ids * sizeof(size_t)));
memcpy(&keep_ids->offs[keep_ids->num_ids], shared_offs_g, (num_ids * sizeof(size_t)));
/* Increment the number of IDs kept */
keep_ids->num_ids += num_ids;
} /* end if */
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_heap() */
/*-------------------------------------------------------------------------
* Function: fill_root_row
*
* Purpose: Fill up a row of direct blocks in the root indirect block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_root_row(H5HF_t *fh, unsigned row, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
hsize_t first_free_space; /* Size of free space in heap after the first block */
hsize_t all_free_space; /* Size of free space in heap after all blocks */
hsize_t first_heap_size; /* Total size of the heap after the first block */
hsize_t all_heap_size; /* Total size of the heap after all blocks */
size_t block_size; /* Block size for row */
size_t block_free; /* Free space in empty block of this row */
unsigned width; /* Width of heap's doubling table */
unsigned expand_rows; /* # of rows to expand heap by */
unsigned u; /* Local index variable */
/* Sanity check */
assert(fh);
assert(state);
/* Get some information for the heap */
block_size = (size_t)DBLOCK_SIZE(fh, row);
block_free = (size_t)DBLOCK_FREE(fh, row);
width = DTABLE_WIDTH(fh);
/* Compute the number of rows to expand heap by */
if (row < 2)
expand_rows = 1;
else if (POWER_OF_TWO(row))
expand_rows = row;
else
expand_rows = 0;
/* Compute first block & all blocks heap size & free space */
if (state->man_size == 0) {
first_heap_size = block_size;
first_free_space = block_free;
all_heap_size = width * block_size;
all_free_space = (width - 1) * block_free;
} /* end if */
else if (expand_rows == 0) {
all_heap_size = state->man_size;
all_free_space = state->man_free_space;
first_heap_size = all_heap_size;
first_free_space = all_free_space;
all_free_space -= block_free; /* Account for shift from first free space */
} /* end if */
else {
all_heap_size = state->man_size;
all_free_space = 0;
for (u = 0; u < expand_rows; u++) {
all_heap_size += width * DBLOCK_SIZE(fh, row + u);
all_free_space += width * DBLOCK_FREE(fh, row + u);
} /* end for */
first_heap_size = all_heap_size;
first_free_space = all_free_space;
all_free_space -= block_free; /* Account for shift from first free space */
} /* end else */
/* Loop over filling direct blocks, until root indirect row is full */
state->man_size = first_heap_size;
state->man_free_space = first_free_space;
for (u = 0; u < width; u++) {
/* Set heap's size & free space correctly */
if (u == 1) {
state->man_size = all_heap_size;
state->man_free_space = all_free_space;
} /* end if */
/* Account for new block added */
state->man_alloc_size += block_size;
/* Fill a direct heap block up */
if (fill_heap(fh, row, obj_size, state, keep_ids))
TEST_ERROR;
} /* end for */
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_root_row() */
/*-------------------------------------------------------------------------
* Function: fill_partial row
*
* Purpose: Fill up part of a row of direct blocks in an non-root indirect block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_partial_row(H5HF_t *fh, unsigned row, unsigned width, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
size_t block_size; /* Size of direct block in this row */
unsigned u; /* Local index variable */
/* Sanity check */
assert(fh);
assert(state);
/* Get some information for the heap */
block_size = (size_t)DBLOCK_SIZE(fh, row);
/* Loop over filling direct blocks, until indirect row is full */
for (u = 0; u < width; u++) {
/* Adjust stats for new block */
state->man_alloc_size += block_size;
/* Fill a direct heap block up */
if (fill_heap(fh, row, obj_size, state, keep_ids))
TEST_ERROR;
} /* end for */
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_partial_row() */
/*-------------------------------------------------------------------------
* Function: fill_row
*
* Purpose: Fill up entire row of direct blocks in an non-root indirect block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_row(H5HF_t *fh, unsigned row, size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids)
{
/* Sanity check */
assert(fh);
assert(state);
/* Fill the entire row (with the partial row fill routine) */
if (fill_partial_row(fh, row, DTABLE_WIDTH(fh), obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_row() */
/*-------------------------------------------------------------------------
* Function: fill_root_direct
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in the root indirect block
* (Generally used to create & fill up direct blocks in a new
* indirect block)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_root_direct(H5HF_t *fh, size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids)
{
unsigned max_dblock_rows; /* Max. # of direct block rows in indirect block */
unsigned row; /* Row being created */
/* Get heap info */
max_dblock_rows = DTABLE_MAX_DROWS(fh);
assert(max_dblock_rows);
/* Loop over rows */
for (row = 0; row < max_dblock_rows; row++)
if (fill_root_row(fh, row, obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_root_direct() */
/*-------------------------------------------------------------------------
* Function: fill_2nd_indirect
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in a second-level indirect block (which only has
* direct blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_2nd_indirect(H5HF_t *fh, unsigned pos, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
unsigned max_dblock_rows; /* Max. # of direct block rows in indirect block */
unsigned row; /* Current row to create */
/* Get some information for the heap */
max_dblock_rows = IBLOCK_MAX_DROWS(fh, pos);
assert(max_dblock_rows);
/* Loop over rows */
for (row = 0; row < max_dblock_rows; row++)
if (fill_row(fh, row, obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_2nd_direct() */
/*-------------------------------------------------------------------------
* Function: fill_all_direct
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks up to the maximum direct block size
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_all_direct(H5HF_t *fh, size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids)
{
unsigned max_dblock_rows; /* Max. # of direct block rows in indirect block */
unsigned row; /* Row being created */
/* Get heap info */
max_dblock_rows = DTABLE_MAX_DROWS(fh);
assert(max_dblock_rows);
/* Loop over rows */
for (row = 0; row < max_dblock_rows; row++)
if (fill_row(fh, row, obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_all_direct() */
/*-------------------------------------------------------------------------
* Function: fill_2nd_indirect_row
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in a row of second-level indirect block (which only
* have direct blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_2nd_indirect_row(H5HF_t *fh, unsigned pos, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
unsigned width; /* Width of heap's doubling table */
unsigned u; /* Local index variable */
/* Get some information for the heap */
width = DTABLE_WIDTH(fh);
/* Loop over row of indirect blocks */
for (u = 0; u < width; u++)
if (fill_2nd_indirect(fh, pos, obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_2nd_direct_row() */
/*-------------------------------------------------------------------------
* Function: fill_all_2nd_indirect_rows
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in all rows of second-level indirect blocks (which only
* have direct blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_all_2nd_indirect_rows(H5HF_t *fh, size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids)
{
unsigned width; /* Width of heap's doubling table */
unsigned u; /* Local index variable */
/* Get some information for the heap */
width = DTABLE_WIDTH(fh);
/* Loop over rows of 2nd level deep indirect blocks */
for (u = 0; u < (H5VM_log2_of2(width) + 1); u++)
if (fill_2nd_indirect_row(fh, (u + 1), obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_2nd_direct_row() */
/*-------------------------------------------------------------------------
* Function: fill_3rd_indirect
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in a third-level indirect block (which
* has one more level of indirect blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_3rd_indirect(H5HF_t *fh, unsigned pos, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
unsigned u; /* Local index variable */
/* Fill all direct block rows in third level indirect block */
if (fill_all_direct(fh, obj_size, state, keep_ids))
TEST_ERROR;
/* Fill rows of recursive indirect blocks in third level indirect block */
for (u = 0; u < pos; u++)
if (fill_2nd_indirect_row(fh, (u + 1), obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_3rd_indirect() */
/*-------------------------------------------------------------------------
* Function: fill_3rd_indirect_row
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in a row of third-level indirect block (which
* have one more level of indirect blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_3rd_indirect_row(H5HF_t *fh, unsigned pos, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
unsigned width; /* Width of heap's doubling table */
unsigned u; /* Local index variable */
/* Get some information for the heap */
width = DTABLE_WIDTH(fh);
/* Loop over row of 3rd level indirect blocks */
for (u = 0; u < width; u++)
/* Fill third level indirect block */
if (fill_3rd_indirect(fh, pos, obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_3rd_direct_row() */
/*-------------------------------------------------------------------------
* Function: fill_all_3rd_indirect_rows
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in all rows of third-level indirect blocks (which
* have one more level of indirect blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_all_3rd_indirect_rows(H5HF_t *fh, size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids)
{
unsigned width; /* Width of heap's doubling table */
unsigned u; /* Local index variable */
/* Get some information for the heap */
width = DTABLE_WIDTH(fh);
/* Loop over rows of 3rd level deep indirect blocks */
for (u = 0; u < (H5VM_log2_of2(width) + 1); u++)
/* Fill row of 3rd level indirect blocks */
if (fill_3rd_indirect_row(fh, (u + 1), obj_size, state, keep_ids))
TEST_ERROR;
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_all_3rd_direct_rows() */
/*-------------------------------------------------------------------------
* Function: fill_4th_indirect_row
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in a row of fourth-level indirect blocks (which
* have two more levels of indirect blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_4th_indirect_row(H5HF_t *fh, unsigned pos, size_t obj_size, fheap_heap_state_t *state,
fheap_heap_ids_t *keep_ids)
{
unsigned width; /* Width of heap's doubling table */
unsigned u, v; /* Local index variables */
/* Get some information for the heap */
width = DTABLE_WIDTH(fh);
/* Loop over row of 4th level indirect blocks */
for (u = 0; u < width; u++) {
/* Fill all direct block rows in fourth level indirect block */
if (fill_all_direct(fh, obj_size, state, keep_ids))
TEST_ERROR;
/* Fill all rows of 2nd level deep indirect blocks in fourth level indirect block */
if (fill_all_2nd_indirect_rows(fh, obj_size, state, keep_ids))
TEST_ERROR;
/* Fill rows of third level indirect blocks in fourth level indirect block */
for (v = 0; v < pos; v++)
if (fill_3rd_indirect_row(fh, (v + 1), obj_size, state, keep_ids))
TEST_ERROR;
} /* end for */
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_4th_direct_row() */
/*-------------------------------------------------------------------------
* Function: fill_all_4th_indirect_rows
*
* Purpose: Insert (small) objects to fill up the free space in all direct
* heap blocks in all rows of fourth-level indirect blocks (which
* have two more levels of indirect blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
fill_all_4th_indirect_rows(H5HF_t *fh, size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids)
{
unsigned width; /* Width of heap's doubling table */
unsigned u; /* Local index variable */
/* Get some information for the heap */
width = DTABLE_WIDTH(fh);
/* Loop over rows of 4th level deep indirect blocks */
for (u = 0; u < (H5VM_log2_of2(width) + 1); u++) {
/* Fill row of 4th level indirect blocks */
if (fill_4th_indirect_row(fh, (u + 1), obj_size, state, keep_ids))
TEST_ERROR;
/* Account for root indirect block doubling # of rows again */
/* (From 16 rows to the max. # of rows: 22) */
/* (Note: this is tied to the particular doubling table/heap creation parameters) */
if (u == 0) {
unsigned max_root_rows; /* Maximum # of rows in root indirect block */
unsigned row; /* Row in heap */
/* Get some information for the heap */
max_root_rows = HEAP_MAX_ROOT_ROWS(fh);
/* Increase heap size & free space */
for (row = 16; row < max_root_rows; row++) {
state->man_size += width * DBLOCK_SIZE(fh, row);
state->man_free_space += width * DBLOCK_FREE(fh, row);
} /* end for */
} /* end if */
} /* end for */
/* Operations succeeded */
return (0);
error:
return (1);
} /* fill_all_4th_direct_rows() */
/*-------------------------------------------------------------------------
* Function: test_create
*
* Purpose: Create fractal heap
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_create(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_create_t test_cparam; /* Creation parameters for heap */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Heap address in file */
h5_stat_size_t empty_size; /* File size, w/o heap */
h5_stat_size_t file_size; /* File size, after deleting heap */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/*
* Test fractal heap creation
*/
TESTING("fractal heap creation");
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
TEST_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
PASSED();
/* Query the type of address mapping */
TESTING("query heap creation parameters");
memset(&test_cparam, 0, sizeof(H5HF_create_t));
if (H5HF_get_cparam_test(fh, &test_cparam) < 0)
FAIL_STACK_ERROR;
if (H5HF_cmp_cparam_test(cparam, &test_cparam))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return 1;
} /* test_create() */
/*-------------------------------------------------------------------------
* Function: test_reopen
*
* Purpose: Create & reopen a fractal heap
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_reopen(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_create_t test_cparam; /* Creation parameters for heap */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
h5_stat_size_t empty_size; /* File size, w/o heap */
h5_stat_size_t file_size; /* File size, after deleting heap */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
bool page = false; /* Paged aggregation strategy or not */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
if (f->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE)
page = true;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/*
* Display testing message
*/
TESTING("create, close & reopen fractal heap");
/* Create heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
TEST_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for closing & re-opening the file */
if (tparam->reopen_heap) {
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Query the creation parameters */
memset(&test_cparam, 0, sizeof(H5HF_create_t));
if (H5HF_get_cparam_test(fh, &test_cparam) < 0)
FAIL_STACK_ERROR;
if (H5HF_cmp_cparam_test(cparam, &test_cparam))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (!page || (page && !tparam->reopen_heap))
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_reopen() */
/*-------------------------------------------------------------------------
* Function: test_open_twice
*
* Purpose: Open a fractal heap twice
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_open_twice(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
hid_t file2 = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5F_t *f2 = NULL; /* Internal file object pointer */
H5HF_create_t test_cparam; /* Creation parameters for heap */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
H5HF_t *fh2 = NULL; /* 2nd fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
h5_stat_size_t empty_size; /* File size, w/o heap */
h5_stat_size_t file_size; /* File size, after deleting heap */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
bool page = false; /* Paged aggregation strategy or not */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
if (f->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE)
page = true;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/*
* Display testing message
*/
TESTING("open fractal heap twice");
/* Create heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
TEST_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
/* Open the heap again, through the first file handle */
if (NULL == (fh2 = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Verify the creation parameters */
memset(&test_cparam, 0, sizeof(H5HF_create_t));
if (H5HF_get_cparam_test(fh2, &test_cparam) < 0)
FAIL_STACK_ERROR;
if (H5HF_cmp_cparam_test(cparam, &test_cparam))
TEST_ERROR;
/* Close the second fractal heap wrapper */
if (H5HF_close(fh2) < 0)
FAIL_STACK_ERROR;
fh2 = NULL;
/* Check for closing & re-opening the heap & file */
if (reopen_file(&file, &f, filename, fapl, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file2 = H5Freopen(file)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f2 = (H5F_t *)H5VL_object(file2)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f2) < 0)
FAIL_STACK_ERROR;
/* Open the fractal heap through the second file handle */
if (NULL == (fh2 = H5HF_open(f2, fh_addr)))
FAIL_STACK_ERROR;
/* Verify the creation parameters */
memset(&test_cparam, 0, sizeof(H5HF_create_t));
if (H5HF_get_cparam_test(fh2, &test_cparam) < 0)
FAIL_STACK_ERROR;
if (H5HF_cmp_cparam_test(cparam, &test_cparam))
TEST_ERROR;
/* Close the first fractal heap wrapper */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the first file */
/* (close before second file, to detect error on internal heap header's
* shared file information)
*/
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Close the second fractal heap wrapper */
if (H5HF_close(fh2) < 0)
FAIL_STACK_ERROR;
fh2 = NULL;
/* Delete heap */
if (H5HF_delete(f2, fh_addr) < 0)
FAIL_STACK_ERROR;
/* Close the second file */
if (H5Fclose(file2) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (!page || (page && !tparam->reopen_heap))
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
if (fh2)
H5HF_close(fh2);
H5Fclose(file);
H5Fclose(file2);
}
H5E_END_TRY
return 1;
} /* test_open_twice() */
/*-------------------------------------------------------------------------
* Function: test_delete_open
*
* Purpose: Delete opened fractal heap (& open deleted heap)
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_delete_open(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_create_t test_cparam; /* Creation parameters for heap */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
H5HF_t *fh2 = NULL; /* 2nd fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/no heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Display test banner */
TESTING("deleting open fractal heap");
/* Create heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
TEST_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
/* Open the heap again */
if (NULL == (fh2 = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Request that the heap be deleted */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
/* Verify the creation parameters */
memset(&test_cparam, 0, sizeof(H5HF_create_t));
if (H5HF_get_cparam_test(fh2, &test_cparam) < 0)
FAIL_STACK_ERROR;
if (H5HF_cmp_cparam_test(cparam, &test_cparam))
TEST_ERROR;
/* Close the second fractal heap wrapper */
if (H5HF_close(fh2) < 0)
FAIL_STACK_ERROR;
fh2 = NULL;
/* Try re-opening the heap again (should fail, as heap will be deleted) */
H5E_BEGIN_TRY
{
fh2 = H5HF_open(f, fh_addr);
}
H5E_END_TRY
if (fh2) {
/* Close opened heap */
H5HF_close(fh2);
fh2 = NULL;
/* Indicate error */
TEST_ERROR;
} /* end if */
/* Close the first fractal heap wrapper */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for closing & re-opening the file */
if (tparam->reopen_heap) {
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Try re-opening the heap again (should fail, as heap is now deleted) */
H5E_BEGIN_TRY
{
fh = H5HF_open(f, fh_addr);
}
H5E_END_TRY
if (fh) {
/* Close opened heap */
H5HF_close(fh);
fh = NULL;
/* Indicate error */
TEST_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
if (fh2)
H5HF_close(fh2);
H5Fclose(file);
}
H5E_END_TRY
return 1;
} /* test_delete_open() */
/*-------------------------------------------------------------------------
* Function: test_id_limits
*
* Purpose: Test limits for heap ID lengths
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_id_limits(hid_t fapl, H5HF_create_t *cparam, hid_t fcpl)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
unsigned deflate_level; /* Deflation level */
size_t id_len; /* Size of fractal heap IDs */
size_t tiny_max_len; /* Max. length of tiny objects */
bool tiny_len_extended; /* Do tiny objects use two bytes for the length? */
bool huge_ids_direct; /* Are 'huge' objects directly accessed? */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Display testing message */
TESTING("limits of heap ID lengths");
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Set the 'default' heap ID length */
tmp_cparam.id_len = 0;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != (HEAP_ID_LEN - 1))
TEST_ERROR;
if (tiny_len_extended != false)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != false)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Set the heap ID length to the size needed for directly accessing 'huge' objects */
/* (with no I/O pipeline filters) */
tmp_cparam.id_len = 1;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != 17)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != 16)
TEST_ERROR;
if (tiny_len_extended != false)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != true)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Set the heap ID length to the size needed for directly accessing 'huge' objects */
/* (with I/O pipeline filters) */
tmp_cparam.id_len = 1;
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
FAIL_STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != 29)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != 27)
TEST_ERROR;
if (tiny_len_extended != true)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != true)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Release the I/O pipeline filter information */
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline);
/* Set the heap ID length to a size that's too small for 'managed' heap IDs */
tmp_cparam.id_len = 3;
/* Create absolute heap */
H5E_BEGIN_TRY
{
fh = H5HF_create(f, &tmp_cparam);
}
H5E_END_TRY
if (NULL != fh)
FAIL_STACK_ERROR;
/* Set the heap ID length a size that's large enough for 'tiny' & 'managed'
* objects, but too small for directly accessing 'huge' objects
*/
tmp_cparam.id_len = 8;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != 8)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != 7)
TEST_ERROR;
if (tiny_len_extended != false)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != false)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Set the heap ID length a size that's large enough for directly
* directly accessing 'huge' objects
*/
tmp_cparam.id_len = 17;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != 17)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != 16)
TEST_ERROR;
if (tiny_len_extended != false)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != true)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Set the heap ID length to the low side of the boundary condition for
* encoding 'tiny' objects in one byte
*/
tmp_cparam.id_len = 18;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != 18)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != 16)
TEST_ERROR;
if (tiny_len_extended != false)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != true)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Set the heap ID length to the high side of the boundary condition for
* encoding 'tiny' objects in one byte
*/
tmp_cparam.id_len = 19;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != 19)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != 17)
TEST_ERROR;
if (tiny_len_extended != true)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != true)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Set the heap ID length a size that's larger than what is needed for
* directly accessing 'huge' objects
*/
tmp_cparam.id_len = 45;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Test ID length information for heap */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != 45)
FAIL_STACK_ERROR;
if (H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0)
FAIL_STACK_ERROR;
if (tiny_max_len != 43)
TEST_ERROR;
if (tiny_len_extended != true)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (huge_ids_direct != true)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Set the heap ID length to a size that's too large to encode the length
* of 'tiny' objects
*/
tmp_cparam.id_len = H5HF_MAX_ID_LEN + 1;
/* Create absolute heap */
H5E_BEGIN_TRY
{
fh = H5HF_create(f, &tmp_cparam);
}
H5E_END_TRY
if (NULL != fh)
FAIL_STACK_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* All tests passed */
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return 1;
} /* test_id_limits() */
/*-------------------------------------------------------------------------
* Function: test_filtered_create
*
* Purpose: Test creating a heap with I/O filters
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_filtered_create(hid_t fapl, H5HF_create_t *cparam, hid_t fcpl)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
H5HF_create_t test_cparam; /* Temporary local heap creation parameters */
unsigned deflate_level; /* Deflation level */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Display testing message */
TESTING("creating heaps with I/O filters");
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
FAIL_STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, &tmp_cparam)))
FAIL_STACK_ERROR;
/* Get heap's address */
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Query the heap creation parameters */
memset(&test_cparam, 0, sizeof(H5HF_create_t));
if (H5HF_get_cparam_test(fh, &test_cparam) < 0)
FAIL_STACK_ERROR;
if (H5HF_cmp_cparam_test(&tmp_cparam, &test_cparam))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Release the I/O pipeline filter information */
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline);
H5O_msg_reset(H5O_PLINE_ID, &test_cparam.pline);
/* All tests passed */
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return 1;
} /* test_filtered_create() */
/*-------------------------------------------------------------------------
* Function: test_size
*
* Purpose: Test querying heap size
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_size(hid_t fapl, H5HF_create_t *cparam, hid_t fcpl)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
hsize_t empty_heap_size; /* Total size of empty heap on disk */
hsize_t one_heap_size; /* Total size of heap on disk after inserting one object */
hsize_t heap_size; /* Total size of heap on disk */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Display testing message */
TESTING("querying heap statistics");
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
/* Get heap's address */
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
/* Get an empty heap's size */
empty_heap_size = 0;
if (H5HF_size(fh, &empty_heap_size) < 0)
FAIL_STACK_ERROR;
if (empty_heap_size == 0)
TEST_ERROR;
/* Insert an object */
if (add_obj(fh, (size_t)0, (size_t)10, NULL, NULL) < 0)
TEST_ERROR;
/* Get the heap's size after inserting one object */
one_heap_size = 0;
if (H5HF_size(fh, &one_heap_size) < 0)
FAIL_STACK_ERROR;
if (one_heap_size <= empty_heap_size)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Check the heap's size */
heap_size = 0;
if (H5HF_size(fh, &heap_size) < 0)
FAIL_STACK_ERROR;
if (heap_size != one_heap_size)
TEST_ERROR;
/* Insert another object */
if (add_obj(fh, (size_t)1, (size_t)10, NULL, NULL) < 0)
TEST_ERROR;
/* Check the heap's size */
heap_size = 0;
if (H5HF_size(fh, &heap_size) < 0)
FAIL_STACK_ERROR;
if (heap_size != one_heap_size)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* All tests passed */
PASSED();
return 0;
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return 1;
} /* test_size() */
/*-------------------------------------------------------------------------
* Function: test_reopen_hdr
*
* Purpose: Test opening a header through one file handle, closing
* that file handle, then reopening through a different file
* handle that was open the whole time. The header should
* stay in cache between the two opens.
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_reopen_hdr(hid_t fapl, H5HF_create_t *cparam, hid_t fcpl)
{
hid_t file1 = H5I_INVALID_HID; /* File ID */
hid_t file2 = -2; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
hsize_t heap_size; /* Total size of heap on disk */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file1 = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file1)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Display testing message */
TESTING("reopening header through different file");
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
/* Get heap's address */
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
/* Insert an object */
if (add_obj(fh, (size_t)0, (size_t)10, NULL, NULL) < 0)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file1) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Re-open the file again */
if ((file2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object (file1) */
if (NULL == (f = (H5F_t *)H5VL_object(file1)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Close the heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file (file1) */
if (H5Fclose(file1) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object (file2) */
if (NULL == (f = (H5F_t *)H5VL_object(file2)))
FAIL_STACK_ERROR;
/* Reopen the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Check the heap's size */
heap_size = 0;
if (H5HF_size(fh, &heap_size) < 0)
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
/* Close the file (file2) */
if (H5Fclose(file2) < 0)
FAIL_STACK_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file1);
H5Fclose(file2);
}
H5E_END_TRY
return (1);
} /* test_reopen_hdr() */
/*-------------------------------------------------------------------------
* Function: test_man_insert_weird
*
* Purpose: Test inserting "weird" sized objects into absolute heap
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_insert_weird(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
herr_t ret; /* Generic return value */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
TEST_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/*
* Test inserting "weird" sized objects into heap
*/
TESTING("inserting 'weird' sized objects into absolute heap");
/* Attempt to insert 0-sized object into heap */
H5E_BEGIN_TRY
{
ret = H5HF_insert(fh, (size_t)0, shared_wobj_g, heap_id);
}
H5E_END_TRY
if (ret >= 0)
TEST_ERROR;
H5Eclear2(H5E_DEFAULT);
/* Insert a 1-sized object into heap (should be a 'tiny' object) */
if (add_obj(fh, (size_t)10, (size_t)1, &state, NULL))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check for correctly sized heap */
if (check_stats(fh, &state))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_insert_weird() */
#ifdef ALL_INSERT_TESTS
/*-------------------------------------------------------------------------
* Function: test_man_insert_first
*
* Purpose: Test inserting first object into absolute heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_insert_first(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
TEST_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
TEST_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/*
* Test inserting first (small) object into absolute heap
*/
TESTING("inserting first (small) object into absolute heap");
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check for correctly sized heap */
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_insert_first() */
/*-------------------------------------------------------------------------
* Function: test_man_insert_second
*
* Purpose: Test inserting two objects into absolute heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_insert_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting first (small) object into absolute heap
*/
TESTING("inserting two (small) objects into absolute heap");
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert second object */
if (add_obj(fh, (size_t)20, SMALL_OBJ_SIZE2, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_insert_second() */
/*-------------------------------------------------------------------------
* Function: test_man_insert_root_mult
*
* Purpose: Test inserting mult. objects into absolute heap, up to the
* limit of a root direct block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_insert_root_mult(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) object into absolute heap
*/
TESTING("inserting objects to fill absolute heap's root direct block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill the heap up */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_insert_root_mult() */
/*-------------------------------------------------------------------------
* Function: test_man_insert_force_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, filling the
* root direct block and forcing the root block to be converted
* into an indirect block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test forcing creation of indirect root block & second direct block
*/
TESTING("inserting objects to create root indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill the heap up */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force root indirect block creation */
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_insert_force_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_insert_fill_second
*
* Purpose: Test inserting mult. objects into absolute heap, filling the
* root direct block, forcing the root block to be converted
* into an indirect block and filling the secnod indirect block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill second direct block
*/
TESTING("inserting objects to fill second direct block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill the first direct block heap up */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill the second direct block heap up (also creates initial root indirect block) */
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_insert_fill_second() */
/*-------------------------------------------------------------------------
* Function: test_man_insert_third_direct
*
* Purpose: Test inserting mult. objects into absolute heap, filling the
* root direct block, forcing the root block to be converted
* into an indirect block, filling the secnod indirect block and
* creating a third direct block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_insert_third_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to create third direct block
*/
TESTING("inserting objects to create third direct block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill the first direct block up */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill the second direct block heap up (also creates initial root indirect block) */
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of third direct block */
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_insert_third_direct() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_first_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill first row of root indirect
* block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill first row in root indirect block
*/
TESTING("inserting objects to fill first row of root indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill first row of [root] indirect block */
if (fill_root_row(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_first_row() */
/*-------------------------------------------------------------------------
* Function: test_man_start_second_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill first row of root indirect
* block, then add another object to start second row.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_start_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to start second row in root indirect block
*/
TESTING("inserting objects to start second row of root indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill first root indirect row */
if (fill_root_row(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force expanding root indirect block to two rows */
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_alloc_size += DBLOCK_SIZE(fh, 1);
state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 1);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_start_second_row() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_second_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill first row of root indirect
* block, then fill the second row also.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to start second row in root indirect block
*/
TESTING("inserting objects to fill second row of root indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill first root indirect row */
if (fill_root_row(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill second root indirect row */
if (fill_root_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_second_row() */
/*-------------------------------------------------------------------------
* Function: test_man_start_third_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill first row of root indirect
* block, fill the second row also, then add another object to
* start the third row.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_start_third_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to start third row in root indirect block
*/
TESTING("inserting objects to start third row of root indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill first root indirect row */
if (fill_root_row(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill second root indirect row */
if (fill_root_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force expanding root indirect block to four rows */
/* (Goes to four rows because it's doubling) */
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3);
state.man_alloc_size += DBLOCK_SIZE(fh, 2);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_start_third_row() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_fourth_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill first four rows of root indirect
* block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variables */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill four rows in root indirect block
*/
TESTING("inserting objects to fill four rows of root indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Loop over rows */
for (u = 0; u < 4; u++)
if (fill_root_row(fh, u, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_fourth_row() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_all_root_direct
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct rows in root indirect block
*/
TESTING("inserting objects to fill all direct rows of root indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill all direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_all_root_direct() */
/*-------------------------------------------------------------------------
* Function: test_man_first_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block and create first recursive indirect block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to force creation of first recursive indirect block
*/
TESTING("inserting objects to create first recursive indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of first recursive indirect block */
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_first_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_second_direct_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, create first recursive indirect block and start second
* direct block in that indirect block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to force creation of second direct
* block in first recursive indirect block
*/
TESTING("inserting objects to create second direct block in first recursive indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill the first direct block in the recursive indirect block up */
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of second direct block in
* first recursive indirect block
*/
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_second_direct_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_first_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, create first recursive indirect block and filling all
* direct blocks in that indirect block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to fill all direct blocks in first recursive indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first recursive indirect block */
if (fill_2nd_indirect(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_first_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_second_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, create first recursive indirect block, filling all
* direct blocks in that indirect block and adding another
* object to force creation of second recursive indirect block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to start second recursive indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill first recursive indirect block */
if (fill_2nd_indirect(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of second
* recursive indirect block
*/
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_second_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_second_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, create first recursive indirect block, filling all
* direct blocks in that indirect block and then create second
* recursive indirect block and fill all direct blocks in that
* indirect block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to fill all direct blocks in second recursive indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill first recursive indirect block */
if (fill_2nd_indirect(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill 2nd recursive indirect block */
if (fill_2nd_indirect(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_second_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_recursive_indirect_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, create first recursive indirect block, filling all
* direct blocks in that indirect block and then create second
* recursive indirect block and fill all direct blocks in that
* indirect block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to fill all direct blocks in first row of recursive indirect block");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks in root indirect block up */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill row of recursive indirect blocks */
if (fill_2nd_indirect_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_recursive_indirect_row() */
/*-------------------------------------------------------------------------
* Function: test_man_start_2nd_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the first row of indirect
* blocks and start on first block in second row of indirect blocks
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to start second row of recursive indirect blocks");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks in root indirect block up */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill row of recursive indirect blocks */
if (fill_2nd_indirect_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of second
* recursive indirect block
*/
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_start_2nd_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_recursive_indirect_two_deep
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to fill recursive indirect blocks two levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_recursive_indirect_two_deep() */
/*-------------------------------------------------------------------------
* Function: test_man_start_3rd_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep and start first direct block
* in 3rd level of indirect blocks
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to start recursive indirect blocks three levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of third level deep
* recursive indirect block
*/
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_start_3rd_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_first_3rd_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep and fill first indirect block
* in 3rd level of indirect blocks
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to fill first indirect block of recursive indirect blocks three levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all direct block rows in third level indirect block */
if (fill_all_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill row of recursive indirect blocks in third level indirect block */
if (fill_2nd_indirect_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_first_3rd_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_3rd_recursive_indirect_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep and fill all indirect blocks
* first row of 3rd level of indirect blocks
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING(
"inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill 1st row of 3rd level indirect blocks */
if (fill_3rd_indirect_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_3rd_recursive_indirect_row() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_all_3rd_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep and fill all indirect blocks
* that are three levels deep
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING(
"inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_all_3rd_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_start_4th_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep, fill all indirect blocks
* that are three levels deep and start first direct block that
* is four levels deep
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to start first direct block in recursive indirect blocks four levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of four level deep
* recursive indirect block
*/
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_start_4th_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_first_4th_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep, fill all indirect blocks
* that are three levels deep and fill the first (3rd level)
* indirect block that is four levels deep
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to fill first (3rd level) indirect block in recursive indirect block four "
"levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill direct block rows in fourth level indirect block */
if (fill_all_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level deep indirect blocks in fourth level indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row of 3rd level deep indirect blocks in fourth level indirect block */
if (fill_3rd_indirect_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_first_4th_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_4th_recursive_indirect_row
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep, fill all indirect blocks
* that are three levels deep and fill the first row of
* indirect block that is four levels deep
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in first recursive indirect block
*/
TESTING("inserting objects to fill first row of recursive indirect blocks four levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill 1st row of 4th level indirect blocks */
if (fill_4th_indirect_row(fh, 1, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_4th_recursive_indirect_row() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_all_4th_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep, fill all indirect blocks
* that are three levels deep and fill all rows of
* indirect blocks that are four levels deep
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in recursive indirect blocks four levels deep
*/
TESTING("inserting objects to fill all rows of recursive indirect blocks four levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 4th level indirect blocks */
if (fill_all_4th_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_all_4th_recursive_indirect() */
#endif /* ALL_INSERT_TESTS */
/*-------------------------------------------------------------------------
* Function: test_man_start_5th_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
* block, fill all direct blocks in the row of indirect
* blocks that are 2 levels deep, fill all indirect blocks
* that are three levels deep, fill all rows of indirect blocks
* that are four levels deep and start first direct block in
* indirect blocks five levels deep
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
/*
* Test inserting mult. (small) objects to fill all direct
* blocks in recursive indirect blocks four levels deep and add one more
* block, to make a five level deep structure
*/
TESTING("inserting objects to create first direct block in recursive indirect blocks five levels deep");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Fill direct blocks up in root indirect block */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap & file */
if (reopen_file(&file, &f, filename, fapl, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap & file */
if (reopen_file(&file, &f, filename, fapl, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap & file */
if (reopen_file(&file, &f, filename, fapl, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 4th level indirect blocks */
if (fill_all_4th_indirect_rows(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap & file */
if (reopen_file(&file, &f, filename, fapl, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to force creation of five level deep
* recursive indirect block
*/
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, NULL))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_start_5th_recursive_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_bogus
*
* Purpose: Test removing bogus heap IDs
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */
unsigned long seed = 0; /* Random # seed */
size_t id_len; /* Size of fractal heap IDs */
hsize_t obj_off; /* Offset of object in heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
herr_t ret; /* Generic return value */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/*
* Test removing bogus IDs from heap
*/
TESTING("removing bad heap IDs from absolute heap");
/* Retrieve "bulk" filling object size */
fill_size = get_fill_size(tparam);
/* Choose random # seed */
seed = (unsigned long)time(NULL);
#if 0
/* seed = (unsigned long)1155438845; */
fprintf(stderr, "Random # seed was: %lu\n", seed);
#endif
srand((unsigned)seed);
/* Set heap ID to random (non-null) value */
heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN;
for (u = 1; u < HEAP_ID_LEN; u++)
heap_id[u] = (unsigned char)(rand() + 1);
/* Try removing bogus heap ID from empty heap */
H5E_BEGIN_TRY
{
ret = H5HF_remove(fh, heap_id);
}
H5E_END_TRY
if (ret >= 0)
FAIL_STACK_ERROR;
/* Fill root direct blocks */
if (fill_root_direct(fh, fill_size, &state, NULL))
FAIL_STACK_ERROR;
/* Get offset of random heap ID */
if (H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0)
FAIL_STACK_ERROR;
/* Make certain we can't accidentally use a valid heap ID */
while (obj_off < state.man_size) {
/* Set heap ID to random (non-null) value */
heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN;
for (u = 1; u < HEAP_ID_LEN; u++)
heap_id[u] = (unsigned char)(rand() + 1);
/* Get offset of random heap ID */
if (H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0)
FAIL_STACK_ERROR;
} /* end while */
/* Try removing bogus heap ID from heap w/objects */
H5E_BEGIN_TRY
{
ret = H5HF_remove(fh, heap_id);
}
H5E_END_TRY
if (ret >= 0)
TEST_ERROR;
H5Eclear2(H5E_DEFAULT);
/* Try reading bogus heap ID from heap w/objects */
H5E_BEGIN_TRY
{
ret = H5HF_read(fh, heap_id, shared_robj_g);
}
H5E_END_TRY
if (ret >= 0)
TEST_ERROR;
H5Eclear2(H5E_DEFAULT);
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
fprintf(stderr, "Random # seed was: %lu\n", seed);
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_bogus() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_one
*
* Purpose: Test removing single object from heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */
unsigned char obj[SMALL_OBJ_SIZE1]; /* Buffer for object to insert */
size_t id_len; /* Size of fractal heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Prepare for querying the size of a file with an empty heap */
/* Close (empty) heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Re-open heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/*
* Test removing first (small) object from absolute heap
*/
TESTING("removing single object from absolute heap");
/* Initialize the buffer for objects to insert */
for (u = 0; u < sizeof(obj); u++)
obj[u] = (unsigned char)u;
/* Insert object into heap */
if (H5HF_insert(fh, sizeof(obj), obj, &heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0) - sizeof(obj);
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
state.man_nobjs = 0;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_one() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_two
*
* Purpose: Test removing two objects from heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for first object */
unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */
unsigned char obj[SMALL_OBJ_SIZE1]; /* Buffer for object to insert */
size_t id_len; /* Size of fractal heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Prepare for querying the size of a file with an empty heap */
/* Close (empty) heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Re-open heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/*
* Test removing two (small) objects from absolute heap
*/
TESTING("removing two objects from absolute heap");
/* Initialize the buffer for objects to insert */
for (u = 0; u < sizeof(obj); u++)
obj[u] = (unsigned char)u;
/* Insert first object into heap */
if (H5HF_insert(fh, sizeof(obj), obj, &heap_id1) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0) - sizeof(obj);
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Insert second object into heap */
if (H5HF_insert(fh, sizeof(obj), obj, &heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_free_space -= sizeof(obj);
state.man_nobjs++;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id1) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_free_space += sizeof(obj);
state.man_nobjs--;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
state.man_nobjs = 0;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_two() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_one_larger
*
* Purpose: Test removing single larger (but < standalone size) object
* from heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */
unsigned char *obj; /* Buffer for object to insert */
size_t obj_len; /* Length of object to insert */
size_t id_len; /* Size of fractal heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Prepare for querying the size of a file with an empty heap */
/* Close (empty) heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Re-open heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/*
* Test removing one larger object from absolute heap
*/
TESTING("removing single larger object from absolute heap");
/* Set up object to insert */
obj_len = (size_t)DBLOCK_SIZE(fh, 2) + 1;
obj = shared_wobj_g;
/* Insert object into heap */
if (H5HF_insert(fh, obj_len, obj, &heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
for (u = 0; u < 4; u++) {
state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size = DBLOCK_SIZE(fh, 3);
state.man_free_space -= obj_len;
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
state.man_nobjs = 0;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_one_larger() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_two_larger
*
* Purpose: Test removing two larger (but < standalone size) objects
* from heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for first object */
unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */
unsigned char *obj; /* Buffer for object to insert */
size_t obj_len; /* Length of object to insert */
size_t id_len; /* Size of fractal heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Prepare for querying the size of a file with an empty heap */
/* Close (empty) heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Re-open heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/*
* Test removing two larger objects from absolute heap
*/
if (tparam->del_dir == FHEAP_DEL_FORWARD)
TESTING("removing two larger objects from absolute heap (forward)");
else
TESTING("removing two larger objects from absolute heap (reverse)");
/* Set up first object to insert */
obj_len = (size_t)DBLOCK_SIZE(fh, 2) + 1;
obj = shared_wobj_g;
/* Insert object into heap */
if (H5HF_insert(fh, obj_len, obj, &heap_id1) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
for (u = 0; u < 4; u++) {
state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size = DBLOCK_SIZE(fh, 3);
state.man_free_space -= obj_len;
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Set up second object to insert */
obj_len = (size_t)DBLOCK_SIZE(fh, 4) + 1;
obj = shared_wobj_g;
/* Insert object into heap */
if (H5HF_insert(fh, obj_len, obj, &heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (Goes to 8 rows because of doubling) */
for (u = 4; u < 8; u++) {
state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size += DBLOCK_SIZE(fh, 5);
state.man_free_space -= obj_len;
state.man_nobjs = 2;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove objects in different orders */
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id1) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_alloc_size -= DBLOCK_SIZE(fh, 3);
state.man_free_space += DBLOCK_SIZE(fh, 2) + 1;
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
} /* end if */
else {
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (Goes to 4 rows because of halving) */
for (u = 4; u < 8; u++) {
state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size -= DBLOCK_SIZE(fh, 5);
state.man_free_space += DBLOCK_SIZE(fh, 4) + 1;
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id1) < 0)
FAIL_STACK_ERROR;
} /* end else */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
state.man_nobjs = 0;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_two_larger() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_three_larger
*
* Purpose: Test removing three larger (but < standalone size) objects
* from heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id1[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 *obj; /* Buffer for object to insert */
size_t obj_len; /* Length of object to insert */
size_t id_len; /* Size of fractal heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
TEST_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Prepare for querying the size of a file with an empty heap */
/* Close (empty) heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
/* Close file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of a file w/empty heap*/
if ((empty_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Re-open heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/*
* Test removing three larger objects from absolute heap
*/
if (tparam->del_dir == FHEAP_DEL_FORWARD)
TESTING("removing three larger objects from absolute heap (forward)");
else
TESTING("removing three larger objects from absolute heap (reverse)");
/* Set up first object to insert */
obj_len = (size_t)DBLOCK_SIZE(fh, 2) + 1;
obj = shared_wobj_g;
/* Insert object into heap */
if (H5HF_insert(fh, obj_len, obj, &heap_id1) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
for (u = 0; u < 4; u++) {
state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size = DBLOCK_SIZE(fh, 3);
state.man_free_space -= obj_len;
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Set up second object to insert */
obj_len = (size_t)DBLOCK_SIZE(fh, 4) + 1;
obj = shared_wobj_g;
/* Insert object into heap */
if (H5HF_insert(fh, obj_len, obj, &heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (Goes to 8 rows because of doubling) */
for (u = 4; u < 8; u++) {
state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size += DBLOCK_SIZE(fh, 5);
state.man_free_space -= obj_len;
state.man_nobjs = 2;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Set up third object to insert */
obj_len = (size_t)DBLOCK_SIZE(fh, 7) + 1;
obj = shared_wobj_g;
/* Insert object into heap */
if (H5HF_insert(fh, obj_len, obj, &heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (Goes to 16 rows because of doubling) */
for (u = 8; u < 16; u++) {
state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size += DBLOCK_SIZE(fh, 8);
state.man_free_space -= obj_len;
state.man_nobjs = 3;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove objects in different orders */
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id1) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_alloc_size -= DBLOCK_SIZE(fh, 3);
state.man_free_space += DBLOCK_SIZE(fh, 2) + 1;
state.man_nobjs = 2;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_alloc_size -= DBLOCK_SIZE(fh, 5);
state.man_free_space += DBLOCK_SIZE(fh, 4) + 1;
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove third object from heap */
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
} /* end if */
else {
/* Remove third object from heap */
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (Goes to 8 rows because of halving) */
for (u = 8; u < 16; u++) {
state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size -= DBLOCK_SIZE(fh, 8);
state.man_free_space += DBLOCK_SIZE(fh, 7) + 1;
state.man_nobjs = 2;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (Goes to 4 rows because of halving) */
for (u = 4; u < 8; u++) {
state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width;
state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width;
} /* end for */
state.man_alloc_size -= DBLOCK_SIZE(fh, 5);
state.man_free_space += DBLOCK_SIZE(fh, 4) + 1;
state.man_nobjs = 1;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id1) < 0)
FAIL_STACK_ERROR;
} /* end else */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
state.man_nobjs = 0;
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_three_larger() */
/*-------------------------------------------------------------------------
* Function: test_man_incr_insert_remove
*
* Purpose: Test incremental insert & removal of objects in heap
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_incr_insert_remove(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char **heap_id = NULL;
unsigned char *heap_id_data = NULL;
struct a_type_t1 {
char a[10];
char b[40];
} obj1, obj2; /* Objects to insert/remove */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
int i, j;
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Set up data array */
if (NULL == (heap_id_data = (unsigned char *)calloc(100 * MAX_HEAP_ID_LEN, sizeof(unsigned char))))
TEST_ERROR;
if (NULL == (heap_id = (unsigned char **)calloc(100, sizeof(heap_id_data))))
TEST_ERROR;
for (i = 0; i < 100; i++)
heap_id[i] = heap_id_data + (i * MAX_HEAP_ID_LEN);
/* Create the file to work on */
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, tparam->my_fcpl, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Create absolute heap */
if (NULL == (fh = H5HF_create(f, cparam)))
FAIL_STACK_ERROR;
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR;
if (H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR;
if (!H5_addr_defined(fh_addr))
FAIL_STACK_ERROR;
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
FAIL_STACK_ERROR;
/*
* Test incremental insert and removal
*/
TESTING("incremental object insertion and removal");
memset(&obj1, 0, sizeof(obj1));
memset(&obj2, 0, sizeof(obj2));
for (i = 0; i < 100; i++) {
for (j = 0; j < i; j++) {
if (H5HF_remove(fh, heap_id[j]) < 0)
FAIL_STACK_ERROR;
snprintf(obj2.b, sizeof(obj2.b), "%s%2d", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", j);
if (H5HF_insert(fh, (sizeof(obj2)), &obj2, heap_id[j]) < 0)
FAIL_STACK_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object */
memset(heap_id[i], 0, id_len);
snprintf(obj1.b, sizeof(obj1.b), "%s%2d", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", i);
if (H5HF_insert(fh, (sizeof(obj1)), &obj1, heap_id[i]) < 0)
FAIL_STACK_ERROR;
} /* end for */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
TEST_ERROR;
/* Close the file */
if (H5Fclose(file) < 0)
TEST_ERROR;
/* All tests passed */
PASSED();
free(heap_id);
free(heap_id_data);
return 0;
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
free(heap_id);
free(heap_id_data);
return 1;
} /* test_man_incr_insert_remove() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_root_direct
*
* Purpose: Test filling and removing all objects from root direct block in
* heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from root direct block of absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill the heap up */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_root_direct() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_two_direct
*
* Purpose: Test filling and removing all objects from (first) two direct
* blocks in heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_two_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from two direct blocks of absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill the first block in heap */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
if (check_stats(fh, &state))
TEST_ERROR;
/* Fill the second block in heap */
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_two_direct() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_first_row
*
* Purpose: Test filling and removing all objects from first row of direct
* blocks in heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from first row of direct blocks of absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill first row of direct blocks */
if (fill_root_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_first_row() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_first_two_rows
*
* Purpose: Test filling and removing all objects from first two rows of
* direct blocks in heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_first_two_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from first two rows of direct blocks of absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill first two rows of direct blocks */
if (fill_root_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_root_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_first_two_rows() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_first_four_rows
*
* Purpose: Test filling and removing all objects from first four rows of
* direct blocks in heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_first_four_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from first four rows of direct blocks of absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill first two rows of direct blocks */
if (fill_root_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_root_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_root_row(fh, 2, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_root_row(fh, 3, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_first_four_rows() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_all_root_direct
*
* Purpose: Test filling and removing all objects from all direct blocks
* in root indirect block of heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from all direct blocks of root group in absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_all_root_direct() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_2nd_indirect
*
* Purpose: Test filling and removing all objects up to 2nd level indirect
* blocks of heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_2nd_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from 2nd level indirect blocks of absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_2nd_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_remove_3rd_indirect
*
* Purpose: Test filling and removing all objects up to 3rd level indirect
* blocks of heap
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_remove_3rd_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "removing all objects from 3rd level indirect blocks of absolute heap";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_remove_3rd_indirect() */
/*-------------------------------------------------------------------------
* Function: test_man_skip_start_block
*
* Purpose: Test inserting object into absolute heap which is too large
* for starting block size, which forces root indirect block
* creation
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_skip_start_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "inserting object that is too large for starting block, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
obj_size = (size_t)DBLOCK_SIZE(fh, 0) + 1;
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_alloc_size = DBLOCK_SIZE(fh, 2);
state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_skip_start_block() */
/*-------------------------------------------------------------------------
* Function: test_man_skip_start_block_add_back
*
* Purpose: Test inserting object into absolute heap which is too large
* for starting block size, which forces root indirect block
* creation, then add object which fits in skipped direct block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc =
"skipping starting block, then adding object back to first block, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Insert object too large for starting block size */
obj_size = (size_t)DBLOCK_SIZE(fh, 0) + 1;
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_alloc_size = DBLOCK_SIZE(fh, 2);
state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the heap block just created */
obj_size = (size_t)DBLOCK_FREE(fh, 2) - obj_size;
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert second "real" object, which should go in earlier direct block */
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)20, (size_t)SMALL_OBJ_SIZE2, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_skip_start_block_add_back() */
/*-------------------------------------------------------------------------
* Function: test_man_skip_start_block_add_skipped
*
* Purpose: Test inserting object into absolute heap which is too large
* for starting block size, which forces root indirect block
* creation, then add objects to fill skipped direct blocks
* and add another object to start on next "normal" block
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc =
"skipping starting block, then adding objects to backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Insert object too large for starting block size */
obj_size = (size_t)DBLOCK_SIZE(fh, 0) + 1;
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_alloc_size = DBLOCK_SIZE(fh, 2);
state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the heap block just created */
obj_size = (size_t)DBLOCK_FREE(fh, 2) - obj_size;
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add rows of blocks to "backfill" direct blocks that were skipped */
if (fill_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert another object, which should extend direct blocks, instead of backfill */
state.man_alloc_size += DBLOCK_SIZE(fh, 2);
if (add_obj(fh, (size_t)20, (size_t)SMALL_OBJ_SIZE2, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_skip_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_skip_2nd_block
*
* Purpose: Test inserting object into absolute heap which is small
* enough for starting block size, then add object too large
* for any blocks in first row of direct blocks, to force
* early creation of indirect block (and range of skipped blocks)
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert object to initial block, then add object too large for starting direct "
"blocks, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Insert small object, to create root direct block */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (add_obj(fh, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped blocks that are too small to hold the second object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 0) + 1;
state.man_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_alloc_size += DBLOCK_SIZE(fh, 2);
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_skip_2nd_block() */
/*-------------------------------------------------------------------------
* Function: test_man_skip_2nd_block_add_skipped
*
* Purpose: Test inserting object into absolute heap which is small
* enough for starting block size, then add object too large
* for any blocks in first row of direct blocks, to force
* early creation of indirect block (and range of skipped blocks).
* Then add more objects to fill up remainder of initial direct
* block and all the skipped blocks, and one more object (to
* start next "normal" block).
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned v; /* Local index variables */
/* Test description */
const char *base_desc = "insert object to initial block, then add object too large for starting direct "
"blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Insert small object, to create root direct block */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (add_obj(fh, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped blocks that are too small to hold the second object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 0) + 1;
state.man_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_alloc_size += DBLOCK_SIZE(fh, 2);
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the (smaller) heap block just created */
obj_size = (size_t)DBLOCK_FREE(fh, 0) - SMALL_OBJ_SIZE1;
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill remainder of 2 * start size block */
obj_size = (size_t)DBLOCK_FREE(fh, 2) - ((size_t)DBLOCK_SIZE(fh, 0) + 1);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects to fill remaining rows of the starting block size */
/* Fill remainder of first row of direct heap blocks up */
for (v = 0; v < (cparam->managed.width - 1); v++) {
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Fill second row of direct blocks */
if (fill_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to create new 2 * start size direct block */
state.man_alloc_size += DBLOCK_SIZE(fh, 2);
if (add_obj(fh, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_skip_2nd_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_one_partial_skip_2nd_block_add_skipped
*
* Purpose: Test filling initial direct block, then add object small enough
* for initial block size (to create root indirect block), then
* add object too large for any blocks in first three rows of
* direct blocks, to force extension of indirect block (and range
* of skipped blocks).
*
* Then add more objects to fill up remainder of partial direct
* block and all the skipped blocks, and one more object (to
* start next "normal" block).
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Test description */
const char *base_desc =
"skipping blocks with indirect root, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill initial direct block */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert small object, to create root indirect block */
state.man_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0);
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
if (add_obj(fh, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped blocks that are too small to hold the large object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 2) + 1;
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3);
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the (smaller) heap block just created */
obj_size = (size_t)DBLOCK_FREE(fh, 0) - SMALL_OBJ_SIZE1;
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill remainder of 4 * start size block */
obj_size = (size_t)DBLOCK_FREE(fh, 3) - ((size_t)DBLOCK_SIZE(fh, 2) + 1);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects to fill remaining heaps in first row */
for (u = 0; u < (cparam->managed.width - 2); u++) {
/* Fill a direct heap block up */
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (fill_heap(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects to fill remaining heaps in second row */
if (fill_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects to fill remaining heaps in third row */
if (fill_row(fh, 2, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to create new 4 * start size direct block */
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_one_partial_skip_2nd_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_row_skip_add_skipped
*
* Purpose: Test filling first row of direct blocks, then
* add object too large for any blocks in first three rows of
* direct blocks, to force extension of indirect block (and range
* of skipped blocks).
*
* Then add more objects to fill up remainder of partial direct
* block and all the skipped blocks, and one more object (to
* start next "normal" block).
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc =
"filling first row, then skipping rows, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill first row of direct blocks */
if (fill_root_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped blocks that are too small to hold the large object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 2) + 1;
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3);
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill remainder of 4 * start size block */
obj_size = (size_t)DBLOCK_FREE(fh, 3) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects to fill remaining heaps in second row */
if (fill_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects to fill remaining heaps in third row */
if (fill_row(fh, 2, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to create new 4 * start size direct block */
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_row_skip_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_skip_direct_skip_indirect_two_rows_add_skipped
*
* Purpose: Test adding object too large for all but the last row in the
* direct blocks in root indirect block, then
* add object too large for initial block in first two rows of
* indirect blocks, to force extension of non-root
* indirect block (and range of skipped blocks).
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_skip_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned num_direct_rows; /* Number of rows (of direct blocks) in root indirect block */
unsigned row; /* Current row */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
fheap_heap_state_t state; /* State of fractal heap */
unsigned v; /* Local index variables */
/* Test description */
const char *base_desc = "skipping direct blocks to last row and skipping two rows of root indirect "
"block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Compute # direct block rows in root indirect block */
num_direct_rows = DTABLE_MAX_DROWS(fh);
/* Compute heap size & free space when half direct blocks allocated */
row = 0;
do {
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row);
row++;
} while (row < (num_direct_rows / 2));
/* Insert object to extend root block to middle of root direct blocks
*/
obj_size = (size_t)DBLOCK_SIZE(fh, row - 2) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, row - 1);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Compute heap size & free space when all direct blocks allocated */
do {
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row);
row++;
} while (row < num_direct_rows);
/* Insert large objects into last row of direct blocks in root indirect
* block, to force extension of root indirect block that covers the first
* row of indirect blocks in root indirect block
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_direct_rows - 2) + 1;
for (v = 0; v < cparam->managed.width; v++) {
state.man_alloc_size += DBLOCK_SIZE(fh, num_direct_rows - 1);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Compute heap size & free space when root indirect block doubles again */
do {
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row);
row++;
} while (row < (2 * num_direct_rows));
/* Insert large object, to force creation of indirect blocks with
* range of skipped blocks that are too small to hold the large object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_direct_rows - 2) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_direct_rows - 1);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_skip_direct_skip_indirect_two_rows_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_direct_skip_indirect_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block, then
* add object too large for initial block in first row of direct
* blocks in indirect block, to force extension of non-root
* indirect block (and range of skipped blocks).
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "filling direct blocks and skipping blocks in non-root indirect block, then "
"backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped blocks that are too small to hold the large object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 2) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add rows of blocks to "backfill" direct blocks that were skipped */
if (fill_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the (biggest) heap block created */
obj_size = (size_t)DBLOCK_FREE(fh, 3) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill direct block heaps with 2 * initial block size in nested indirect block */
if (fill_row(fh, 2, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert one more object, to create new 4 * start size direct block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_direct_skip_indirect_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_direct_skip_2nd_indirect_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block, then
* add object too large for all direct blocks in first row of
* indirect blocks, to force skipping a row of indirect blocks
* (and range of skipped blocks), then backfill all direct blocks
* skipped and extend to next "normal" direct block.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the */
/* first indirect blocks */
unsigned row; /* Current row in indirect block */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Test description */
const char *base_desc = "filling direct blocks and skipping row of non-root indirect blocks, then "
"backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of direct blocks that are smaller than large object's block size */
for (row = 0; row < num_first_indirect_rows; row++) {
/* Fill rows of direct blocks in skipped indirect blocks */
for (u = 0; u < cparam->managed.width; u++)
if (fill_row(fh, row, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */
if (fill_row(fh, row, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_direct_skip_2nd_indirect_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_2nd_direct_less_one_wrap_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, except the last
* one, then insert object insert object that is too large to
* hold in row of 2nd level indirect blocks (forcing the use of
* the next row of 2nd level blocks), then backfill all skipped
* direct blocks & extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, except last one, and insert object too "
"large for 2nd level indirect blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row (except one) of 2nd level indirect blocks */
for (u = 0; u < cparam->managed.width - 1; u++)
/* Fill all rows of 2nd level indirect blocks in root block */
if (fill_2nd_indirect(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in 2nd level indirect block's direct blocks
* (and rows of next 2nd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in skipped 2nd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in current 2nd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block, then
* add object too large for all direct blocks in first row of
* indirect blocks, to force skipping a row of indirect blocks
* (and range of skipped blocks), then add object that is too
* large for initial block size in skipped indirect blocks, then
* backfill all direct blocks and extend to next "normal" direct
* block (but insert first block of backfilling with object
* too large for initial block size in skipped indirect block
* row's direct blocks).
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
unsigned row; /* Current row in indirect block */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
/* Test description */
const char *base_desc = "filling direct blocks and skipping row of non-root indirect blocks, then skip "
"row of direct blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object too large for initial block size in skipped indirect blocks */
obj_size = (size_t)DBLOCK_SIZE(fh, 3) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, 4);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (medium) block just created */
obj_size = (size_t)DBLOCK_FREE(fh, 4) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Finish off blocks in row of medium block size (just to make row filling easier below) */
obj_size = (size_t)DBLOCK_FREE(fh, 4);
for (u = 1; u < cparam->managed.width; u++) {
state.man_alloc_size += DBLOCK_SIZE(fh, 4);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of direct blocks that are smaller than large object's block size */
for (row = 0; row < num_first_indirect_rows; row++) {
/* Fill rows of direct blocks in skipped indirect blocks */
for (u = 0; u < cparam->managed.width; u++)
if (fill_row(fh, row, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */
/* (Skip the row of blocks filled above) */
if (row != 4)
if (fill_row(fh, row, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end while */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_direct_skip_indirect_two_rows_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block, then
* add object too large for initial block in first two rows of
* indirect blocks, to force extension of non-root
* indirect block (and range of skipped blocks).
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
unsigned max_dblock_rows; /* Max. # of rows (of direct blocks) in the root indirect block */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc = "filling direct blocks and skipping two rows of root indirect block, then "
"backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
max_dblock_rows = DTABLE_MAX_DROWS(fh);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped blocks that are too small to hold the large object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, max_dblock_rows - 2) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the (biggest) heap block created */
obj_size = (size_t)DBLOCK_FREE(fh, max_dblock_rows - 1) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in indirect block's direct blocks */
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in first row of skipped 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block rows in second row of skipped 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in used 2nd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows in second row of skipped 2nd level indirect blocks (and used 2nd level block) */
/* Direct block rows in skipped 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, num_first_indirect_rows, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Direct block row in used 2nd level indirect block */
if (fill_row(fh, num_first_indirect_rows, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_direct_skip_indirect_two_rows_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block, then
* add object too large for initial block in first two rows of
* indirect blocks, to force extension of non-root
* indirect block, then add object too large for first row of
* indirect blocks, (and ranges of skipped blocks), then backfill
* and extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
unsigned max_dblock_rows; /* Max. # of rows (of direct blocks) in the root indirect block */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks and skipping two rows of root indirect block, skip one row of root indirect "
"block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
max_dblock_rows = DTABLE_MAX_DROWS(fh);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of two rows of indirect blocks and
* range of skipped blocks that are too small to hold the large object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, max_dblock_rows - 2) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the (biggest) heap block created */
obj_size = (size_t)DBLOCK_FREE(fh, max_dblock_rows - 1) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object that can't fit in first row of indirect blocks
* previously skipped, but is small enough to fit into second row of
* skipped blocks.
*/
obj_size = (size_t)DBLOCK_SIZE(fh, max_dblock_rows - 3) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 2);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert an object to fill up the (2nd biggest) heap block created */
obj_size = (size_t)DBLOCK_FREE(fh, max_dblock_rows - 2) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in indirect block's direct blocks */
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in first row of skipped 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block rows in second row of skipped 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in used 2nd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows in second row of skipped 2nd level indirect blocks (and used 2nd level block) */
/* Finish blocks in partially used 2nd level indirect block */
if (fill_partial_row(fh, num_first_indirect_rows, cparam->managed.width - 1, fill_size, &state,
&keep_ids))
TEST_ERROR;
/* Direct block rows in skipped 2nd level indirect blocks */
/* (less the one indirect block already used) */
for (v = 0; v < cparam->managed.width - 1; v++)
if (fill_row(fh, num_first_indirect_rows, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Direct block row in used 3rd row 2nd level indirect block */
if (fill_row(fh, num_first_indirect_rows, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_2nd_direct_skip_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, the insert object
* that is too large to hold in first row of direct blocks of
* 3rd level indirect block, then backfill & extend all skipped
* 3rd level indirect block's direct blocks.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, and skip first rows of direct blocks of "
"3rd level indirect block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 2) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, 3) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in 3rd level indirect block's direct blocks */
if (fill_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_row(fh, 2, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_2nd_direct_skip_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks in 3rd level indirect block, then insert object
* that is too large to hold in first row of direct blocks of
* 3rd level indirect block's first 2nd level indirect block, then
* backfill & extend all skipped 2nd level indirect block's direct
* blocks.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect block's direct "
"blocks, and skip first rows of direct blocks of 3rd level indirect block's 2nd level indirect "
"block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in third level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 2) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, 3) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (3rd level indirect block's) 2nd level
* indirect block's direct blocks
*/
if (fill_row(fh, 0, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
if (fill_row(fh, 2, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, 3);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks in 3rd level indirect block, then insert object
* that is too large to hold in first row of 2nd level indirect
* blocks of 3rd level indirect block, then backfill & extend all
* skipped direct blocks.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl,
H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level "
"indirect block's direct blocks, and skip first row of indirect blocks of 3rd "
"level indirect block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in third level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (first 3rd level indirect block's) 2nd level
* indirect block's direct blocks
* (and second 3rd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in 3rd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks in 3rd level indirect block, then insert object
* that is too large to hold in first & second rows of 2nd level
* indirect blocks (although this 3rd level indirect block only
* has one row of 2nd level indirect blocks) of 3rd level indirect
* block, then backfill & extend all skipped direct blocks.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped(hid_t fapl,
H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level "
"indirect block's direct blocks, and skip first two rows of indirect blocks of "
"3rd level indirect block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in third level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows + 1);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows + 1) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (first 3rd level indirect block's) 2nd level
* indirect block's direct blocks
* (and second 3rd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in 3rd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Fill row of direct blocks in second 3rd level indirect block */
if (fill_row(fh, num_first_indirect_rows, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows + 1);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, all 3rd level
* indirect blocks in first row except the last one, fill direct
* blocks in last 3rd level indirect block, then insert object
* insert object that is too large to hold in last 3rd level
* indirect block's row of 2nd level indirect blocks (forcing the
* use of the next row of 3rd level blocks), then backfill all
* skipped direct blocks & extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling first row of 3rd level indirect "
"blocks, except last one, fill all direct blocks in last 3rd level indirect block, and insert object "
"too large for it's 2nd level indirect blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in root indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row (except one) of 3rd level indirect blocks */
for (u = 0; u < cparam->managed.width - 1; u++)
/* Fill 3rd level indirect block */
if (fill_3rd_indirect(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in last third level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in 2nd level indirect block's direct blocks
* (and rows of next 3rd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in current 3rd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, all 3rd level
* indirect blocks in first row, fill direct blocks in 2nd row 3rd
* level indirect block, fill all direct blocks in 1st row of
* 2nd level indirect blocks except the last one, then insert
* object that is too large to hold in 3rd level indirect block's
* first row of 2nd level indirect blocks (forcing the use of the
* next row of 2nd level blocks), then backfill all skipped direct
* blocks & extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(
hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variables */ /* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling first row of 3rd level indirect "
"blocks, fill all direct blocks in next 3rd level indirect block, fill all 1st row of 2nd level "
"indirect blocks, except last one, and insert object too large for 2nd level indirect block, then "
"backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in 4th level indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row of 3rd level indirect blocks */
if (fill_3rd_indirect_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in 2nd row third level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row (except one) of 2nd level indirect blocks */
for (u = 0; u < cparam->managed.width - 1; u++)
if (fill_2nd_indirect(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in 2nd level indirect block's direct blocks
* (and rows of next 2nd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in skipped 2nd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in current 2nd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks and indirect blocks in 3rd level indirect block, then
* fill all direct blocks in 4th level indirect block, then
* insert object that is too large to hold in first row of 2nd
* level indirect blocks of 4th level indirect block, then
* backfill all skipped direct blocks & extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam,
fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill "
"4th level indirect block's direct blocks, and skip first row of 2nd indirect blocks of 4th level "
"indirect block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in fourth level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (first 4th level indirect block's) 2nd level
* indirect block's direct blocks
* (and second row of 2nd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in 2nd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function: test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks and indirect blocks in 3rd level indirect block, then
* fill all direct blocks and 2nd level indirect blocks in 4th
* level indirect block, then
* insert object that is too large to hold in first row of 2nd
* level indirect blocks of 4th level indirect block's first
* 3rd level indirect block, then
* backfill all skipped direct blocks & extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(
hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill "
"4th level indirect block's direct, 2nd level indirect blocks and 3rd level direct block, and skip "
"first row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then "
"backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in fourth level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in fourth level indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in fourth level indirect block's 3rd level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (first 4th level indirect block's first 3rd
* level block's) 2nd level indirect block's direct blocks
* (and rows of 2nd 3rd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in 3rd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function:
*test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks and indirect blocks in 3rd level indirect block, fill all
* direct & indirect blocks in first row of 4th level indirect
* blocks, then fill all direct blocks in first row of 3rd level
* indirect blocks in 4th level indirect block, fill direct blocks
* in first block of 2nd row of 3rd level indirect blocks in 4th
* level indirect block, then insert object insert object that is
* too large to hold in first row of 2nd level indirect blocks of
* 3rd level indirect block (in 4th level indirect block), then
* backfill all skipped direct blocks & extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(
hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill "
"first row of 4th level indirect blocks, fill 2nd row 4th level indirect block's direct, 2nd level "
"indirect blocks, first row of 3rd level indirect blocks, 3rd level direct block in 2nd row, and "
"skip first row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then "
"backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row of 4th level indirect blocks */
if (fill_4th_indirect_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Account for root indirect block doubling # of rows again */
/* (From 16 rows to the max. # of rows: 22) */
/* (Note: this is tied to the particular doubling table/heap creation parameters) */
{
unsigned max_root_rows; /* Maximum # of rows in root indirect block */
unsigned row; /* Row in heap */
/* Get some information for the heap */
max_root_rows = HEAP_MAX_ROOT_ROWS(fh);
/* Increase heap size & free space */
for (row = 16; row < max_root_rows; row++) {
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row);
} /* end for */
} /* end if */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in 2nd row 4th level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in 2nd row 4th level indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row of 3rd level indirect blocks in 2nd row 4th level indirect block */
if (fill_3rd_indirect_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in 4th level indirect block's 2nd row of 3rd level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (first block in 2nd row 4th level indirect
* block's first 3rd level block's) 2nd level indirect block's direct
* blocks (and rows of 2nd 3rd level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in 3rd level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped()
*/
/*-------------------------------------------------------------------------
* Function:
*test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks and indirect blocks in 3rd level indirect block, fill all
* direct & indirect blocks in 4th level indirect
* block, then fill all direct blocks in first row of 3rd
* level indirect blocks in 4th level indirect block except
* the last (3rd level indirect block) in 4th level indirect block,
* fill direct blocks in last 3rd level indirect block, then
* insert object insert object that is too large to hold in first
* row of 2nd level indirect blocks of 3rd level indirect block
* (in 4th level indirect block) (forcing the use of the next
* 4th level block), then backfill all skipped direct blocks &
* extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(
hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill "
"first row of 3rd level indirect blocks in 4th level indirect block except last 3rd level block, "
"fill direct blocks in 3rd level block, and skip row of 2nd indirect blocks of 4th level indirect "
"block's 3rd level indirect block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in 4th level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in 4th level indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row (except one) of 3rd level indirect blocks in 4th level indirect block */
for (u = 0; u < cparam->managed.width - 1; u++) {
/* Fill all direct block rows in 3rd level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill row of 2nd level indirect blocks in 3rd level indirect block */
if (fill_2nd_indirect_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (4th level indirect block's first 3rd level
* block's) 2nd level indirect block's direct blocks (and rows of next 4th
* level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in 4th level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */
/*-------------------------------------------------------------------------
* Function:
*test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped
*
* Purpose: Test filling all direct blocks in root indirect block and all
* direct blocks in 2nd level indirect blocks, fill all direct
* blocks and indirect blocks in 3rd level indirect block, fill all
* direct & indirect blocks in first row of 4th level indirect
* blocks, except last one, then fill all direct blocks in first
* row of 3rd level indirect blocks in 4th level indirect block
* except the last (3rd level indirect block) in 4th level
* indirect block, fill direct blocks in last 3rd level indirect
* block, then insert object insert object that is too large to
* hold in row of 2nd level indirect blocks in 3rd level indirect
* block (in 4th level indirect block) (forcing the use of the
* next row of 4th level blocks), then backfill all skipped direct
* blocks & extend.
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(
hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill "
"first row of 4th level indirect blocks, except last one, fill first row of 3rd level indirect "
"blocks in last 4th level indirect block except last 3rd level block, fill direct blocks in 3rd "
"level block, and skip row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect "
"block, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve info about heap */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 3rd level indirect blocks */
if (fill_all_3rd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill first row (except one) of 4th level indirect blocks */
for (u = 0; u < cparam->managed.width - 1; u++) {
/* Fill all direct block rows in 4th level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in 4th level indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill row of 3rd level indirect blocks in 4th level indirect block */
if (fill_3rd_indirect_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in 4th level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in 4th level indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill row (except one) of 3rd level indirect blocks in 4th level indirect block */
for (u = 0; u < cparam->managed.width - 1; u++) {
/* Fill all direct block rows in 3rd level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Fill row of 2nd level indirect blocks in 3rd level indirect block */
if (fill_2nd_indirect_row(fh, 1, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */
if (fill_all_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Account for root indirect block doubling # of rows again */
/* (From 16 rows to the max. # of rows: 22) */
/* (Note: this is tied to the particular doubling table/heap creation parameters) */
{
unsigned max_root_rows; /* Maximum # of rows in root indirect block */
unsigned row; /* Row in heap */
/* Get some information for the heap */
max_root_rows = HEAP_MAX_ROOT_ROWS(fh);
/* Increase heap size & free space */
for (row = 16; row < max_root_rows; row++) {
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row);
} /* end for */
} /* end if */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert large object, to force creation of indirect block and
* range of skipped (indirect) blocks that are too small to hold the large
* object
*/
obj_size = (size_t)DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object to fill space in (large) block created */
obj_size = (size_t)DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size;
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill rows skipped over in (4th level indirect block's first 3rd level
* block's) 2nd level indirect block's direct blocks (and rows of next 4th
* level indirect block's direct blocks)
*/
for (u = 0; u < num_first_indirect_rows; u++) {
/* Direct block rows in 2nd level indirect blocks */
for (v = 0; v < cparam->managed.width; v++)
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Direct block row in 4th level indirect block */
if (fill_row(fh, u, fill_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Add one more object, to create another "large" block */
obj_size = SMALL_OBJ_SIZE1;
state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped()
*/
/*-------------------------------------------------------------------------
* Function: test_man_frag_simple
*
* Purpose: Test inserting objects small enough to fit into first row of
* direct blocks, but not to share a block with another object,
* until start-block-size * 2 blocks are reached. Then, go back
* and fill in the space in the blocks skipped.
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variables */
/* Test description */
const char *base_desc = "fragmenting small blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Insert objects small enough to fit into initial blocks, but not to
* share them with other objects of the same size, until the next larger
* block size is reached.
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 0) / 2;
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
for (u = 0; u < cparam->managed.width; u++) {
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
if (u == 0) {
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
} /* end if */
} /* end for */
state.man_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width;
for (u = 0; u < cparam->managed.width; u++) {
state.man_alloc_size += DBLOCK_SIZE(fh, 1);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* (Account for doubling root indirect block for rows 3-4 */
for (u = 0; u < 2; u++) {
state.man_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u + 2) * cparam->managed.width;
} /* end for */
/* Add one more object, to create a 2 * start_block_size block */
state.man_alloc_size += DBLOCK_SIZE(fh, 2);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Go back and fill in direct blocks of initial block size (which have large free space in them) */
obj_size = (size_t)DBLOCK_FREE(fh, 0) - obj_size;
for (u = 0; u < cparam->managed.width; u++)
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
for (u = 0; u < cparam->managed.width; u++)
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill in 2 * start_block_size block */
obj_size = (size_t)DBLOCK_FREE(fh, 2) - ((size_t)DBLOCK_SIZE(fh, 0) / 2);
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_frag_simple() */
/*-------------------------------------------------------------------------
* Function: test_man_frag_direct
*
* Purpose: Test inserting small object to fit into each direct block
* in root block, but not to share a block with another object,
* Then, go back and fill in the space in the blocks skipped.
*
* Then, go back and remove all objects
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned root_direct_rows; /* Number of rows in root indirect block */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc = "fragmenting direct blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Retrieve # of direct rows in root indirect block */
root_direct_rows = H5HF_get_dtable_max_drows_test(fh);
/* Insert objects small enough to fit into each direct block, but not to
* share them with other objects of the same size.
*/
obj_size = (size_t)DBLOCK_SIZE(fh, 0) / 2;
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0);
/* First row */
for (u = 0; u < cparam->managed.width; u++) {
state.man_alloc_size += DBLOCK_SIZE(fh, 0);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
if (u == 0) {
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0);
} /* end if */
} /* end for */
state.man_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width;
/* Second row */
for (u = 0; u < cparam->managed.width; u++) {
state.man_alloc_size += DBLOCK_SIZE(fh, 1);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* (Account for doubling root indirect block for rows 3-4 */
for (u = 0; u < 2; u++) {
state.man_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u + 2) * cparam->managed.width;
} /* end for */
/* Rows 3-4 */
for (u = 0; u < 2; u++) {
obj_size = (size_t)DBLOCK_SIZE(fh, u + 2) / 2;
for (v = 0; v < cparam->managed.width; v++) {
state.man_alloc_size += DBLOCK_SIZE(fh, u + 2);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* (Account for doubling root indirect block for rows 5-8 */
for (u = 0; u < 4; u++) {
state.man_size += DBLOCK_SIZE(fh, u + 4) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u + 4) * cparam->managed.width;
} /* end for */
/* Rows 5-8 */
for (u = 0; u < 4; u++) {
obj_size = (size_t)DBLOCK_SIZE(fh, u + 4) / 2;
for (v = 0; v < cparam->managed.width; v++) {
state.man_alloc_size += DBLOCK_SIZE(fh, u + 4);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* (Account for doubling root indirect block for rows 9-16 */
for (u = 0; u < 8; u++) {
state.man_size += DBLOCK_SIZE(fh, u + 8) * cparam->managed.width;
state.man_free_space += DBLOCK_FREE(fh, u + 8) * cparam->managed.width;
} /* end for */
/* Row 9 (last direct block row) */
obj_size = (size_t)DBLOCK_SIZE(fh, 8) / 2;
for (v = 0; v < cparam->managed.width; v++) {
state.man_alloc_size += DBLOCK_SIZE(fh, 8);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Go back and backfill all root block's direct blocks */
for (u = 0; u < root_direct_rows; u++) {
obj_size = (size_t)DBLOCK_FREE(fh, u) - ((size_t)DBLOCK_SIZE(fh, u) / 2);
for (v = 0; v < cparam->managed.width; v++)
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_frag_direct() */
/*-------------------------------------------------------------------------
* Function: test_man_frag_2nd_direct
*
* Purpose: Test filling all direct blocks in root indirect block, then
* inserting small object to fit into each direct block
* in 2nd level indirect block, but not to share a block with
* another object.
* Then, go back and fill in the space in the blocks skipped.
*
* Then, go back and remove all the objects
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_frag_2nd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned
num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc = "fill root direct blocks, then fragment 2nd level indirect block's direct "
"blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Compute # of bits used in first row */
num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects small enough to fit into each direct block, but not to
* share them with other objects of the same size.
*/
for (u = 0; u < num_first_indirect_rows; u++) {
obj_size = (size_t)DBLOCK_SIZE(fh, u) / 2;
for (v = 0; v < cparam->managed.width; v++) {
state.man_alloc_size += DBLOCK_SIZE(fh, u);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Go back and backfill all 2nd level indirect block's direct blocks */
for (u = 0; u < num_first_indirect_rows; u++) {
obj_size = (size_t)DBLOCK_FREE(fh, u) - ((size_t)DBLOCK_SIZE(fh, u) / 2);
for (v = 0; v < cparam->managed.width; v++)
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_frag_2nd_direct() */
/*-------------------------------------------------------------------------
* Function: test_man_frag_3rd_direct
*
* Purpose: Test filling all direct blocks in root indirect block and
* all 2nd level indirect blocks, then
* inserting small object to fit into each direct block
* in 3rd level indirect block, but not to share a block with
* another object.
* Then, go back and fill in the space in the blocks skipped.
*
* Then, go back and remove all objects
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
unsigned root_direct_rows; /* Number of rows in root indirect block */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t fill_size; /* Size of objects for "bulk" filled blocks */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u, v; /* Local index variables */
/* Test description */
const char *base_desc =
"fill root direct blocks and 2nd level indirect blocks, then fragment 3rd level indirect block's "
"direct blocks, then backfill and extend, then remove all objects";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Compute # of direct rows in root indirect block */
root_direct_rows = DTABLE_MAX_DROWS(fh);
/* Fill direct blocks in root indirect block */
if (fill_root_direct(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Fill all rows of 2nd level indirect blocks in root indirect block */
if (fill_all_2nd_indirect_rows(fh, fill_size, &state, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert objects small enough to fit into each direct block, but not to
* share them with other objects of the same size.
*/
for (u = 0; u < root_direct_rows; u++) {
obj_size = (size_t)DBLOCK_SIZE(fh, u) / 2;
for (v = 0; v < cparam->managed.width; v++) {
state.man_alloc_size += DBLOCK_SIZE(fh, u);
if (add_obj(fh, (size_t)10, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
} /* end for */
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Go back and backfill all 3rd level indirect block's direct blocks */
for (u = 0; u < root_direct_rows; u++) {
obj_size = (size_t)DBLOCK_FREE(fh, u) - ((size_t)DBLOCK_SIZE(fh, u) / 2);
for (v = 0; v < cparam->managed.width; v++)
if (add_obj(fh, (size_t)20, obj_size, &state, &keep_ids))
TEST_ERROR;
} /* end for */
/* Perform common file & heap close operations */
if (close_heap(filename, fapl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0)
TEST_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_man_frag_3rd_direct() */
/*-------------------------------------------------------------------------
* Function: test_huge_insert_one
*
* Purpose: Test inserting one huge object in the heap
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
unsigned char *heap_id = NULL; /* Heap ID for object */
size_t obj_size; /* Size of object */
size_t robj_size; /* Size of object read */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert one huge object, then remove";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)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, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = obj_size;
state.huge_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in huge object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Remove object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = 0;
state.huge_nobjs = 0;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* Free resources */
H5MM_xfree(heap_id);
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(heap_id);
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_huge_insert_one() */
/*-------------------------------------------------------------------------
* Function: test_huge_insert_two
*
* Purpose: Test inserting two huge objects in the heap
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_huge_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
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 */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert two huge objects, then remove";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id2 = (unsigned char *)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, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = obj_size;
state.huge_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in huge object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert second object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 1;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id2) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id2, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs = 2;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in second huge object */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id2, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = obj_size;
state.huge_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = 0;
state.huge_nobjs = 0;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
else {
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = obj_size;
state.huge_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = 0;
state.huge_nobjs = 0;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end else */
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_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);
/* All tests passed */
PASSED();
return (0);
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);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_huge_insert_two() */
/*-------------------------------------------------------------------------
* Function: test_huge_insert_three
*
* Purpose: Test inserting three huge objects in the heap
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
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 */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert three huge objects, then remove";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id2 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id3 = (unsigned char *)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, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = obj_size;
state.huge_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in first huge object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert second object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id2) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id2, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs = 2;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in second huge object */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id2, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert third object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 3;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id3) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id3, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs = 3;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in third huge object */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id3, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove first object from heap */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove third object from heap */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
else {
/* Remove third object from heap */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove first object from heap */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end else */
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_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);
/* All tests passed */
PASSED();
return (0);
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);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_huge_insert_three() */
/*-------------------------------------------------------------------------
* Function: test_huge_insert_mix
*
* Purpose: Test inserting a mix of 'normal' & 'huge' objects in the heap
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
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 */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert mix of normal & huge objects, then remove";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id2 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id3 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id4 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id5 = (unsigned char *)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, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in first huge object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert second object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id2) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id2, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in second huge object */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id2, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert third object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 3;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id3) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id3, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in third huge object */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id3, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert fourth object small enough to fit into 'normal' heap blocks */
obj_size = (size_t)DBLOCK_SIZE(fh, 0) + 1;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id4) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id4, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_MAN)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_alloc_size = DBLOCK_SIZE(fh, 2);
state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += DBLOCK_FREE(fh, 2) - obj_size;
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 2);
state.man_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in fourth ('normal') object */
if (H5HF_get_obj_len(fh, heap_id4, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id4, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert fifth object small enough to fit into 'normal' heap blocks */
obj_size = (size_t)DBLOCK_SIZE(fh, 3) + 1;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id5) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id5, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_MAN)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (account for doubling of root indirect block) */
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 4);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 5);
state.man_alloc_size += DBLOCK_SIZE(fh, 4);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3);
state.man_free_space += DBLOCK_FREE(fh, 4) - obj_size;
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 4);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 5);
state.man_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in fifth ('normal') object */
if (H5HF_get_obj_len(fh, heap_id5, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id5, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove first object from heap */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove third object from heap */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove fourth ('normal') object from heap */
if (H5HF_remove(fh, heap_id4) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Remove fifth ('normal') object from heap */
if (H5HF_remove(fh, heap_id5) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
} /* end if */
else {
/* Remove fifth ('normal') object from heap */
if (H5HF_remove(fh, heap_id5) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Remove fourth ('normal') object from heap */
if (H5HF_remove(fh, heap_id4) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Reset 'managed' object statistics after they are all removed */
state.man_nobjs = 0;
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
/* Remove third object from heap */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
} /* end else */
/* Check up on heap... */
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_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);
/* All tests passed */
PASSED();
return (0);
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);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_huge_insert_mix() */
/*-------------------------------------------------------------------------
* Function: test_filtered_huge
*
* Purpose: Test storing 'huge' object in a heap with I/O filters
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_filtered_huge(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
size_t id_len; /* Size of fractal heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
unsigned char *heap_id = NULL; /* Heap ID for object */
size_t obj_size; /* Size of object */
size_t robj_size; /* Size of object read */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
unsigned deflate_level; /* Deflation level */
size_t old_actual_id_len = 0; /* Old actual ID length */
bool huge_ids_direct; /* Are 'huge' objects directly accessed? */
bool pline_init = false; /* Whether the I/O pipeline has been initialized */
/* Test description */
const char *base_desc = "insert 'huge' object into heap with I/O filters, then remove";
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
FAIL_STACK_ERROR;
pline_init = true;
/* Adjust actual ID length, if asking for IDs that can directly access 'huge' objects */
if (cparam->id_len == 1) {
old_actual_id_len = tparam->actual_id_len;
tparam->actual_id_len = 29; /* 1 + 8 (file address size) + 8 (file length size) + 4 (filter mask
length) + 8 (object length size) */
} /* end if */
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
/* Make certain that 'huge' object's heap IDs are correct form */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len != tparam->actual_id_len)
TEST_ERROR;
if (H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0)
FAIL_STACK_ERROR;
if (cparam->id_len == 1) {
if (huge_ids_direct != true)
TEST_ERROR;
} /* end if */
else if (tparam->actual_id_len >= 29) {
if (huge_ids_direct != true)
TEST_ERROR;
} /* end if */
else {
if (huge_ids_direct != false)
TEST_ERROR;
} /* end else */
/* Insert object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 1;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
#ifdef QAK
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
#endif /* QAK */
/* Check up on heap... */
state.huge_size = obj_size;
state.huge_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in huge object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Remove object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size = 0;
state.huge_nobjs = 0;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* Reset actual ID length, if asking for IDs that can directly access 'huge' objects */
if (cparam->id_len == 1)
tparam->actual_id_len = old_actual_id_len;
/* Free resources */
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
H5MM_xfree(heap_id);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(heap_id);
if (fh)
H5HF_close(fh);
if (pline_init)
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_filtered_huge() */
/*-------------------------------------------------------------------------
* Function: test_tiny_insert_one
*
* Purpose: Test inserting one tiny object in the heap
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_tiny_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
unsigned char *heap_id = NULL; /* Heap ID for object */
size_t obj_size; /* Size of object */
size_t robj_size; /* Size of object read */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert one tiny object, then remove";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
/* Make certain that 'tiny' 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 small enough to encode in heap ID */
obj_size = tparam->actual_id_len - 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_TINY)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = obj_size;
state.tiny_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in tiny object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Remove object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = 0;
state.tiny_nobjs = 0;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* Free resources */
H5MM_xfree(heap_id);
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(heap_id);
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_tiny_insert_one() */
/*-------------------------------------------------------------------------
* Function: test_tiny_insert_two
*
* Purpose: Test inserting two tiny objects in the heap
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_tiny_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
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 */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert two tiny objects, then remove";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id2 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
/* Make certain that 'tiny' 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 small enough to encode in heap ID */
obj_size = tparam->actual_id_len - 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_TINY)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = obj_size;
state.tiny_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in tiny object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert second object small enough to encode in heap ID */
obj_size = tparam->actual_id_len - 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id2) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id2, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_TINY)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size += obj_size;
state.tiny_nobjs = 2;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in second tiny object */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id2, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = obj_size;
state.tiny_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = 0;
state.tiny_nobjs = 0;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
else {
/* Remove second object from heap */
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = obj_size;
state.tiny_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = 0;
state.tiny_nobjs = 0;
if (check_stats(fh, &state))
TEST_ERROR;
} /* end else */
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_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);
/* All tests passed */
PASSED();
return (0);
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);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_tiny_insert_two() */
/*-------------------------------------------------------------------------
* Function: test_tiny_insert_mix
*
* Purpose: Test inserting a mix of 'normal', 'huge' & 'tiny' objects in
* the heap
*
* Then, remove all the objects, in various ways
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_tiny_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
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 */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
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 */
unsigned char *heap_id6 = NULL; /* Heap ID for sixth object */
unsigned char *heap_id7 = NULL; /* Heap ID for seventh object */
size_t obj_size; /* Size of object */
size_t robj_size; /* Size of object read */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
/* Test description */
const char *base_desc = "insert mix of normal, huge & tiny objects, then remove";
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Allocate heap ID(s) */
if (NULL == (heap_id = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id2 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id3 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id4 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id5 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id6 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
if (NULL == (heap_id7 = (unsigned char *)H5MM_malloc(tparam->actual_id_len)))
TEST_ERROR;
/* Make certain that 'tiny' 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, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in first huge object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Check 'op' functionality on first huge object */
memset(shared_robj_g, 0, obj_size);
if (H5HF_op(fh, heap_id, op_memcpy, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert second object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id2) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id2, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in second huge object */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id2, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Check 'op' functionality on second huge object */
memset(shared_robj_g, 0, obj_size);
if (H5HF_op(fh, heap_id2, op_memcpy, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert third object too large for managed heap blocks */
obj_size = SMALL_STAND_SIZE + 3;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id3) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id3, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_HUGE)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size += obj_size;
state.huge_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in third huge object */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id3, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Check 'op' functionality on third huge object */
memset(shared_robj_g, 0, obj_size);
if (H5HF_op(fh, heap_id3, op_memcpy, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert fourth object small enough to fit into 'normal' heap blocks */
obj_size = (size_t)DBLOCK_SIZE(fh, 0) + 1;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id4) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id4, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_MAN)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2);
state.man_alloc_size = DBLOCK_SIZE(fh, 2);
state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1);
state.man_free_space += DBLOCK_FREE(fh, 2) - obj_size;
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 2);
state.man_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in fourth ('normal') object */
if (H5HF_get_obj_len(fh, heap_id4, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id4, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Check 'op' functionality on fourth ('normal') object */
memset(shared_robj_g, 0, obj_size);
if (H5HF_op(fh, heap_id4, op_memcpy, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert fifth object small enough to fit into 'normal' heap blocks */
obj_size = (size_t)DBLOCK_SIZE(fh, 3) + 1;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id5) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id5, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_MAN)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
/* (account for doubling of root indirect block) */
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 4);
state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 5);
state.man_alloc_size += DBLOCK_SIZE(fh, 4);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3);
state.man_free_space += DBLOCK_FREE(fh, 4) - obj_size;
state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 4);
state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 5);
state.man_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in fifth ('normal') object */
if (H5HF_get_obj_len(fh, heap_id5, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id5, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Check 'op' functionality on fifth ('normal') object */
memset(shared_robj_g, 0, obj_size);
if (H5HF_op(fh, heap_id5, op_memcpy, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert sixth object small enough to encode in heap ID */
obj_size = tparam->actual_id_len - 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id6) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id6, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_TINY)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size = obj_size;
state.tiny_nobjs = 1;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in tiny object */
if (H5HF_get_obj_len(fh, heap_id6, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id6, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Check 'op' functionality on sixth ('tiny') object */
memset(shared_robj_g, 0, obj_size);
if (H5HF_op(fh, heap_id6, op_memcpy, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Insert seventh object small enough to encode in heap ID */
obj_size = tparam->actual_id_len - 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id7) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id7, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_TINY)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size += obj_size;
state.tiny_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in tiny object */
if (H5HF_get_obj_len(fh, heap_id7, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id7, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Check 'op' functionality on seventh ('tiny') object */
memset(shared_robj_g, 0, obj_size);
if (H5HF_op(fh, heap_id7, op_memcpy, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove first object from heap */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove third object from heap */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove fourth ('normal') object from heap */
if (H5HF_remove(fh, heap_id4) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Remove fifth ('normal') object from heap */
if (H5HF_remove(fh, heap_id5) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Reset 'managed' object statistics after they are all removed */
state.man_nobjs = 0;
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
/* Remove sixth object from heap */
if (H5HF_get_obj_len(fh, heap_id6, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id6) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size -= robj_size;
state.tiny_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove seventh object from heap */
if (H5HF_remove(fh, heap_id7) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
} /* end if */
else {
/* Remove seventh object from heap */
if (H5HF_get_obj_len(fh, heap_id7, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id7) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size -= robj_size;
state.tiny_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove sixth object from heap */
if (H5HF_get_obj_len(fh, heap_id6, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id6) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.tiny_size -= robj_size;
state.tiny_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove fifth ('normal') object from heap */
if (H5HF_remove(fh, heap_id5) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Remove fourth ('normal') object from heap */
if (H5HF_remove(fh, heap_id4) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Reset 'managed' object statistics after they are all removed */
state.man_nobjs = 0;
state.man_size = 0;
state.man_alloc_size = 0;
state.man_free_space = 0;
/* Remove third object from heap */
if (H5HF_get_obj_len(fh, heap_id3, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id3) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove second object from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
state.huge_size -= robj_size;
state.huge_nobjs--;
if (check_stats(fh, &state))
TEST_ERROR;
/* Remove first object from heap */
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
} /* end else */
/* Check up on heap... */
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_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(heap_id6);
H5MM_xfree(heap_id7);
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
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(heap_id6);
H5MM_xfree(heap_id7);
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_tiny_insert_mix() */
/*-------------------------------------------------------------------------
* Function: test_filtered_man_root_direct
*
* Purpose: Test storing one 'managed' object in a heap with I/O filters
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_filtered_man_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
#ifdef NOT_YET
h5_stat_size_t file_size; /* Size of file currently */
#endif /* NOT_YET */
unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */
size_t obj_size; /* Size of object */
size_t robj_size; /* Size of object read */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
unsigned deflate_level; /* Deflation level */
/* Test description */
const char *base_desc = "insert one 'managed' object into heap with I/O filters, then remove";
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
FAIL_STACK_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Insert object small enough to fit into direct heap block */
obj_size = (size_t)DBLOCK_SIZE(fh, 0) / 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_MAN)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Check up on heap... */
state.man_size = DBLOCK_SIZE(fh, 0);
state.man_alloc_size = DBLOCK_SIZE(fh, 0);
state.man_free_space = DBLOCK_FREE(fh, 0) - obj_size;
state.man_nobjs++;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in ('normal') object */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Remove object from heap */
if (H5HF_get_obj_len(fh, heap_id, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Check up on heap... */
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Needs file free space to be persistent */
#ifdef NOT_YET
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
#endif /* NOT_YET */
/* Free resources */
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_filtered_man_root_direct() */
/*-------------------------------------------------------------------------
* Function: test_filtered_man_root_indirect
*
* Purpose: Test storing several objects in a 'managed heap with I/O filters
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_filtered_man_root_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
#ifdef NOT_YET
h5_stat_size_t file_size; /* Size of file currently */
#endif /* NOT_YET */
unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for object #1 */
unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for object #2 */
size_t obj_size; /* Size of object */
size_t robj_size; /* Size of object read */
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
unsigned deflate_level; /* Deflation level */
/* Test description */
const char *base_desc = "insert two 'managed' objects into heap with I/O filters, then remove";
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
FAIL_STACK_ERROR;
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Perform common test initialization operations */
if (begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
TEST_ERROR;
/* Insert object #1, small enough to fit into direct heap block */
obj_size = (size_t)DBLOCK_SIZE(fh, 0) / 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id1) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id1, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_MAN)
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Insert object #2, small enough to fit into direct heap block */
obj_size = (size_t)DBLOCK_SIZE(fh, 0) / 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, heap_id2) < 0)
FAIL_STACK_ERROR;
if (H5HF_get_id_type_test(heap_id2, &obj_type) < 0)
FAIL_STACK_ERROR;
if (obj_type != H5HF_ID_TYPE_MAN)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Check up on heap... */
state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
state.man_alloc_size = 2 * DBLOCK_SIZE(fh, 0);
state.man_free_space = (cparam->managed.width * DBLOCK_FREE(fh, 0)) - (obj_size * 2);
state.man_nobjs += 2;
if (check_stats(fh, &state))
TEST_ERROR;
/* Read in ('normal') object #1 */
if (H5HF_get_obj_len(fh, heap_id1, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id1, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Read in ('normal') object #2 */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (obj_size != robj_size)
TEST_ERROR;
memset(shared_robj_g, 0, obj_size);
if (H5HF_read(fh, heap_id2, shared_robj_g) < 0)
FAIL_STACK_ERROR;
if (memcmp(shared_wobj_g, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
if (tparam->del_dir == FHEAP_DEL_FORWARD) {
/* Remove object #1 from heap */
if (H5HF_get_obj_len(fh, heap_id1, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id1) < 0)
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Remove object #2 from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Check up on heap... */
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Check up on heap... */
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
else {
/* Remove object #2 from heap */
if (H5HF_get_obj_len(fh, heap_id2, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id2) < 0)
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Remove object #1 from heap */
if (H5HF_get_obj_len(fh, heap_id1, &robj_size) < 0)
FAIL_STACK_ERROR;
if (H5HF_remove(fh, heap_id1) < 0)
FAIL_STACK_ERROR;
/* Check up on heap... */
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Check up on heap... */
memset(&state, 0, sizeof(fheap_heap_state_t));
if (check_stats(fh, &state))
TEST_ERROR;
} /* end else */
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Needs file free space to be persistent */
#ifdef NOT_YET
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
#endif /* NOT_YET */
/* Free resources */
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_filtered_man_root_indirect() */
/*-------------------------------------------------------------------------
* Function: test_random
*
* Purpose: Test inserting random sized objects into a heap, and read
* them back.
*
* Then, go back and remove all objects
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_random(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
unsigned long seed = 0; /* Random # seed */
hsize_t total_obj_added; /* Size of objects added */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
size_t obj_size; /* Size of object */
size_t obj_loc; /* Location of object in buffer */
fheap_heap_state_t state; /* State of fractal heap */
size_t u; /* Local index variable */
/* Initialize the heap ID structure */
memset(&keep_ids, 0, sizeof(fheap_heap_ids_t));
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Check if we are compressing the blocks */
if (tparam->comp == FHEAP_TEST_COMPRESS) {
unsigned deflate_level; /* Deflation level */
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) <
0)
FAIL_STACK_ERROR;
} /* end if */
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Get information about heap ID lengths */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > MAX_HEAP_ID_LEN)
TEST_ERROR;
/*
* Display testing message
*/
if (tparam->del_dir == FHEAP_DEL_HEAP) {
if (tparam->comp == FHEAP_TEST_COMPRESS)
TESTING("inserting random-sized objects in heap with compressed blocks, then remove all objects "
"(all - deleting heap)");
else
TESTING("inserting random-sized objects, then remove all objects (all - deleting heap)");
} /* end if */
else {
if (tparam->comp == FHEAP_TEST_COMPRESS)
TESTING("inserting random-sized objects in heap with compressed blocks, then remove all objects "
"(all - random)");
else
TESTING("inserting random-sized objects, then remove all objects (all - random)");
} /* end else */
/* Choose random # seed */
seed = (unsigned long)time(NULL);
#if 0
/* seed = (unsigned long)1156158635; */
fprintf(stderr, "Random # seed was: %lu\n", seed);
#endif
srand((unsigned)seed);
/* Loop over adding objects to the heap, until the size limit is reached */
total_obj_added = 0;
while (total_obj_added < size_limit) {
/* Choose a random size of object (from 1 up to above standalone block size limit) */
obj_size = (((uint32_t)rand() % (tmp_cparam.max_man_size + 255)) + 1);
obj_loc = (tmp_cparam.max_man_size + 255) - obj_size;
/* Insert object */
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Increment the amount of objects added */
total_obj_added += obj_size;
} /* end while */
/* Randomize the order of the IDs kept */
for (u = 0; u < keep_ids.num_ids; u++) {
size_t pos; /* Position to swap with */
/* Choose a position to swap with */
/* (0 is current position) */
pos = ((size_t)rand() % (keep_ids.num_ids - u));
/* If we chose a different position, swap with it */
if (pos > 0) {
unsigned char temp_id[MAX_HEAP_ID_LEN]; /* Temp. heap ID holder */
/* Swap current position with future position */
/* (just swap the heap ID, the len & offset isn't used */
memcpy(temp_id, &keep_ids.ids[u * id_len], id_len);
memcpy(&keep_ids.ids[u * id_len], &keep_ids.ids[(u + pos) * id_len], id_len);
memcpy(&keep_ids.ids[(u + pos) * id_len], temp_id, id_len);
} /* end if */
} /* end for */
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Delete objects inserted */
for (u = 0; u < keep_ids.num_ids; u++) {
/* Remove object from heap */
if (H5HF_remove(fh, &keep_ids.ids[id_len * u]) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
} /* end for */
/* Check up on heap... */
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* Free resources */
if (tparam->comp == FHEAP_TEST_COMPRESS)
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
fprintf(stderr, "Random # seed was: %lu\n", seed);
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (tparam->comp == FHEAP_TEST_COMPRESS)
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_random() */
/*-------------------------------------------------------------------------
* Function: test_random_pow2
*
* Purpose: Test inserting random sized objects with a "power of 2
* distribution" (which favors small objects) into a heap,
* and read them back.
*
* Then, go back and remove all objects
*
* Return: Success: 0
*
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_random_pow2(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
unsigned long seed = 0; /* Random # seed */
hsize_t total_obj_added; /* Size of objects added */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
h5_stat_size_t file_size; /* Size of file currently */
size_t obj_size; /* Size of object */
size_t obj_loc; /* Location of object in buffer */
fheap_heap_state_t state; /* State of fractal heap */
size_t u; /* Local index variable */
/* Initialize the heap ID structure */
memset(&keep_ids, 0, sizeof(fheap_heap_ids_t));
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Check if we are compressing the blocks */
if (tparam->comp == FHEAP_TEST_COMPRESS) {
unsigned deflate_level; /* Deflation level */
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) <
0)
FAIL_STACK_ERROR;
} /* end if */
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Get information about heap ID lengths */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > MAX_HEAP_ID_LEN)
TEST_ERROR;
/*
* Display testing message
*/
if (tparam->del_dir == FHEAP_DEL_HEAP) {
if (tparam->comp == FHEAP_TEST_COMPRESS)
TESTING("inserting random-sized objects with power of 2 distribution in heap with compressed "
"blocks, then remove all objects (all - deleting heap)");
else
TESTING("inserting random-sized objects with power of 2 distribution, then remove all objects "
"(all - deleting heap)");
} /* end if */
else {
if (tparam->comp == FHEAP_TEST_COMPRESS)
TESTING("inserting random-sized objects with power of 2 distribution in heap with compressed "
"blocks, then remove all objects (all - random)");
else
TESTING("inserting random-sized objects with power of 2 distribution, then remove all objects "
"(all - random)");
} /* end else */
/* Choose random # seed */
seed = (unsigned long)time(NULL);
#if 0
/* seed = (unsigned long)1155181717; */
fprintf(stderr, "Random # seed was: %lu\n", seed);
#endif
srand((unsigned)seed);
/* Loop over adding objects to the heap, until the size limit is reached */
total_obj_added = 0;
while (total_obj_added < size_limit) {
size_t size_range = (tmp_cparam.managed.start_block_size / 8); /* Object size range */
/* Determine the size of the range for this object */
/* (50% of the objects inserted will use the initial size range,
* 25% of the objects will be twice as large, 12.5% will be
* four times larger, etc.)
*/
while (rand() < (RAND_MAX / 2) && size_range < tmp_cparam.max_man_size)
size_range *= 2;
if (size_range > (tmp_cparam.max_man_size + 255))
size_range = tmp_cparam.max_man_size + 255;
/* Choose a random size of object (from 1 up to stand alone block size) */
obj_size = (((unsigned)rand() % (size_range - 1)) + 1);
obj_loc = (tmp_cparam.max_man_size + 255) - obj_size;
/* Insert object */
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Increment the amount of objects added */
total_obj_added += obj_size;
} /* end while */
/* Randomize the order of the IDs kept */
for (u = 0; u < keep_ids.num_ids; u++) {
size_t pos; /* Position to swap with */
/* Choose a position to swap with */
/* (0 is current position) */
pos = ((size_t)rand() % (keep_ids.num_ids - u));
/* If we chose a different position, swap with it */
if (pos > 0) {
unsigned char temp_id[MAX_HEAP_ID_LEN]; /* Temp. heap ID holder */
/* Swap current position with future position */
/* (just swap the heap ID, the len & offset isn't used */
memcpy(temp_id, &keep_ids.ids[u * id_len], id_len);
memcpy(&keep_ids.ids[u * id_len], &keep_ids.ids[(u + pos) * id_len], id_len);
memcpy(&keep_ids.ids[(u + pos) * id_len], temp_id, id_len);
} /* end if */
} /* end for */
/* Delete individual objects, if we won't be deleting the entire heap later */
if (tparam->del_dir != FHEAP_DEL_HEAP) {
/* Delete objects inserted */
for (u = 0; u < keep_ids.num_ids; u++) {
/* Remove object from heap */
if (H5HF_remove(fh, &keep_ids.ids[id_len * u]) < 0)
FAIL_STACK_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
} /* end for */
/* Check up on heap... */
if (check_stats(fh, &state))
TEST_ERROR;
} /* end if */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Check for deleting the entire heap */
if (tparam->del_dir == FHEAP_DEL_HEAP) {
/* Delete heap */
if (H5HF_delete(f, fh_addr) < 0)
FAIL_STACK_ERROR;
} /* end if */
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Get the size of the file */
if ((file_size = h5_get_file_size(filename, fapl)) < 0)
TEST_ERROR;
/* Verify the file is correct size */
if (file_size != empty_size)
TEST_ERROR;
/* Free resources */
if (tparam->comp == FHEAP_TEST_COMPRESS)
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
fprintf(stderr, "Random # seed was: %lu\n", seed);
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
if (tparam->comp == FHEAP_TEST_COMPRESS)
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_random_pow2() */
/*-------------------------------------------------------------------------
* Function: test_write
*
* Purpose: Test inserting objects, then changing the value for them.
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
/* Custom filter used to verify that the filters are actually called and do not
* just silently fail */
static bool test_write_filter_called;
static size_t
test_write_filter(unsigned int H5_ATTR_UNUSED flags, size_t H5_ATTR_UNUSED cd_nelmts,
const unsigned int H5_ATTR_UNUSED cd_values[], size_t nbytes,
size_t H5_ATTR_UNUSED *buf_size, void H5_ATTR_UNUSED **buf)
{
test_write_filter_called = true;
return nbytes;
} /* end link_filter_filter */
static unsigned
test_write(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
H5HF_create_t tmp_cparam; /* Local heap creation parameters */
size_t id_len; /* Size of fractal heap IDs */
unsigned char tiny_heap_id[HEAP_ID_LEN]; /* Heap ID for 'tiny' object */
unsigned char huge_heap_id[HEAP_ID_LEN]; /* Heap ID for 'huge' object */
bool id_changed = false; /* Whether the heap ID changed */
unsigned char *rewrite_obj = NULL; /* Pointer to re-write buffer for objects */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t obj_loc; /* Location of object in buffer */
fheap_heap_state_t state; /* State of fractal heap */
unsigned u; /* Local index variable */
herr_t ret; /* Generic return value */
/*
* Display testing message
*/
if (tparam->comp == FHEAP_TEST_COMPRESS)
TESTING("writing objects in heap with compressed blocks");
else
TESTING("writing objects in heap");
/* Initialize the heap ID structure */
memset(&keep_ids, 0, sizeof(fheap_heap_ids_t));
/* Copy heap creation properties */
memcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
/* Check if we are compressing the blocks */
if (tparam->comp == FHEAP_TEST_COMPRESS) {
H5Z_class2_t filter_class; /* Custom filter */
unsigned deflate_level; /* Deflation level */
/* Set an I/O filter for heap data */
deflate_level = 6;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) <
0)
FAIL_STACK_ERROR;
/* Register and append custom filter */
filter_class.version = H5Z_CLASS_T_VERS;
filter_class.id = H5Z_FILTER_RESERVED + 43;
filter_class.encoder_present = true;
filter_class.decoder_present = true;
filter_class.name = "custom_fheap_filter";
filter_class.can_apply = NULL;
filter_class.set_local = NULL;
filter_class.filter = test_write_filter;
if (H5Zregister(&filter_class) < 0)
TEST_ERROR;
if (H5Z_append(&tmp_cparam.pline, H5Z_FILTER_RESERVED + 43, 0, (size_t)0, NULL) < 0)
FAIL_STACK_ERROR;
test_write_filter_called = false;
} /* end if */
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Get information about heap ID lengths */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > MAX_HEAP_ID_LEN)
TEST_ERROR;
/* Create 'tiny' and 'huge' objects */
obj_size = id_len / 2;
if (H5HF_insert(fh, obj_size, shared_wobj_g, tiny_heap_id) < 0)
FAIL_STACK_ERROR;
obj_size = tmp_cparam.max_man_size + 1;
if (H5HF_insert(fh, obj_size, shared_wobj_g, huge_heap_id) < 0)
FAIL_STACK_ERROR;
/* Verify that writing to 'huge' objects works for un-filtered heaps */
H5E_BEGIN_TRY
{
ret = H5HF_write(fh, huge_heap_id, &id_changed, shared_wobj_g);
}
H5E_END_TRY
assert(!id_changed);
if (tparam->comp == FHEAP_TEST_COMPRESS) {
if (ret >= 0)
TEST_ERROR;
} /* end if */
else {
if (ret < 0)
FAIL_STACK_ERROR;
} /* end else */
/* Verify that writing to 'tiny' objects return failure (for now) */
H5E_BEGIN_TRY
{
ret = H5HF_write(fh, tiny_heap_id, &id_changed, shared_wobj_g);
}
H5E_END_TRY
assert(!id_changed);
if (ret >= 0)
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Verify that the custom filter has been applied for the huge object (if
* applicable) */
if (tparam->comp == FHEAP_TEST_COMPRESS) {
if (!test_write_filter_called)
TEST_ERROR;
test_write_filter_called = false;
} /* end if */
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Initialize data to overwrite with */
rewrite_obj = (unsigned char *)H5MM_malloc(shared_obj_size_g);
for (u = 0; u < shared_obj_size_g; u++)
rewrite_obj[u] = (unsigned char)(shared_wobj_g[u] * 2);
/* Insert different sized objects, but stay out of "tiny" and "huge" zones */
obj_size = 20;
for (u = 0; u < 40; u++) {
obj_loc = u;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
/* Check for closing & re-opening the heap */
if (reopen_heap(f, &fh, fh_addr, tparam) < 0)
TEST_ERROR;
/* Overwrite data just written */
if (H5HF_write(fh, &keep_ids.ids[id_len * u], &id_changed, rewrite_obj) < 0)
FAIL_STACK_ERROR;
assert(!id_changed);
/* Read data back in */
if (H5HF_read(fh, &keep_ids.ids[id_len * u], shared_robj_g) < 0)
FAIL_STACK_ERROR;
/* Compare data read in */
if (memcmp(rewrite_obj, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Change size of data to write */
if (u < 20)
obj_size = (size_t)((float)obj_size * 1.3F);
else
obj_size = (size_t)((float)obj_size / 1.3F);
} /* end for */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Verify that the custom filter has been applied to the managed objects (if
* applicable) */
if (tparam->comp == FHEAP_TEST_COMPRESS)
if (!test_write_filter_called)
TEST_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Verify changed objects */
obj_size = 20;
for (u = 0; u < 40; u++) {
/* Read data back in */
if (H5HF_read(fh, &keep_ids.ids[id_len * u], shared_robj_g) < 0)
FAIL_STACK_ERROR;
/* Compare data read in */
if (memcmp(rewrite_obj, shared_robj_g, obj_size) != 0)
TEST_ERROR;
/* Change size of data to write */
if (u < 20)
obj_size = (size_t)((float)obj_size * 1.3F);
else
obj_size = (size_t)((float)obj_size / 1.3F);
} /* end for */
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Free resources */
if (tparam->comp == FHEAP_TEST_COMPRESS)
H5O_msg_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
H5MM_xfree(rewrite_obj);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
H5MM_xfree(rewrite_obj);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_write() */
/*-------------------------------------------------------------------------
* Function: test_bug1
*
* Purpose: Test inserting several objects, then deleting one and
* re-inserting an object, along with opening and closing
* the file.
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static unsigned
test_bug1(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = H5I_INVALID_HID; /* File ID */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
h5_stat_size_t empty_size; /* Size of a file with an empty heap */
size_t obj_size; /* Size of object */
size_t obj_loc; /* Location of object in buffer */
fheap_heap_state_t state; /* State of fractal heap */
/*
* Display testing message
*/
TESTING("bug1: inserting several objects & removing one, then re-inserting");
/* Initialize the heap ID structure */
memset(&keep_ids, 0, sizeof(fheap_heap_ids_t));
/* Perform common file & heap open operations */
if (open_heap(filename, fapl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR;
/* Get information about heap ID lengths */
if (H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR;
if (id_len > MAX_HEAP_ID_LEN)
TEST_ERROR;
/* Insert objects */
obj_size = 44;
obj_loc = 1;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
obj_size = 484;
obj_loc = 2;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
obj_size = 168;
obj_loc = 3;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
obj_size = 96;
obj_loc = 4;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
obj_size = 568;
obj_loc = 5;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
obj_size = 568;
obj_loc = 6;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Remove one of the objects */
if (H5HF_remove(fh, &keep_ids.ids[id_len * 4]) < 0)
FAIL_STACK_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Re-open the file */
if ((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR;
/* Get a pointer to the internal file object */
if (NULL == (f = (H5F_t *)H5VL_object(file)))
FAIL_STACK_ERROR;
/* Ignore metadata tags in the file's cache */
if (H5AC_ignore_tags(f) < 0)
FAIL_STACK_ERROR;
/* Re-open the heap */
if (NULL == (fh = H5HF_open(f, fh_addr)))
FAIL_STACK_ERROR;
/* Insert another object */
obj_size = 208;
obj_loc = 6;
if (add_obj(fh, obj_loc, obj_size, NULL, &keep_ids))
TEST_ERROR;
/* Close the fractal heap */
if (H5HF_close(fh) < 0)
FAIL_STACK_ERROR;
fh = NULL;
/* Close the file */
if (H5Fclose(file) < 0)
FAIL_STACK_ERROR;
/* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
/* All tests passed */
PASSED();
return (0);
error:
H5E_BEGIN_TRY
{
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
if (fh)
H5HF_close(fh);
H5Fclose(file);
}
H5E_END_TRY
return (1);
} /* test_bug1() */
/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test the fractal heap code
*
* Return: Success:
*
* Failure:
*
*-------------------------------------------------------------------------
*/
int
main(void)
{
fheap_test_param_t tparam; /* Testing parameters */
H5HF_create_t small_cparam; /* Creation parameters for "small" heap */
H5HF_create_t large_cparam; /* Creation parameters for "large" heap */
hid_t fapl = H5I_INVALID_HID, def_fapl = H5I_INVALID_HID; /* File access property list for data files */
hid_t pb_fapl = H5I_INVALID_HID; /* File access property list for data files */
hid_t fcpl = H5I_INVALID_HID, def_fcpl = H5I_INVALID_HID; /* File creation property list for data files */
fheap_test_type_t curr_test; /* Current test being worked on */
unsigned u, v; /* Local index variable */
unsigned nerrors = 0; /* Cumulative error count */
unsigned num_pb_fs = 1; /* The number of settings to test for page buffering and file space handling */
const char *driver_name; /* Environment variable */
bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */
H5CX_node_t api_ctx = {{0}, NULL}; /* API context node to push */
bool api_ctx_pushed = false; /* Whether API context pushed */
int test_express;
/* Don't run this test using certain file drivers */
driver_name = h5_get_test_driver_name();
/* Current VFD that does not support contiguous address space */
contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0);
/* Reset library */
h5_test_init();
def_fapl = h5_fileaccess();
/*
* Caution when turning on ExpressMode 0:
* It will activate testing with different combinations of
* page buffering and file space strategy and the
* running time will be long.
* For parallel build, the last two tests for page buffering
* are skipped because this feature is disabled in parallel.
* Activate full testing when this feature is re-enabled
* in the future for parallel build.
*/
test_express = h5_get_testexpress();
if (test_express > 0)
printf("***Express test mode %d. Some tests may be skipped\n", test_express);
else if (test_express == 0) {
#ifdef H5_HAVE_PARALLEL
num_pb_fs = NUM_PB_FS - 2;
#else
num_pb_fs = NUM_PB_FS;
#endif
}
/* Initialize heap creation parameters */
init_small_cparam(&small_cparam);
init_large_cparam(&large_cparam);
/* Push API context */
if (H5CX_push(&api_ctx) < 0)
FAIL_STACK_ERROR;
api_ctx_pushed = true;
/* Allocate space for the shared objects */
shared_obj_size_g = large_cparam.max_man_size + 256;
shared_wobj_g = (unsigned char *)H5MM_malloc(shared_obj_size_g);
shared_robj_g = (unsigned char *)H5MM_malloc(shared_obj_size_g);
/* Create a copy def_fapl and enable page buffering */
if ((pb_fapl = H5Pcopy(def_fapl)) < 0)
TEST_ERROR;
if (H5Pset_page_buffer_size(pb_fapl, PAGE_BUFFER_PAGE_SIZE, 0, 0) < 0)
TEST_ERROR;
/* Create a file creation property list */
if ((def_fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
TEST_ERROR;
/* Initialize the shared write buffer for objects */
for (u = 0; u < shared_obj_size_g; u++)
shared_wobj_g[u] = (unsigned char)u;
for (v = 0; v < num_pb_fs; v++) {
/* Skip test when:
a) multi/split drivers and
b) persisting free-space or using paged aggregation strategy
because the library will fail file creation (temporary) for the above conditions */
if (!contig_addr_vfd && v)
break;
if ((fcpl = H5Pcopy(def_fcpl)) < 0)
TEST_ERROR;
switch (v) {
case 0:
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, false, (hsize_t)1) < 0)
TEST_ERROR;
fapl = def_fapl;
break;
case 1:
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, true, (hsize_t)1) < 0)
TEST_ERROR;
fapl = def_fapl;
/* This is a fix for the daily test failure from the commit for libver bounds. */
/*
* Many tests failed the file size check when comparing (a) and (b) as below:
* --Create a file and close the file. Got the initial file size (a).
* --Reopen the file, perform fractal heap operations, and close the file.
* Got the file size (b).
* The cause for the file size differences:
* When the file is initially created with persisting free-space and with
* (earliest, latest) libver bounds, the file will have version 2 superblock
* due to non-default free-space handling. As the low bound is earliest,
* the library uses version 1 object header when creating the superblock
* extension message.
* When the file is reopened with the same libver bounds, the file's low
* bound is upgraded to v18 because the file has version 2 superblock.
* When the library creates the superblock extension message on file close,
* the library uses version 2 object header for the superblock extension
* message since the low bound is v18.
* This leads to the discrepancy in file sizes as the file is persisting
* free-space and there is object header version differences.
* The fix:
* Set libver bounds in fapl to (v18, latest) so that the file created in the
* test routines will have low bound set to v18. This will cause the
* library to use version 2 object header for the superblock extension
* message.
*/
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_LATEST) < 0)
TEST_ERROR;
break;
case 2:
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1) < 0)
TEST_ERROR;
fapl = def_fapl;
break;
case 3:
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, true, (hsize_t)1) < 0)
TEST_ERROR;
fapl = def_fapl;
break;
case 4:
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1) < 0)
TEST_ERROR;
fapl = pb_fapl;
break;
case 5:
if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, true, (hsize_t)1) < 0)
TEST_ERROR;
fapl = pb_fapl;
break;
case NUM_PB_FS:
default:
goto error;
}
/* Iterate over the testing parameters */
for (curr_test = FHEAP_TEST_NORMAL; curr_test < FHEAP_TEST_NTESTS; curr_test++) {
/* Clear the testing parameters */
memset(&tparam, 0, sizeof(fheap_test_param_t));
tparam.actual_id_len = HEAP_ID_LEN;
/* Set to run with different file space setting */
tparam.my_fcpl = fcpl;
/* Set appropriate testing parameters for each test */
switch (curr_test) {
/* "Normal" testing parameters */
case FHEAP_TEST_NORMAL:
puts("Testing with normal parameters");
break;
/* "Re-open heap" testing parameters */
case FHEAP_TEST_REOPEN:
puts("Testing with reopen heap flag set");
tparam.reopen_heap = FHEAP_TEST_REOPEN;
break;
/* An unknown test? */
case FHEAP_TEST_NTESTS:
default:
goto error;
} /* end switch */
/* Test fractal heap creation */
nerrors += test_create(fapl, &small_cparam, &tparam);
nerrors += test_reopen(fapl, &small_cparam, &tparam);
nerrors += test_open_twice(fapl, &small_cparam, &tparam);
nerrors += test_delete_open(fapl, &small_cparam, &tparam);
nerrors += test_id_limits(fapl, &small_cparam, tparam.my_fcpl);
nerrors += test_filtered_create(fapl, &small_cparam, tparam.my_fcpl);
nerrors += test_size(fapl, &small_cparam, tparam.my_fcpl);
nerrors += test_reopen_hdr(fapl, &small_cparam, tparam.my_fcpl);
{
fheap_test_fill_t fill; /* Size of objects to fill heap blocks with */
/* Filling with different sized objects */
for (fill = FHEAP_TEST_FILL_LARGE; fill < FHEAP_TEST_FILL_N; fill++) {
tparam.fill = fill;
/* Set appropriate testing parameters for each test */
switch (fill) {
/* "Bulk fill" heap blocks with 'large' objects */
case FHEAP_TEST_FILL_LARGE:
puts("Bulk-filling blocks w/large objects");
break;
/* "Bulk fill" heap blocks with 'single' objects */
case FHEAP_TEST_FILL_SINGLE:
puts("Bulk-filling blocks w/single object");
break;
/* An unknown test? */
case FHEAP_TEST_FILL_N:
default:
goto error;
} /* end switch */
/*
* Test fractal heap managed object insertion
*/
/* "Weird" sized objects */
nerrors += test_man_insert_weird(fapl, &small_cparam, &tparam);
#ifdef ALL_INSERT_TESTS
/* "Standard" sized objects, building from simple to complex heaps */
nerrors += test_man_insert_first(fapl, &small_cparam, &tparam);
nerrors += test_man_insert_second(fapl, &small_cparam, &tparam);
nerrors += test_man_insert_root_mult(fapl, &small_cparam, &tparam);
nerrors += test_man_insert_force_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_insert_fill_second(fapl, &small_cparam, &tparam);
nerrors += test_man_insert_third_direct(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_first_row(fapl, &small_cparam, &tparam);
nerrors += test_man_start_second_row(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_second_row(fapl, &small_cparam, &tparam);
nerrors += test_man_start_third_row(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_fourth_row(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_all_root_direct(fapl, &small_cparam, &tparam);
nerrors += test_man_first_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_second_direct_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_first_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_second_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_second_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_recursive_indirect_row(fapl, &small_cparam, &tparam);
nerrors += test_man_start_2nd_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_recursive_indirect_two_deep(fapl, &small_cparam, &tparam);
nerrors += test_man_start_3rd_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_first_3rd_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_3rd_recursive_indirect_row(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_all_3rd_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_start_4th_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_first_4th_recursive_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_4th_recursive_indirect_row(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_all_4th_recursive_indirect(fapl, &small_cparam, &tparam);
#endif /* ALL_INSERT_TESTS */
/* If this test fails, uncomment the tests above, which build up to this
* level of complexity gradually. -QAK
*/
if (test_express > 1)
printf(
"***Express test mode on. test_man_start_5th_recursive_indirect is skipped\n");
else
nerrors += test_man_start_5th_recursive_indirect(fapl, &small_cparam, &tparam);
/*
* Test fractal heap object deletion
*/
/* Simple removal */
nerrors += test_man_remove_bogus(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_one(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_two(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_one_larger(fapl, &small_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_man_remove_two_larger(fapl, &small_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_REVERSE;
nerrors += test_man_remove_two_larger(fapl, &small_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_man_remove_three_larger(fapl, &small_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_REVERSE;
nerrors += test_man_remove_three_larger(fapl, &small_cparam, &tparam);
/* Incremental insert & removal */
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_man_incr_insert_remove(fapl, &small_cparam, &tparam);
{
fheap_test_del_dir_t del_dir; /* Deletion direction */
fheap_test_del_drain_t drain_half; /* Deletion draining */
/* More complex removal patterns */
for (del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) {
tparam.del_dir = del_dir;
for (drain_half = FHEAP_DEL_DRAIN_ALL; drain_half < FHEAP_DEL_DRAIN_N;
drain_half++) {
tparam.drain_half = drain_half;
/* Don't need to test deletion directions when deleting entire heap */
if (tparam.del_dir == FHEAP_DEL_HEAP &&
tparam.drain_half > FHEAP_DEL_DRAIN_ALL)
break;
/* Simple insertion patterns */
nerrors += test_man_remove_root_direct(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_two_direct(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_first_row(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_first_two_rows(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_first_four_rows(fapl, &small_cparam, &tparam);
if (test_express > 1)
printf("***Express test mode on. Some tests skipped\n");
else {
nerrors += test_man_remove_all_root_direct(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_2nd_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_3rd_indirect(fapl, &small_cparam, &tparam);
} /* end else */
/* Skip blocks insertion */
/* (covers insertion & deletion of skipped blocks) */
nerrors += test_man_skip_start_block(fapl, &small_cparam, &tparam);
nerrors += test_man_skip_start_block_add_back(fapl, &small_cparam, &tparam);
nerrors +=
test_man_skip_start_block_add_skipped(fapl, &small_cparam, &tparam);
nerrors += test_man_skip_2nd_block(fapl, &small_cparam, &tparam);
nerrors += test_man_skip_2nd_block_add_skipped(fapl, &small_cparam, &tparam);
nerrors += test_man_fill_one_partial_skip_2nd_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_row_skip_add_skipped(fapl, &small_cparam, &tparam);
nerrors += test_man_skip_direct_skip_indirect_two_rows_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_direct_skip_indirect_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_direct_skip_2nd_indirect_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_2nd_direct_less_one_wrap_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_direct_skip_indirect_two_rows_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_2nd_direct_skip_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors += test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(
fapl, &small_cparam, &tparam);
if (test_express > 1)
printf("***Express test mode on. Some tests skipped\n");
else {
nerrors +=
test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(
fapl, &small_cparam, &tparam);
nerrors +=
test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(
fapl, &small_cparam, &tparam);
} /* end else */
/* Fragmented insertion patterns */
/* (covers insertion & deletion of fragmented blocks) */
nerrors += test_man_frag_simple(fapl, &small_cparam, &tparam);
nerrors += test_man_frag_direct(fapl, &small_cparam, &tparam);
nerrors += test_man_frag_2nd_direct(fapl, &small_cparam, &tparam);
nerrors += test_man_frag_3rd_direct(fapl, &small_cparam, &tparam);
} /* end for */
} /* end for */
/* Reset deletion drain parameter */
tparam.drain_half = FHEAP_DEL_DRAIN_ALL;
} /* end block */
} /* end for */
} /* end block */
/*
* Test fractal heap 'huge' & 'tiny' object insertion & deletion
*/
{
fheap_test_del_dir_t del_dir; /* Deletion direction */
unsigned id_len; /* Length of heap IDs */
/* Test "normal" & "direct" storage of 'huge' & 'tiny' heap IDs */
for (id_len = 0; id_len < 3; id_len++) {
/* Set the ID length for this test */
small_cparam.id_len = (uint16_t)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 (file address size) + 8 (file length size) */
break;
/* Use "direct" storage for 'huge' objects and larger IDs for 'tiny' objects */
case 2:
small_cparam.id_len = 37;
puts("Using 'direct' heap ID format for 'huge' objects and larger IDs for "
"'tiny' objects");
tparam.actual_id_len = 37;
break;
/* An unknown test? */
default:
goto error;
} /* end switch */
/* Try several different methods of deleting objects */
for (del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) {
tparam.del_dir = del_dir;
/* Test 'huge' object insert & delete */
nerrors += test_huge_insert_one(fapl, &small_cparam, &tparam);
nerrors += test_huge_insert_two(fapl, &small_cparam, &tparam);
nerrors += test_huge_insert_three(fapl, &small_cparam, &tparam);
nerrors += test_huge_insert_mix(fapl, &small_cparam, &tparam);
nerrors += test_filtered_huge(fapl, &small_cparam, &tparam);
/* Test 'tiny' object insert & delete */
nerrors += test_tiny_insert_one(fapl, &small_cparam, &tparam);
nerrors += test_tiny_insert_two(fapl, &small_cparam, &tparam);
nerrors += test_tiny_insert_mix(fapl, &small_cparam, &tparam);
} /* end for */
} /* end for */
/* Reset the "normal" heap ID lengths */
small_cparam.id_len = 0;
tparam.actual_id_len = HEAP_ID_LEN;
} /* end block */
/* Test I/O filter support */
/* Try several different methods of deleting objects */
{
fheap_test_del_dir_t del_dir; /* Deletion direction */
for (del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) {
tparam.del_dir = del_dir;
/* Controlled tests */
/* XXX: Re-enable file size checks in these tests, after the file has persistent free
* space tracking working */
nerrors += test_filtered_man_root_direct(fapl, &small_cparam, &tparam);
nerrors += test_filtered_man_root_indirect(fapl, &small_cparam, &tparam);
/* Random tests, with compressed blocks */
tparam.comp = FHEAP_TEST_COMPRESS;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(50 * 1000 * 1000)
: (hsize_t)(25 * 1000 * 1000)),
fapl, &small_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(50 * 1000 * 1000)
: (hsize_t)(2 * 1000 * 1000)),
fapl, &small_cparam, &tparam);
/* Reset block compression */
tparam.comp = FHEAP_TEST_NO_COMPRESS;
} /* end for */
} /* end block */
/* Random object insertion & deletion */
if (test_express > 1)
printf("***Express test mode on. Some tests skipped\n");
else {
/* Random tests using "small" heap creation parameters */
puts("Using 'small' heap creation parameters");
/* (reduce size of tests when re-opening each time) */
/* XXX: Try to speed things up enough that these tests don't have to be reduced when
* re-opening */
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(50 * 1000 * 1000)),
fapl, &small_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(4 * 1000 * 1000)),
fapl, &small_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_HEAP;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(50 * 1000 * 1000)),
fapl, &small_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(4 * 1000 * 1000)),
fapl, &small_cparam, &tparam);
/* Random tests using "large" heap creation parameters */
puts("Using 'large' heap creation parameters");
tparam.actual_id_len = LARGE_HEAP_ID_LEN;
/* (reduce size of tests when re-opening each time) */
/* XXX: Try to speed things up enough that these tests don't have to be reduced when
* re-opening */
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(50 * 1000 * 1000)),
fapl, &large_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(4 * 1000 * 1000)),
fapl, &large_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_HEAP;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(50 * 1000 * 1000)),
fapl, &large_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100 * 1000 * 1000)
: (hsize_t)(4 * 1000 * 1000)),
fapl, &large_cparam, &tparam);
/* Reset the "normal" heap ID length */
tparam.actual_id_len = SMALL_HEAP_ID_LEN;
} /* end else */
/* Test object writing support */
/* Basic object writing */
nerrors += test_write(fapl, &small_cparam, &tparam);
/* Writing objects in heap with filters */
tparam.comp = FHEAP_TEST_COMPRESS;
nerrors += test_write(fapl, &small_cparam, &tparam);
/* Reset block compression */
tparam.comp = FHEAP_TEST_NO_COMPRESS;
} /* end for */
if (H5Pclose(fcpl) < 0)
TEST_ERROR;
} /* end num_pb_fs */
/* Tests that address specific bugs */
tparam.my_fcpl = def_fcpl;
fapl = def_fapl;
/* Tests that address specific bugs */
nerrors += test_bug1(fapl, &small_cparam, &tparam);
/* Verify symbol table messages are cached */
nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0);
if (nerrors)
goto error;
puts("All fractal heap tests passed.");
/* Release space for the shared objects */
H5MM_xfree(shared_wobj_g);
H5MM_xfree(shared_robj_g);
H5MM_xfree(shared_ids_g);
H5MM_xfree(shared_lens_g);
H5MM_xfree(shared_offs_g);
if (H5Pclose(def_fcpl) < 0)
TEST_ERROR;
if (H5Pclose(pb_fapl) < 0)
TEST_ERROR;
/* Pop API context */
if (api_ctx_pushed && H5CX_pop(false) < 0)
FAIL_STACK_ERROR;
api_ctx_pushed = false;
/* Clean up file used */
h5_cleanup(FILENAME, def_fapl);
return 0;
error:
puts("*** TESTS FAILED ***");
H5E_BEGIN_TRY
{
H5MM_xfree(shared_wobj_g);
H5MM_xfree(shared_robj_g);
H5MM_xfree(shared_ids_g);
H5MM_xfree(shared_lens_g);
H5MM_xfree(shared_offs_g);
H5Pclose(def_fapl);
H5Pclose(pb_fapl);
H5Pclose(def_fcpl);
H5Pclose(fcpl);
}
H5E_END_TRY
if (api_ctx_pushed)
H5CX_pop(false);
return 1;
} /* end main() */