mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-21 01:04:10 +08:00
97e1ed4fc8
Since each API context is local to a thread, use the stack to store the context instead of allocating & releasing it each time. This improves performance (slightly), reduces alloc/free calls, and eliminates the H5FL package from the push & pop operations, which helps simplify threadsafe operation. One effect of this change is that the H5VLstart_lib_state / H5VLfinish_lib_state API routines for pass through connector authors now require a parameter that can be used to store the library's context. It was probably a mistake to assume that these two routines would not do this previously, so this is essentially a bug fix for them. Some other minor things: * Added API context push+pop operations to cache tests (I'm not actually certain why this was working before) and a few other places * Cleaned up a bunch of warnings in test code (calloc args, mainly) * Made header file inclusions more standard in some source files
2937 lines
93 KiB
C
2937 lines
93 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. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
/*
|
|
* Tests for free-space manager
|
|
*/
|
|
#include "h5test.h"
|
|
|
|
#define H5FS_FRIEND /*suppress error about including H5FSpkg */
|
|
#define H5FS_TESTING
|
|
#include "H5FSpkg.h" /* Free space manager */
|
|
|
|
/* Other private headers that this test requires */
|
|
#define H5F_FRIEND /*suppress error about including H5Fpkg */
|
|
#include "H5Fpkg.h"
|
|
|
|
#include "H5CXprivate.h" /* API Contexts */
|
|
#include "H5Iprivate.h"
|
|
#include "H5VLprivate.h" /* Virtual Object Layer */
|
|
#include "H5VMprivate.h"
|
|
|
|
#define FILENAME_LEN 1024
|
|
|
|
#define TEST_FSPACE_SECT_TYPE 0
|
|
#define TEST_FSPACE_SECT_TYPE_NEW 1
|
|
#define TEST_FSPACE_SECT_TYPE_NONE 2
|
|
|
|
#define TEST_FSPACE_SHRINK 80
|
|
#define TEST_FSPACE_EXPAND 120
|
|
#define TEST_MAX_SECT_SIZE (64 * 1024)
|
|
#define TEST_MAX_INDEX 32
|
|
|
|
#define TEST_SECT_ADDR60 60
|
|
#define TEST_SECT_ADDR70 70
|
|
#define TEST_SECT_ADDR80 80
|
|
#define TEST_SECT_ADDR100 100
|
|
#define TEST_SECT_ADDR150 150
|
|
#define TEST_SECT_ADDR200 200
|
|
#define TEST_SECT_ADDR300 300
|
|
|
|
#define TEST_SECT_SIZE5 5
|
|
#define TEST_SECT_SIZE10 10
|
|
#define TEST_SECT_SIZE15 15
|
|
#define TEST_SECT_SIZE20 20
|
|
#define TEST_SECT_SIZE30 30
|
|
#define TEST_SECT_SIZE40 40
|
|
#define TEST_SECT_SIZE50 50
|
|
#define TEST_SECT_SIZE80 80
|
|
|
|
#define FSPACE_THRHD_DEF 1 /* Default: no alignment threshold */
|
|
#define FSPACE_ALIGN_DEF 1 /* Default: no alignment */
|
|
|
|
static const char *FILENAME[] = {"frspace", NULL};
|
|
|
|
typedef struct frspace_state_t {
|
|
hsize_t tot_space; /* Total amount of space tracked */
|
|
hsize_t tot_sect_count; /* Total # of sections tracked */
|
|
hsize_t serial_sect_count; /* # of serializable sections tracked */
|
|
hsize_t ghost_sect_count; /* # of un-serializable sections tracked */
|
|
} frspace_state_t;
|
|
|
|
haddr_t g_eoa = 0;
|
|
static haddr_t TEST_get_eoa(void);
|
|
static void TEST_set_eoa(haddr_t);
|
|
|
|
/*
|
|
* TEST client
|
|
*/
|
|
typedef struct TEST_free_section_t {
|
|
H5FS_section_info_t sect_info; /* Free space section information (must be first in struct) */
|
|
} TEST_free_section_t;
|
|
|
|
static herr_t TEST_sect_init_cls(H5FS_section_class_t *, void *);
|
|
static herr_t TEST_sect_free(H5FS_section_info_t *_sect);
|
|
static herr_t TEST_sect_can_merge(const H5FS_section_info_t *, const H5FS_section_info_t *,
|
|
void H5_ATTR_UNUSED *);
|
|
static herr_t TEST_sect_merging(H5FS_section_info_t **, H5FS_section_info_t *, void H5_ATTR_UNUSED *);
|
|
static herr_t TEST_sect_can_shrink(const H5FS_section_info_t *, void *);
|
|
static herr_t TEST_sect_shrinking(H5FS_section_info_t **, void *);
|
|
|
|
static unsigned test_fs_create(hid_t fapl);
|
|
static unsigned test_fs_sect_add(hid_t fapl);
|
|
static unsigned test_fs_sect_merge(hid_t fapl);
|
|
static unsigned test_fs_sect_shrink(hid_t fapl);
|
|
static unsigned test_fs_sect_find(hid_t fapl);
|
|
static unsigned test_fs_sect_change_class(hid_t fapl);
|
|
static unsigned test_fs_sect_extend(hid_t fapl);
|
|
static unsigned test_fs_sect_iterate(hid_t fapl);
|
|
|
|
H5FS_section_class_t TEST_FSPACE_SECT_CLS[1] = {{
|
|
TEST_FSPACE_SECT_TYPE, /* Section type */
|
|
0, /* Extra serialized size */
|
|
H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
|
|
NULL, /* Class private info */
|
|
|
|
/* Class methods */
|
|
TEST_sect_init_cls, /* Initialize section class */
|
|
NULL, /* Terminate section class */
|
|
|
|
/* Object methods */
|
|
NULL, /* Add section */
|
|
NULL, /* Serialize section */
|
|
NULL, /* Deserialize section */
|
|
TEST_sect_can_merge, /* Can sections merge? */
|
|
TEST_sect_merging, /* Merge sections */
|
|
TEST_sect_can_shrink, /* Can section shrink container?*/
|
|
TEST_sect_shrinking, /* Shrink container w/section */
|
|
TEST_sect_free, /* Free section */
|
|
NULL, /* Check validity of section */
|
|
NULL, /* Split section node for alignment */
|
|
NULL, /* Dump debugging for section */
|
|
}};
|
|
|
|
H5FS_section_class_t TEST_FSPACE_SECT_CLS_NEW[1] = {{
|
|
TEST_FSPACE_SECT_TYPE_NEW, /* Section type */
|
|
0, /* Extra serialized size */
|
|
H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
|
|
NULL, /* Class private info */
|
|
|
|
/* Class methods */
|
|
TEST_sect_init_cls, /* Initialize section class */
|
|
NULL, /* Terminate section class */
|
|
|
|
/* Object methods */
|
|
NULL, /* Add section */
|
|
NULL, /* Serialize section */
|
|
NULL, /* Deserialize section */
|
|
TEST_sect_can_merge, /* Can sections merge? */
|
|
TEST_sect_merging, /* Merge sections */
|
|
NULL, /* Can section shrink container?*/
|
|
NULL, /* Shrink container w/section */
|
|
TEST_sect_free, /* Free section */
|
|
NULL, /* Check validity of section */
|
|
NULL, /* Split section node for alignment */
|
|
NULL, /* Dump debugging for section */
|
|
}};
|
|
|
|
H5FS_section_class_t TEST_FSPACE_SECT_CLS_NOINIT[1] = {{
|
|
TEST_FSPACE_SECT_TYPE_NONE, /* Section type */
|
|
0, /* Extra serialized size */
|
|
H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
|
|
NULL, /* Class private info */
|
|
|
|
/* Class methods */
|
|
NULL, /* Initialize section class */
|
|
NULL, /* Terminate section class */
|
|
|
|
/* Object methods */
|
|
NULL, /* Add section */
|
|
NULL, /* Serialize section */
|
|
NULL, /* Deserialize section */
|
|
TEST_sect_can_merge, /* Can sections merge? */
|
|
TEST_sect_merging, /* Merge sections */
|
|
NULL, /* Can section shrink container?*/
|
|
NULL, /* Shrink container w/section */
|
|
TEST_sect_free, /* Free section */
|
|
NULL, /* Check validity of section */
|
|
NULL, /* Split section node for alignment */
|
|
NULL, /* Dump debugging for section */
|
|
}};
|
|
|
|
const H5FS_section_class_t *test_classes[] = {TEST_FSPACE_SECT_CLS, TEST_FSPACE_SECT_CLS_NEW,
|
|
TEST_FSPACE_SECT_CLS_NOINIT};
|
|
|
|
static void init_cparam(H5FS_create_t *);
|
|
static void init_sect_node(TEST_free_section_t *, haddr_t, hsize_t, unsigned, H5FS_section_state_t);
|
|
static int check_stats(const H5F_t *, const H5FS_t *, frspace_state_t *);
|
|
|
|
#define NUM_SECTIONS 1000
|
|
|
|
/* User data for free space section iterator callback */
|
|
typedef struct {
|
|
hsize_t tot_size;
|
|
hsize_t tot_sect_count;
|
|
} TEST_iter_ud_t;
|
|
|
|
static herr_t TEST_sects_cb(H5FS_section_info_t *_sect, void *_udata);
|
|
|
|
/*
|
|
* Tests
|
|
*/
|
|
|
|
/*
|
|
* free-space section routines for client TEST
|
|
*/
|
|
static herr_t
|
|
TEST_sect_init_cls(H5FS_section_class_t *cls, void *_udata)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
unsigned *init_flags;
|
|
|
|
/* Check arguments. */
|
|
assert(cls);
|
|
assert(_udata);
|
|
|
|
init_flags = (unsigned *)_udata;
|
|
cls->flags |= *init_flags;
|
|
|
|
return ret_value;
|
|
} /* TEST_sect_init_cls() */
|
|
|
|
/*
|
|
* Check if the two sections can be merged:
|
|
* true if second section adjoins the first section
|
|
*/
|
|
H5_ATTR_PURE static herr_t
|
|
TEST_sect_can_merge(const H5FS_section_info_t *_sect1, const H5FS_section_info_t *_sect2,
|
|
void H5_ATTR_UNUSED *_udata)
|
|
{
|
|
const TEST_free_section_t *sect1 = (const TEST_free_section_t *)_sect1;
|
|
const TEST_free_section_t *sect2 = (const TEST_free_section_t *)_sect2;
|
|
htri_t ret_value; /* Return value */
|
|
|
|
/* Check arguments. */
|
|
assert(sect1);
|
|
assert(sect2);
|
|
assert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
|
|
assert(H5_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
|
|
|
|
/* Check if second section adjoins first section */
|
|
ret_value = H5_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
|
|
|
|
return ret_value;
|
|
} /* TEST_sect_can_merge() */
|
|
|
|
/*
|
|
* Merge the two sections (second section is merged into the first section)
|
|
*/
|
|
static herr_t
|
|
TEST_sect_merging(H5FS_section_info_t **_sect1, H5FS_section_info_t *_sect2, void H5_ATTR_UNUSED *_udata)
|
|
{
|
|
TEST_free_section_t **sect1 = (TEST_free_section_t **)_sect1;
|
|
TEST_free_section_t *sect2 = (TEST_free_section_t *)_sect2;
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
/* Check arguments. */
|
|
assert(sect1);
|
|
assert(((*sect1)->sect_info.type == TEST_FSPACE_SECT_TYPE) ||
|
|
((*sect1)->sect_info.type == TEST_FSPACE_SECT_TYPE_NEW) ||
|
|
((*sect1)->sect_info.type == TEST_FSPACE_SECT_TYPE_NONE));
|
|
assert(sect2);
|
|
assert((sect2->sect_info.type == TEST_FSPACE_SECT_TYPE) ||
|
|
(sect2->sect_info.type == TEST_FSPACE_SECT_TYPE_NEW) ||
|
|
(sect2->sect_info.type == TEST_FSPACE_SECT_TYPE_NONE));
|
|
assert(H5_addr_eq((*sect1)->sect_info.addr + (*sect1)->sect_info.size, sect2->sect_info.addr));
|
|
|
|
/* Add second section's size to first section */
|
|
(*sect1)->sect_info.size += sect2->sect_info.size;
|
|
|
|
/* Get rid of second section */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect2) < 0)
|
|
TEST_ERROR;
|
|
error:
|
|
return ret_value;
|
|
} /* TEST_sect_merging() */
|
|
|
|
/*
|
|
* Free the section
|
|
*/
|
|
static herr_t
|
|
TEST_sect_free(H5FS_section_info_t *sect)
|
|
{
|
|
/* Release the section */
|
|
free(sect);
|
|
|
|
return 0;
|
|
} /* TEST_sect_free() */
|
|
|
|
/*
|
|
* Determine if the section can be shrunk and set _udata accordingly
|
|
* if _udata passed in is NULL, return false
|
|
* Otherwise:
|
|
* if section's address+size is the end of file, return true
|
|
* otherwise return false
|
|
*/
|
|
static herr_t
|
|
TEST_sect_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
|
|
{
|
|
unsigned *can_shrink = (unsigned *)_udata;
|
|
const TEST_free_section_t *sect = (const TEST_free_section_t *)_sect;
|
|
haddr_t end, eoa;
|
|
|
|
if (can_shrink == NULL)
|
|
return false;
|
|
|
|
end = sect->sect_info.addr + sect->sect_info.size;
|
|
eoa = TEST_get_eoa();
|
|
|
|
if (end == eoa)
|
|
*can_shrink = true;
|
|
else
|
|
*can_shrink = false;
|
|
|
|
return (htri_t)*can_shrink;
|
|
} /* TEST_sect_can_shrink() */
|
|
|
|
/*
|
|
* Shrink the section
|
|
*/
|
|
static herr_t
|
|
TEST_sect_shrinking(H5FS_section_info_t **_sect, void *_udata)
|
|
{
|
|
TEST_free_section_t **sect = (TEST_free_section_t **)_sect;
|
|
unsigned *can_shrink = (unsigned *)_udata;
|
|
|
|
/* address of the section is faked, so, doesn't need to do anything */
|
|
/* just free the section node */
|
|
if (*can_shrink) {
|
|
if (TEST_sect_free((H5FS_section_info_t *)*sect) < 0)
|
|
TEST_ERROR;
|
|
*sect = NULL;
|
|
return true;
|
|
} /* end if */
|
|
|
|
error:
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* iteration callback
|
|
*/
|
|
static herr_t
|
|
TEST_sects_cb(H5FS_section_info_t *_sect, void *_udata)
|
|
{
|
|
TEST_free_section_t *sect = (TEST_free_section_t *)_sect;
|
|
TEST_iter_ud_t *udata = (TEST_iter_ud_t *)_udata;
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
assert(sect);
|
|
assert(udata);
|
|
|
|
udata->tot_size += sect->sect_info.size;
|
|
udata->tot_sect_count += 1;
|
|
|
|
return (ret_value);
|
|
}
|
|
|
|
/* supporting routine for shrinking */
|
|
static haddr_t
|
|
TEST_get_eoa(void)
|
|
{
|
|
return g_eoa;
|
|
}
|
|
|
|
/* supporting routine for shrinking */
|
|
static void
|
|
TEST_set_eoa(haddr_t val)
|
|
{
|
|
g_eoa = val;
|
|
}
|
|
|
|
/*
|
|
* Initialize creation parameter structure for TEST client
|
|
*/
|
|
static void
|
|
init_cparam(H5FS_create_t *cparam)
|
|
{
|
|
memset(cparam, 0, sizeof(H5FS_create_t));
|
|
|
|
/* Set the free space creation parameters */
|
|
cparam->shrink_percent = TEST_FSPACE_SHRINK;
|
|
cparam->expand_percent = TEST_FSPACE_EXPAND;
|
|
cparam->max_sect_size = TEST_MAX_SECT_SIZE;
|
|
cparam->max_sect_addr = TEST_MAX_INDEX;
|
|
|
|
} /* init_cparam() */
|
|
|
|
/*
|
|
* Initialize free space section node
|
|
*/
|
|
static void
|
|
init_sect_node(TEST_free_section_t *sect_node, haddr_t addr, hsize_t size, unsigned type,
|
|
H5FS_section_state_t state)
|
|
{
|
|
sect_node->sect_info.addr = addr;
|
|
sect_node->sect_info.size = size;
|
|
sect_node->sect_info.type = type;
|
|
sect_node->sect_info.state = state;
|
|
} /* init_sect_node() */
|
|
|
|
/*
|
|
* Verify statistics for the free-space manager
|
|
*/
|
|
static int
|
|
check_stats(const H5F_t *f, const H5FS_t *frsp, frspace_state_t *state)
|
|
{
|
|
H5FS_stat_t frspace_stats; /* Statistics about the heap */
|
|
|
|
/* Get statistics for heap and verify they are correct */
|
|
if (H5FS_stat_info(f, frsp, &frspace_stats) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (frspace_stats.tot_space != state->tot_space) {
|
|
fprintf(stdout, "frspace_stats.tot_space = %" PRIuHSIZE ", state->tot_space = %" PRIuHSIZE "\n",
|
|
frspace_stats.tot_space, state->tot_space);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
if (frspace_stats.tot_sect_count != state->tot_sect_count) {
|
|
fprintf(stdout,
|
|
"frspace_stats.tot_sect_count = %" PRIuHSIZE ", state->tot_sect_count = %" PRIuHSIZE "\n",
|
|
frspace_stats.tot_sect_count, state->tot_sect_count);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
if (frspace_stats.serial_sect_count != state->serial_sect_count) {
|
|
fprintf(stdout,
|
|
"frspace_stats.serial_sect_count = %" PRIuHSIZE ", state->serial_sect_count = %" PRIuHSIZE
|
|
"\n",
|
|
frspace_stats.serial_sect_count, state->serial_sect_count);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
if (frspace_stats.ghost_sect_count != state->ghost_sect_count) {
|
|
fprintf(stdout,
|
|
"frspace_stats.ghost_sect_count = %" PRIuHSIZE ", state->ghost_sect_count = %" PRIuHSIZE "\n",
|
|
frspace_stats.ghost_sect_count, state->ghost_sect_count);
|
|
TEST_ERROR;
|
|
} /* end if */
|
|
|
|
/* All tests passed */
|
|
return 0;
|
|
|
|
error:
|
|
return 1;
|
|
} /* check_stats() */
|
|
|
|
/*
|
|
* TESTS for free-space manager
|
|
*/
|
|
|
|
/*
|
|
* To verify the creation, close, reopen and deletion of the free-space manager
|
|
*/
|
|
static unsigned
|
|
test_fs_create(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr; /* address of free space */
|
|
h5_stat_size_t file_size, empty_size; /* File size */
|
|
frspace_state_t state; /* State of free space*/
|
|
H5FS_create_t cparam, test_cparam; /* creation parameters */
|
|
uint16_t nclasses;
|
|
unsigned init_flags = 0;
|
|
|
|
TESTING("the creation/close/reopen/deletion of the free-space manager");
|
|
|
|
/* 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, H5P_DEFAULT, 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;
|
|
|
|
/* initialize creation parameters for free-space manager */
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
if (frsp->nclasses != nclasses)
|
|
TEST_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
memset(&test_cparam, 0, sizeof(H5FS_create_t));
|
|
if (H5FS__get_cparam_test(frsp, &test_cparam) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5FS__cmp_cparam_test(&cparam, &test_cparam))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* reopen the free-space manager */
|
|
if (NULL == (frsp = H5FS_open(f, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF,
|
|
(hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
if (frsp->nclasses != nclasses)
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* 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 the correct size */
|
|
if (file_size != empty_size)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_fs_create() */
|
|
|
|
/*
|
|
* Test 1:
|
|
* Create free-space manager
|
|
* Add section A via H5FS_sect_add() with H5FS_ADD_RETURNED_SPACE
|
|
* Close the free-space manager
|
|
* Result: section A is serialized to the file
|
|
*
|
|
* Test 2:
|
|
* Create free-space manager with H5FS_CLS_GHOST_OBJ section class setting
|
|
* Add section A via H5FS_sect_add() with H5FS_ADD_RETURNED_SPACE
|
|
* Close the free-space manager
|
|
* Result: section A is not serialized to the file
|
|
*
|
|
* Test 3:
|
|
* Add section A via H5FS_sect_add() to allow shrinking with H5FS_ADD_RETURNED_SPACE
|
|
* Set EOF to be the ending address of section A
|
|
* Result: H5FS_sect_add() will shrink section A
|
|
*
|
|
* Test 4:
|
|
* Add section A via H5FS_sect_add() to allow shrinking with H5FS_ADD_DESERIALIZING
|
|
* Set EOF to be the ending address of section A
|
|
* Result: H5FS_sect_add() will not shrink section A
|
|
*
|
|
*/
|
|
static unsigned
|
|
test_fs_sect_add(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr = HADDR_UNDEF; /* address of free space */
|
|
uint16_t nclasses;
|
|
H5FS_create_t cparam; /* creation parameters */
|
|
frspace_state_t state; /* State of free space*/
|
|
|
|
TEST_free_section_t *sect_node = NULL;
|
|
unsigned init_flags = 0;
|
|
h5_stat_size_t file_size = 0, tmp_file_size = 0, fr_meta_size = 0;
|
|
unsigned can_shrink = false;
|
|
|
|
TESTING("adding a section via H5FS_sect_add() to free-space: test 1");
|
|
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of a file w/empty heap*/
|
|
if ((file_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;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
if (NULL == (sect_node = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
fr_meta_size = H5FS_HEADER_SIZE(f) + H5FS_SINFO_PREFIX_SIZE(f);
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
sect_node = NULL;
|
|
|
|
if (h5_using_default_driver(NULL)) {
|
|
/* Get the size of a file w/empty heap*/
|
|
if ((tmp_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (tmp_file_size <= (file_size + fr_meta_size))
|
|
TEST_ERROR;
|
|
}
|
|
|
|
PASSED();
|
|
|
|
TESTING("adding a section via H5FS_sect_add() to free-space with H5FS_CLS_GHOST_OBJ: test 2");
|
|
|
|
/* Get the size of a file w/empty heap*/
|
|
if ((file_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;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
init_flags = H5FS_CLS_GHOST_OBJ;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/* Create free list section node */
|
|
if (NULL == (sect_node = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, 0, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.ghost_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
fr_meta_size = H5FS_HEADER_SIZE(f);
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
sect_node = NULL;
|
|
|
|
if (h5_using_default_driver(NULL)) {
|
|
/* Get the size of a file w/empty heap*/
|
|
if ((tmp_file_size = h5_get_file_size(filename, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (tmp_file_size != (file_size + fr_meta_size))
|
|
TEST_ERROR;
|
|
}
|
|
|
|
PASSED();
|
|
|
|
TESTING("adding a section via H5FS_sect_add() to free-space: test 3");
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of a file w/empty heap*/
|
|
if ((file_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;
|
|
|
|
TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
init_flags = 0;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
if (NULL == (sect_node = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* nothing in free-space */
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
sect_node = NULL;
|
|
|
|
PASSED();
|
|
|
|
TESTING("adding a section via H5FS_sect_add() to free-space: test 4");
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the size of a file w/empty heap*/
|
|
if ((file_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;
|
|
|
|
TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
init_flags = 0;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
if (NULL == (sect_node = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
init_sect_node(sect_node, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_DESERIALIZING, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free the section node(s) */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node) < 0)
|
|
TEST_ERROR;
|
|
sect_node = NULL;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
sect_node = NULL;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (sect_node)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node);
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_fs_sect_add() */
|
|
|
|
/*
|
|
* To verify the finding of a section with the requested-size from free-space
|
|
*
|
|
* Test 1: Free-space is empty and is not able to fulfill the requested-size
|
|
* Set up: free-space is started up but is empty
|
|
*
|
|
* Test 2: Add a section and find the section whose size is equal to the requested-size
|
|
* Set up: Add section A whose size is less than requested-size
|
|
* Add section B whose size is the same as requested-size with addr=b
|
|
* Add section C whose size is the same as requested-size with addr=c > b
|
|
* Add section D whose size is greater than requested-size
|
|
*
|
|
* Test 3: Add a section and find the section whose size is > requested-size
|
|
* Set up: Add section A whose size is less than requested-size
|
|
* Add section B whose size is greater than requested-size
|
|
*
|
|
* Test 4: Add a section but the section is not able to fulfill the requested-size
|
|
* Set up: Add section A whose size is less than requested-size
|
|
*
|
|
*/
|
|
static unsigned
|
|
test_fs_sect_find(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr = HADDR_UNDEF; /* address of free space */
|
|
uint16_t nclasses;
|
|
H5FS_create_t cparam; /* creation parameters */
|
|
frspace_state_t state; /* State of free space*/
|
|
|
|
TEST_free_section_t *sect_node1 = NULL, *sect_node2, *sect_node3 = NULL, *sect_node4 = NULL;
|
|
TEST_free_section_t *node;
|
|
htri_t node_found = false;
|
|
unsigned init_flags = 0;
|
|
|
|
TESTING("H5FS_sect_find(): free-space is empty");
|
|
|
|
/* 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, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)TEST_SECT_SIZE30, (H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5FS_sect_find() a section equal to requested-size from free-space");
|
|
|
|
/* reopen the free-space manager */
|
|
if (NULL == (frsp = H5FS_open(f, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF,
|
|
(hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
if (frsp->nclasses != nclasses)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section C
|
|
*/
|
|
if (NULL == (sect_node3 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node3, (haddr_t)(TEST_SECT_ADDR200), (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node3->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node2->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section D
|
|
*/
|
|
if (NULL == (sect_node4 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR300, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node4->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR100) || (node->sect_info.size != TEST_SECT_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* remove sections A, C and D */
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node4) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free the section node(s) */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node1) < 0)
|
|
TEST_ERROR;
|
|
sect_node1 = NULL;
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node3) < 0)
|
|
TEST_ERROR;
|
|
sect_node3 = NULL;
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node4) < 0)
|
|
TEST_ERROR;
|
|
sect_node4 = NULL;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5FS_sect_find() a section greater than requested-size from free-space");
|
|
|
|
/* reopen the free-space manager */
|
|
if (NULL == (frsp = H5FS_open(f, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF,
|
|
(hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
if (frsp->nclasses != nclasses)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR200, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node2->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR200) || (node->sect_info.size < TEST_SECT_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
node = NULL;
|
|
|
|
/* remove sections A */
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free the section node(s) */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node1) < 0)
|
|
TEST_ERROR;
|
|
sect_node1 = NULL;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
PASSED();
|
|
|
|
TESTING("H5FS_sect_find(): cannot find a section with requested-size from free-space");
|
|
|
|
/* reopen the free-space manager */
|
|
if (NULL == (frsp = H5FS_open(f, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF,
|
|
(hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
if (frsp->nclasses != nclasses)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
/* remove sections A */
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free the section node(s) */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node1) < 0)
|
|
TEST_ERROR;
|
|
sect_node1 = NULL;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (sect_node1)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node1);
|
|
if (sect_node3)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node3);
|
|
if (sect_node4)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node4);
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_fs_sect_find() */
|
|
|
|
/*
|
|
* To verify that sections are merged when adding sections to free-space
|
|
*
|
|
* Test 1:
|
|
* Set up:
|
|
* H5FS_CLS_SEPAR_OBJ (cls->flags) is not set
|
|
* H5FS_ADD_RETURNED_SPACE is passed to H5FS_sect_add()
|
|
*
|
|
* Add sections C, B, A & D that can be merged together
|
|
*
|
|
* Test 2:
|
|
* Set up:
|
|
* H5FS_CLS_SEPAR_OBJ (cls->flags) is set
|
|
* H5FS_ADD_RETURNED_SPACE is passed to H5FS_sect_add()
|
|
*
|
|
* Add sections A & B that can be merged together but cannot do so because H5FS_CLS_SEPAR_OBJ flag is set
|
|
*
|
|
* Test 3:
|
|
* Set up:
|
|
* H5FS_CLS_SEPAR_OBJ (cls->flags) is not set
|
|
* H5FS_ADD_RETURNED_SPACE is passed to H5FS_sect_add()
|
|
*
|
|
* Add 4 sections that adjoin each other as follows:
|
|
* section A is of section class type A
|
|
* section B is of section class type B
|
|
* section C is of section class type B
|
|
* section D is of section class type A
|
|
* Sections B & C are merged together but not section A nor D because:
|
|
* sections B & C are merged because of the same section class type
|
|
* section A cannot be merged with the merged section of B & C because of different section class type
|
|
* section D cannot be merged with the merged section of B & C because of different section class type
|
|
*/
|
|
static unsigned
|
|
test_fs_sect_merge(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr = HADDR_UNDEF; /* address of free space */
|
|
uint16_t nclasses;
|
|
H5FS_create_t cparam; /* creation parameters */
|
|
frspace_state_t state; /* State of free space*/
|
|
|
|
TEST_free_section_t *sect_node1 = NULL, *sect_node2 = NULL, *sect_node3 = NULL, *sect_node4 = NULL;
|
|
unsigned init_flags = 0;
|
|
htri_t node_found = false;
|
|
TEST_free_section_t *node;
|
|
|
|
TESTING("the merge of sections when H5FS_sect_add() to free-space: test 1");
|
|
|
|
/*
|
|
* TEST 1
|
|
*/
|
|
/* 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, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section C
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += TEST_SECT_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* section B & C are merged */
|
|
state.tot_space += TEST_SECT_SIZE30;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node3 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE10, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* section A is merged with the merged section of B & C */
|
|
state.tot_space += TEST_SECT_SIZE10;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section D
|
|
*/
|
|
if (NULL == (sect_node4 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR150, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* section D is merged with the merged section of A & B & C */
|
|
state.tot_space += TEST_SECT_SIZE80;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* should be able to find the merged section of A, B, C & D */
|
|
if ((node_found = H5FS_sect_find(
|
|
f, frsp, (hsize_t)(TEST_SECT_SIZE10 + TEST_SECT_SIZE30 + TEST_SECT_SIZE50 + TEST_SECT_SIZE80),
|
|
(H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR60) ||
|
|
(node->sect_info.size != (TEST_SECT_SIZE10 + TEST_SECT_SIZE30 + TEST_SECT_SIZE50 + TEST_SECT_SIZE80)))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
/*
|
|
* TEST 2
|
|
*/
|
|
TESTING("the merge of sections when H5FS_sect_add() to free-space: test 2");
|
|
|
|
/* 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;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
init_flags = H5FS_CLS_SEPAR_OBJ;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += TEST_SECT_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* section A & B are not merged because H5FS_CLS_SEPAR_OBJ is set */
|
|
state.tot_space += TEST_SECT_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* should not be able to find the merged section of A & B */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE30 + TEST_SECT_SIZE50),
|
|
(H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
/* remove section A from free-space */
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* remove section B from free-space */
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free the section node(s) */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node1) < 0)
|
|
TEST_ERROR;
|
|
sect_node1 = NULL;
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node2) < 0)
|
|
TEST_ERROR;
|
|
sect_node2 = NULL;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
/*
|
|
* TEST 3
|
|
*/
|
|
TESTING("the merge of sections when H5FS_sect_add() to free-space: test 3");
|
|
|
|
/* 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;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
init_flags = 0; /* reset */
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE10, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += TEST_SECT_SIZE10;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30,
|
|
TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* sections A & B are not merged because H5FS_CLS_MERGE_SYM is set & section class type is different */
|
|
state.tot_space += TEST_SECT_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section C
|
|
*/
|
|
if (NULL == (sect_node3 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50,
|
|
TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* sections B & C are merged because H5FS_CLS_MERGE_SYM is set & section class type is the same */
|
|
state.tot_space += TEST_SECT_SIZE50;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section D
|
|
*/
|
|
if (NULL == (sect_node4 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node4, (haddr_t)TEST_SECT_ADDR150, (hsize_t)TEST_SECT_SIZE80, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node4, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* section D is not merged with the merged section of B & C because
|
|
* H5FS_CLS_MERGE_SYM is set and section class type is different
|
|
*/
|
|
state.tot_space += TEST_SECT_SIZE80;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* should not be able to find a merged section of A, B, C & D */
|
|
if ((node_found = H5FS_sect_find(
|
|
f, frsp, (hsize_t)(TEST_SECT_SIZE10 + TEST_SECT_SIZE30 + TEST_SECT_SIZE50 + TEST_SECT_SIZE80),
|
|
(H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
/* should be able to find the merged section of B & C */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE30 + TEST_SECT_SIZE50),
|
|
(H5FS_section_info_t **)&node)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR70) ||
|
|
(node->sect_info.size != (TEST_SECT_SIZE30 + TEST_SECT_SIZE50)))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* should be able to find section A */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE10), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR60) || (node->sect_info.size != TEST_SECT_SIZE10))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* should be able to find section D */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE80), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR150) || (node->sect_info.size != TEST_SECT_SIZE80))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (sect_node1)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node1);
|
|
if (sect_node2)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node2);
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_fs_sect_merge() */
|
|
|
|
/*
|
|
* To verify that sections are shrunk when adding sections to free-space
|
|
*
|
|
* Test 1:
|
|
* Set EOF to be the ending address of section A
|
|
* H5FS_CLS_SEPAR_OBJ (cls->flags) is not set when creating free-space manager
|
|
* Add section A to allow shrinking but is not shrunk because its section class type
|
|
* TEST_FSPACE_SECT_TYPE_NEW does not define "can_shrink"
|
|
* Result:section A is not shrunk and section A is still in free-space
|
|
*
|
|
* Re-add section A to allow shrinking and with section class type TEST_FSPACE_SECT_TYPE
|
|
* that defines "can_shrink"
|
|
* Result:section A is shrunk and there is nothing in free-space
|
|
*
|
|
* Test 2:
|
|
* Set EOF to be greater than the ending address of section A
|
|
* Set H5FS_CLS_SEPAR_OBJ (cls->flags) when creating free-space manager
|
|
*
|
|
* Add section A to allow shrinking but is not shrunk because it is not at EOF,
|
|
* and section A is not on the merge list due to H5FS_CLS_SEPAR_OBJ
|
|
* Add section B to allow shrinking and whose ending address is the same as eof.
|
|
* Section B is not merged with section A because of H5FS_CLS_SEPAR_OBJ but it is shrunk
|
|
* Result: section A is still in free-space
|
|
*
|
|
* Test 3:
|
|
* Set EOF to be greater than the ending address of section A
|
|
* H5FS_CLS_SEPAR_OBJ (cls->flags) is not set when creating free-space manager
|
|
*
|
|
* Add section A to allow shrinking but is not shrunk because it is not at EOF,
|
|
* and section A is on the merge list
|
|
* Add section B to allow shrinking and whose ending address is the same as eof.
|
|
* Section B is merged with section A and then shrunk.
|
|
* Result: free-space should be empty
|
|
*/
|
|
static unsigned
|
|
test_fs_sect_shrink(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr = HADDR_UNDEF; /* address of free space */
|
|
uint16_t nclasses;
|
|
H5FS_create_t cparam; /* creation parameters */
|
|
frspace_state_t state; /* State of free space*/
|
|
|
|
TEST_free_section_t *sect_node1 = NULL, *sect_node2 = NULL;
|
|
unsigned init_flags = 0;
|
|
unsigned can_shrink = false;
|
|
htri_t node_found = false;
|
|
TEST_free_section_t *node;
|
|
|
|
TESTING("shrinking of sections when H5FS_sect_add() to free-space: test 1");
|
|
|
|
/* 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, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A that allow shrinking but its section class type does not define "can_shrink"
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50,
|
|
TEST_FSPACE_SECT_TYPE_NEW, H5FS_SECT_LIVE);
|
|
|
|
can_shrink = false;
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* section A should still be there in free-space */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR100) || (node->sect_info.size != TEST_SECT_SIZE50))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Re-add section A that allow shrinking and its section class type defines "can_shrink"
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
can_shrink = false;
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* should have nothing in free-space */
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* section A should not be there in free-space */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("shrinking of sections when H5FS_sect_add() to free-space: test 2");
|
|
|
|
/* 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;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */
|
|
|
|
/* does not allow merging */
|
|
init_flags = H5FS_CLS_SEPAR_OBJ;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* free-space should be the same since section B is shrunk */
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* section B should not be there in free-space */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* section A should still be there in free-space */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE20), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!node_found)
|
|
TEST_ERROR;
|
|
|
|
if ((node->sect_info.addr != TEST_SECT_ADDR80) || (node->sect_info.size != TEST_SECT_SIZE20))
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
TESTING("shrinking of sections when H5FS_sect_add() to free-space: test 3");
|
|
|
|
/* 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;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
TEST_set_eoa((haddr_t)TEST_SECT_ADDR150); /* set end of file address for shrinking */
|
|
|
|
init_flags = 0; /* reset */
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* section A & B are merged and then strunk, so there is nothing in free-space */
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* section B should not be there in free-space */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE50), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
/* section A should not be there in free-space */
|
|
if ((node_found = H5FS_sect_find(f, frsp, (hsize_t)(TEST_SECT_SIZE30), (H5FS_section_info_t **)&node)) <
|
|
0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node_found)
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_sect_shrink() */
|
|
|
|
/*
|
|
* To verify a section's class is changed via H5FS_sect_change_class()
|
|
*
|
|
* Test 1:
|
|
* Add section A with TEST_FSPACE_SECT_TYPE class type with H5FS_CLS_GHOST_OBJ setting
|
|
* Add section B with TEST_FSPACE_SECT_TYPE_NONE class type without H5FS_CLS_GHOST_OBJ setting
|
|
* Change section A's class to the second section's class
|
|
* Result: serial_sect_count is incremented by 1; ghost_sect_count is decremented by 1
|
|
*
|
|
* Test 2:
|
|
* Add section A with TEST_FSPACE_SECT_TYPE class type with H5FS_CLS_SEPAR_OBJ setting
|
|
* Add section B with TEST_FSPACE_SECT_TYPE_NONE class type without H5FS_CLS_SEPAR_OBJ setting
|
|
* Add section C with TEST_FSPACE_SECT_TYPE_NONE class type without H5FS_CLS_SEPAR_OBJ setting
|
|
* Sections B & C are on the merge list
|
|
* Change section class of B and C to A's section class
|
|
* Result: the merge list should be null and the class of sections B & C should be changed
|
|
*/
|
|
static unsigned
|
|
test_fs_sect_change_class(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr = HADDR_UNDEF; /* address of free space */
|
|
uint16_t nclasses;
|
|
H5FS_create_t cparam; /* creation parameters */
|
|
frspace_state_t state; /* State of free space*/
|
|
|
|
TEST_free_section_t *sect_node1 = NULL, *sect_node2 = NULL, *sect_node3 = NULL;
|
|
unsigned init_flags = 0;
|
|
TEST_free_section_t *node;
|
|
|
|
TESTING("the change of section class via H5FS_sect_change_class() in free-space: Test 1");
|
|
|
|
/* 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, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
init_flags = H5FS_CLS_GHOST_OBJ;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR60, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += TEST_SECT_SIZE30;
|
|
state.tot_sect_count += 1;
|
|
state.ghost_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50,
|
|
TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += TEST_SECT_SIZE50;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5FS_sect_change_class(f, frsp, (H5FS_section_info_t *)sect_node1, TEST_FSPACE_SECT_TYPE_NONE) < 0)
|
|
TEST_ERROR;
|
|
|
|
state.serial_sect_count += 1;
|
|
state.ghost_sect_count -= 1;
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
if (H5FS_sect_find(f, frsp, (hsize_t)TEST_SECT_SIZE30, (H5FS_section_info_t **)&node) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node->sect_info.type != TEST_FSPACE_SECT_TYPE_NONE)
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free the section node(s) */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node2) < 0)
|
|
TEST_ERROR;
|
|
sect_node2 = NULL;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
/*
|
|
* TEST 2
|
|
*/
|
|
TESTING("the merge of sections when H5FS_sect_add() to free-space: test 2");
|
|
|
|
/* 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;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
init_flags = H5FS_CLS_SEPAR_OBJ;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE30, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE50,
|
|
TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Add section C
|
|
*/
|
|
if (NULL == (sect_node3 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node3, (haddr_t)TEST_SECT_ADDR200, (hsize_t)TEST_SECT_SIZE80,
|
|
TEST_FSPACE_SECT_TYPE_NONE, H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node3, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* change the class of B to A's class */
|
|
if (H5FS_sect_change_class(f, frsp, (H5FS_section_info_t *)sect_node2, TEST_FSPACE_SECT_TYPE) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* change the class of C to A's class */
|
|
if (H5FS_sect_change_class(f, frsp, (H5FS_section_info_t *)sect_node3, TEST_FSPACE_SECT_TYPE) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* the merge_list should be empty */
|
|
if (frsp->sinfo->merge_list)
|
|
if (H5SL_count(frsp->sinfo->merge_list))
|
|
TEST_ERROR;
|
|
|
|
/* verify that section B has changed class */
|
|
if (H5FS_sect_find(f, frsp, (hsize_t)TEST_SECT_SIZE50, (H5FS_section_info_t **)&node) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node->sect_info.type != TEST_FSPACE_SECT_TYPE)
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* verify that section C has changed class */
|
|
if (H5FS_sect_find(f, frsp, (hsize_t)TEST_SECT_SIZE80, (H5FS_section_info_t **)&node) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (node->sect_info.type != TEST_FSPACE_SECT_TYPE)
|
|
TEST_ERROR;
|
|
|
|
if (TEST_sect_free((H5FS_section_info_t *)node) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* remove section A from free-space */
|
|
if (H5FS_sect_remove(f, frsp, (H5FS_section_info_t *)sect_node1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Free the section node(s) */
|
|
if (TEST_sect_free((H5FS_section_info_t *)sect_node1) < 0)
|
|
TEST_ERROR;
|
|
sect_node1 = NULL;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (sect_node1)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node1);
|
|
if (sect_node2)
|
|
TEST_sect_free((H5FS_section_info_t *)sect_node2);
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_sect_change_class() */
|
|
|
|
/*
|
|
* To verify the extension of a block using space from a section in free-space
|
|
*
|
|
* Test 1: Try to extend the block by requested-size, which is equal to section B's size
|
|
* Add section A (addr=70, size=5)
|
|
* Add section B (addr=100, size=40)
|
|
* Try to extend the block (addr=80, size=20) by 40, which is the same as section B's size
|
|
* Result: succeed in extending the block
|
|
*
|
|
* Test 2: Try to extend the block by requested-size, which is greater than section B's size
|
|
* Add section A (addr=70, size=5)
|
|
* Add section B (addr=100, size=40)
|
|
* Try to extend the block (addr=80, size=20) by 50, which is greater than section B's size
|
|
* Result: fail in extending the block
|
|
*
|
|
* Test 3: Try to extend the block by requested-size, which is less than section B's size
|
|
* Add section A (addr=70, size=5)
|
|
* Add section B (addr=100, size=40)
|
|
* Try to extend the block (addr=80, size=20) by 30, which is less than section B's size
|
|
* Result: succeed in extending the block and a section of size=10 is left in free-space
|
|
*
|
|
* Test 4: Try to extend the block which does not adjoin section B
|
|
* Add section A (addr=70, size=5)
|
|
* Add section B (addr=100, size=40)
|
|
* Try to extend the block (addr=80, size=15) by 40
|
|
* Result: fail in extending the block because:
|
|
* the block does not adjoin section B (80+15 != addr of section B (80))
|
|
* even though the requested-size is equal to section B's size
|
|
*
|
|
*/
|
|
static unsigned
|
|
test_fs_sect_extend(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr = HADDR_UNDEF; /* address of free space */
|
|
uint16_t nclasses;
|
|
H5FS_create_t cparam; /* creation parameters */
|
|
frspace_state_t state; /* State of free space*/
|
|
TEST_free_section_t *sect_node1 = NULL, *sect_node2 = NULL;
|
|
unsigned init_flags = 0;
|
|
htri_t status; /* Status of 'try' calls */
|
|
|
|
TESTING("a block's extension by requested-size which is = adjoining free section's size: Test 1");
|
|
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the file to work on */
|
|
if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
/*
|
|
* TEST 1
|
|
*/
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node2->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Extend a block by requested-size */
|
|
if ((status = H5FS_sect_try_extend(f, frsp, (haddr_t)TEST_SECT_SIZE80, (hsize_t)TEST_SECT_SIZE20,
|
|
(hsize_t)TEST_SECT_SIZE40, 0, NULL)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (false == status)
|
|
TEST_ERROR;
|
|
|
|
/* Succeed in extending the block: free space info is decremented accordingly */
|
|
state.tot_space -= (hsize_t)TEST_SECT_SIZE40;
|
|
state.tot_sect_count -= 1;
|
|
state.serial_sect_count -= 1;
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
PASSED();
|
|
|
|
/*
|
|
* TEST 2
|
|
*/
|
|
TESTING("a block's extension by requested-size which is > adjoining free section's size: Test 2");
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node2->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Extend the block by requested-size */
|
|
if ((status = H5FS_sect_try_extend(f, frsp, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20,
|
|
(hsize_t)TEST_SECT_SIZE50, 0, NULL)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (true == status)
|
|
TEST_ERROR;
|
|
|
|
/* Not able to extend the block: free space info remains the same */
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
PASSED();
|
|
|
|
/*
|
|
* Test 3
|
|
*/
|
|
TESTING("a block's extension by requested-size which is < adjoining free section's size: Test 3");
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node2->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Extend the block by requested-size */
|
|
if ((status = H5FS_sect_try_extend(f, frsp, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE20,
|
|
(hsize_t)TEST_SECT_SIZE30, 0, NULL)) < 0)
|
|
TEST_ERROR;
|
|
if (false == status)
|
|
TEST_ERROR;
|
|
|
|
/* Succeed in extending the block: total free space is decreased but other info remains the same */
|
|
state.tot_space -= 30;
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
PASSED();
|
|
|
|
/*
|
|
* TEST 4
|
|
*/
|
|
TESTING("a block's extension by requested-size which does not adjoin any free section: Test 4");
|
|
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section A
|
|
*/
|
|
if (NULL == (sect_node1 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node1, (haddr_t)TEST_SECT_ADDR70, (hsize_t)TEST_SECT_SIZE5, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(&state, 0, sizeof(frspace_state_t));
|
|
state.tot_space += sect_node1->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Add section B
|
|
*/
|
|
if (NULL == (sect_node2 = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_sect_node(sect_node2, (haddr_t)TEST_SECT_ADDR100, (hsize_t)TEST_SECT_SIZE40, TEST_FSPACE_SECT_TYPE,
|
|
H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node2, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
state.tot_space += sect_node2->sect_info.size;
|
|
state.tot_sect_count += 1;
|
|
state.serial_sect_count += 1;
|
|
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Extend the block by requested-size */
|
|
if ((status = H5FS_sect_try_extend(f, frsp, (haddr_t)TEST_SECT_ADDR80, (hsize_t)TEST_SECT_SIZE15,
|
|
(hsize_t)TEST_SECT_SIZE40, 0, NULL)) < 0)
|
|
TEST_ERROR;
|
|
if (true == status)
|
|
TEST_ERROR;
|
|
|
|
/* Not able to extend the block: free space manager info remains the same */
|
|
if (check_stats(f, frsp, &state))
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
PASSED();
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_sect_extend() */
|
|
|
|
/*
|
|
* To verify the iteration of free-space sections
|
|
*
|
|
* Create free-space manager with H5FS_CLS_SEPAR_OBJ
|
|
* Create a whole bunch of sections
|
|
* Iterate through all sections and collect size and count for all sections
|
|
* Check info with H5FS_sect_stat()
|
|
*/
|
|
static unsigned
|
|
test_fs_sect_iterate(hid_t fapl)
|
|
{
|
|
hid_t file = H5I_INVALID_HID; /* File ID */
|
|
char filename[FILENAME_LEN]; /* Filename to use */
|
|
H5F_t *f = NULL; /* Internal file object pointer */
|
|
H5FS_t *frsp = NULL; /* pointer to free space structure */
|
|
haddr_t fs_addr = HADDR_UNDEF; /* address of free space */
|
|
uint16_t nclasses;
|
|
H5FS_create_t cparam; /* creation parameters */
|
|
|
|
TEST_free_section_t *sect_node = NULL;
|
|
unsigned init_flags = 0, sect_size;
|
|
TEST_iter_ud_t udata;
|
|
int i;
|
|
hsize_t tot_space, nsects;
|
|
|
|
TESTING("iteration of sections in the free-space manager");
|
|
|
|
/* 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, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(file)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
init_cparam(&cparam);
|
|
nclasses = NELMTS(test_classes);
|
|
udata.tot_size = 0;
|
|
udata.tot_sect_count = 0;
|
|
|
|
/* Tag with the global free space tag */
|
|
H5AC_tag(H5AC__FREESPACE_TAG, NULL);
|
|
|
|
init_flags = H5FS_CLS_SEPAR_OBJ;
|
|
if (NULL == (frsp = H5FS_create(f, &fs_addr, &cparam, nclasses, test_classes, &init_flags,
|
|
(hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!H5_addr_defined(fs_addr))
|
|
TEST_ERROR;
|
|
|
|
for (i = 1; i <= NUM_SECTIONS; i++) {
|
|
if (NULL == (sect_node = (TEST_free_section_t *)malloc(sizeof(TEST_free_section_t))))
|
|
FAIL_STACK_ERROR;
|
|
|
|
sect_size = (unsigned)((i - 1) % 9) + 1;
|
|
init_sect_node(sect_node, (haddr_t)i * 10, (hsize_t)sect_size, TEST_FSPACE_SECT_TYPE, H5FS_SECT_LIVE);
|
|
|
|
if (H5FS_sect_add(f, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
} /* end for */
|
|
|
|
if (H5FS_sect_iterate(f, frsp, TEST_sects_cb, &udata) < 0)
|
|
TEST_ERROR;
|
|
|
|
H5FS_sect_stats(frsp, &tot_space, &nsects);
|
|
|
|
if (udata.tot_size != tot_space)
|
|
TEST_ERROR;
|
|
if (udata.tot_sect_count != nsects)
|
|
TEST_ERROR;
|
|
|
|
/* Close the free space manager */
|
|
if (H5FS_close(f, frsp) < 0)
|
|
FAIL_STACK_ERROR;
|
|
frsp = NULL;
|
|
|
|
/* Delete free space manager */
|
|
if (H5FS_delete(f, fs_addr) < 0)
|
|
FAIL_STACK_ERROR;
|
|
fs_addr = HADDR_UNDEF;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(file) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
if (frsp)
|
|
H5FS_close(f, frsp);
|
|
H5Fclose(file);
|
|
}
|
|
H5E_END_TRY
|
|
return 1;
|
|
} /* test_fs_sect_iterate() */
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */
|
|
unsigned nerrors = 0; /* Cumulative error count */
|
|
H5CX_node_t api_ctx = {{0}, NULL}; /* API context node to push */
|
|
bool api_ctx_pushed = false; /* Whether API context pushed */
|
|
|
|
h5_test_init();
|
|
|
|
if ((fapl = h5_fileaccess()) < 0) {
|
|
nerrors++;
|
|
PUTS_ERROR("Can't get VFD-dependent fapl");
|
|
} /* end if */
|
|
|
|
/* Push API context */
|
|
if (H5CX_push(&api_ctx) < 0)
|
|
FAIL_STACK_ERROR;
|
|
api_ctx_pushed = true;
|
|
|
|
/* make sure alignment is not set for tests to succeed */
|
|
if (H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1) < 0) {
|
|
nerrors++;
|
|
PUTS_ERROR("Can't set alignment");
|
|
} /* end if */
|
|
|
|
nerrors += test_fs_create(fapl);
|
|
nerrors += test_fs_sect_add(fapl);
|
|
nerrors += test_fs_sect_merge(fapl);
|
|
nerrors += test_fs_sect_shrink(fapl);
|
|
nerrors += test_fs_sect_find(fapl);
|
|
nerrors += test_fs_sect_change_class(fapl);
|
|
nerrors += test_fs_sect_extend(fapl);
|
|
nerrors += test_fs_sect_iterate(fapl);
|
|
|
|
/* Verify symbol table messages are cached */
|
|
nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0);
|
|
|
|
if (nerrors)
|
|
goto error;
|
|
puts("All free-space tests passed.");
|
|
|
|
/* Pop API context */
|
|
if (api_ctx_pushed && H5CX_pop(false) < 0)
|
|
FAIL_STACK_ERROR;
|
|
api_ctx_pushed = false;
|
|
|
|
h5_cleanup(FILENAME, fapl);
|
|
exit(EXIT_SUCCESS);
|
|
|
|
error:
|
|
puts("*** TESTS FAILED ***");
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
if (api_ctx_pushed)
|
|
H5CX_pop(false);
|
|
|
|
exit(EXIT_FAILURE);
|
|
} /* main() */
|