mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-21 01:04:10 +08:00
7f1e49206d
This is where most people will expect to find license information. The COPYING_LBNL_HDF5 file has also been renamed to LICENSE_LBNL_HDF5. The licenses are unchanged.
16559 lines
586 KiB
C
16559 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 */
|
|
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() < 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() */
|