/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * Copyright by the Board of Trustees of the University of Illinois. * * 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 COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * * 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 "H5Iprivate.h" #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 */ 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. */ HDassert(cls); HDassert(_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. */ HDassert(sect1); HDassert(sect2); HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */ HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)); /* Check if second section adjoins first section */ ret_value = H5F_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. */ HDassert(sect1); HDassert(((*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)); HDassert(sect2); HDassert((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)); HDassert(H5F_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 */ HDfree(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 */ HDassert(sect); HDassert(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) { HDmemset(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) { HDfprintf(stdout, "frspace_stats.tot_space = %Hu, state->tot_space = %Zu\n", frspace_stats.tot_space, state->tot_space); TEST_ERROR } /* end if */ if(frspace_stats.tot_sect_count != state->tot_sect_count) { HDfprintf(stdout, "frspace_stats.tot_sect_count = %Hu, state->tot_sect_count = %Hu\n", frspace_stats.tot_sect_count, state->tot_sect_count); TEST_ERROR } /* end if */ if(frspace_stats.serial_sect_count != state->serial_sect_count) { HDfprintf(stdout, "frspace_stats.serial_sect_count = %Hu, state->serial_sect_count = %Hu\n", frspace_stats.serial_sect_count, state->serial_sect_count); TEST_ERROR } /* end if */ if(frspace_stats.ghost_sect_count != state->ghost_sect_count) { HDfprintf(stdout, "frspace_stats.ghost_sect_count = %Hu, state->ghost_sect_count = %Hu\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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl ID (for tag) */ 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 *)H5I_object(file))) FAIL_STACK_ERROR /* initialize creation parameters for free-space manager */ init_cparam(&cparam); nclasses = NELMTS(test_classes); /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if (frsp->nclasses != nclasses) TEST_ERROR HDmemset(&state, 0, sizeof(frspace_state_t)); if(check_stats(f, frsp, &state)) TEST_ERROR HDmemset(&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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* reopen the free-space manager */ if(NULL == (frsp = H5FS_open(f, dxpl_id, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if (frsp->nclasses != nclasses) TEST_ERROR /* Close the free space manager */ if(H5FS_close(f, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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 /* Close the dxpl */ if(H5Pclose(dxpl_id) < 0) FAIL_STACK_ERROR; PASSED() return 0; error: H5E_BEGIN_TRY { if(frsp) H5FS_close(f, dxpl_id, frsp); H5Fclose(file); H5Pclose(dxpl_id); } 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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl_id (for tag) */ 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if(NULL == (sect_node = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Close the file */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR /* 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); init_flags = H5FS_CLS_GHOST_OBJ; if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* Create free list section node */ if(NULL == (sect_node = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node, 0, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR /* Close the file */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR /* 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 *)H5I_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, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if(NULL == (sect_node = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) FAIL_STACK_ERROR /* nothing in free-space */ HDmemset(&state, 0, sizeof(frspace_state_t)); if(check_stats(f, frsp, &state)) TEST_ERROR /* Close the free space manager */ if(H5FS_close(f, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; /* Close the file */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR 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 *)H5I_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, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if(NULL == (sect_node = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_DESERIALIZING, &can_shrink) < 0) FAIL_STACK_ERROR HDmemset(&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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; /* Close the file and dxpl */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR if(H5Pclose(dxpl_id) < 0) FAIL_STACK_ERROR PASSED() return 0; error: H5E_BEGIN_TRY { if(sect_node) TEST_sect_free((H5FS_section_info_t *)sect_node); if(frsp) H5FS_close(f, dxpl_id, frsp); H5Fclose(file); H5Pclose(dxpl_id); } 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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl ID (for tag) */ 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR HDmemset(&state, 0, sizeof(frspace_state_t)); if(check_stats(f, frsp, &state)) TEST_ERROR if((node_found = H5FS_sect_find(f, dxpl_id, 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, dxpl_id, 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, dxpl_id, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if (frsp->nclasses != nclasses) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1) < 0) FAIL_STACK_ERROR if(H5FS_sect_remove(f, dxpl_id, frsp, (H5FS_section_info_t *)sect_node3) < 0) FAIL_STACK_ERROR if(H5FS_sect_remove(f, dxpl_id, 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, dxpl_id, 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, dxpl_id, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if (frsp->nclasses != nclasses) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, fs_addr, nclasses, test_classes, NULL, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR if (frsp->nclasses != nclasses) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; /* Close the file and dxpl */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR if(H5Pclose(dxpl_id) < 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, dxpl_id, frsp); H5Fclose(file); H5Pclose(dxpl_id); } 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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl ID (for tag) */ 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section C */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); init_flags = H5FS_CLS_SEPAR_OBJ; if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1) < 0) FAIL_STACK_ERROR /* remove section B from free-space */ if(H5FS_sect_remove(f, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); init_flags = 0; /* reset */ if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; /* Close the file and dxpl */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR if(H5Pclose(dxpl_id) < 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, dxpl_id, frsp); H5Pclose(dxpl_id); 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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl ID (for tag) */ 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 *)H5I_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 */ /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_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 *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) FAIL_STACK_ERROR HDmemset(&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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) FAIL_STACK_ERROR /* should have nothing in free-space */ HDmemset(&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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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 *)H5I_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, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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 *)H5I_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, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, &can_shrink) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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 */ HDmemset(&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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; /* Close the file and dxpl */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR if(H5Pclose(dxpl_id) < 0) FAIL_STACK_ERROR PASSED() return 0; error: H5E_BEGIN_TRY { if(frsp) H5FS_close(f, dxpl_id, frsp); H5Fclose(file); H5Pclose(dxpl_id); } 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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl ID (for tag) */ 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR init_flags = H5FS_CLS_GHOST_OBJ; if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); init_flags = H5FS_CLS_SEPAR_OBJ; if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; /* Close the file and dxpl */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR if(H5Pclose(dxpl_id) < 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, dxpl_id, frsp); H5Fclose(file); H5Pclose(dxpl_id); } 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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl ID (for tag) */ 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 *)H5I_object(file))) FAIL_STACK_ERROR /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR /* * TEST 1 */ init_cparam(&cparam); nclasses = NELMTS(test_classes); if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, 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, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR /* * Add section A */ if(NULL == (sect_node1 = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node1, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR HDmemset(&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 *)HDmalloc(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, dxpl_id, 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, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; PASSED() /* Close the file and dxpl */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR if(H5Pclose(dxpl_id) < 0) FAIL_STACK_ERROR return 0; error: H5E_BEGIN_TRY { if(frsp) H5FS_close(f, dxpl_id, frsp); H5Fclose(file); H5Pclose(dxpl_id); } 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 = -1; /* File ID */ hid_t dxpl_id = -1; /* dxpl ID (for tag) */ 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 *)H5I_object(file))) FAIL_STACK_ERROR init_cparam(&cparam); nclasses = NELMTS(test_classes); udata.tot_size = 0; udata.tot_sect_count = 0; /* Create the dxpl and tag it with the global free space tag */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) FAIL_STACK_ERROR if(H5AC_tag(dxpl_id, H5AC__FREESPACE_TAG, NULL) < 0) FAIL_STACK_ERROR init_flags = H5FS_CLS_SEPAR_OBJ; if(NULL == (frsp = H5FS_create(f, dxpl_id, &fs_addr, &cparam, nclasses, test_classes, &init_flags, (hsize_t)FSPACE_THRHD_DEF, (hsize_t)FSPACE_ALIGN_DEF))) FAIL_STACK_ERROR if(!H5F_addr_defined(fs_addr)) TEST_ERROR for (i = 1; i <= NUM_SECTIONS; i++) { if(NULL == (sect_node = (TEST_free_section_t *)HDmalloc(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, dxpl_id, frsp, (H5FS_section_info_t *)sect_node, H5FS_ADD_RETURNED_SPACE, NULL) < 0) FAIL_STACK_ERROR } /* end for */ if(H5FS_sect_iterate(f, dxpl_id, 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, dxpl_id, frsp) < 0) FAIL_STACK_ERROR frsp = NULL; /* Delete free space manager */ if(H5FS_delete(f, dxpl_id, fs_addr) < 0) FAIL_STACK_ERROR fs_addr = HADDR_UNDEF; /* Close the file and dxpl */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR if(H5Pclose(dxpl_id) < 0) FAIL_STACK_ERROR PASSED() return 0; error: H5E_BEGIN_TRY { if(frsp) H5FS_close(f, dxpl_id, frsp); H5Fclose(file); H5Pclose(dxpl_id); } H5E_END_TRY; return 1; } /* test_fs_sect_iterate() */ int main(void) { hid_t fapl = -1; /* File access property list for data files */ unsigned nerrors = 0; /* Cumulative error count */ const char *env_h5_drvr = NULL; /* File Driver value from environment */ /* Get the VFD to use */ env_h5_drvr = HDgetenv("HDF5_DRIVER"); if(env_h5_drvr == NULL) env_h5_drvr = "nomatch"; h5_reset(); if((fapl = h5_fileaccess()) < 0) { nerrors++; PUTS_ERROR("Can't get VFD-dependent fapl") } /* end if */ /* 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; HDputs("All free-space tests passed."); h5_cleanup(FILENAME, fapl); HDexit(EXIT_SUCCESS); error: HDputs("*** TESTS FAILED ***"); H5E_BEGIN_TRY { H5Pclose(fapl); } H5E_END_TRY; HDexit(EXIT_FAILURE); } /* main() */