From ea7a5346d7a7387a627142bd3a1e7b597f2c4a6d Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 1 Apr 2006 16:09:48 -0500 Subject: [svn-r12190] Purpose: Code checkpoint Description: Update fractal heap code to allow skipping direct blocks (that are too small to hold object) when the root indirect block is created. Platforms tested: FreeBSD 4.11 (sleipnir) Too minor to require h5committest --- src/H5HFint.c | 27 +++++++---- test/fheap.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 154 insertions(+), 21 deletions(-) diff --git a/src/H5HFint.c b/src/H5HFint.c index 72eace9..421449c 100644 --- a/src/H5HFint.c +++ b/src/H5HFint.c @@ -1799,6 +1799,9 @@ H5HF_man_iblock_place_dblock(H5HF_t *hdr, hid_t dxpl_id, size_t min_dblock_size, H5HF_indirect_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_place_dblock) +#ifdef QAK +HDfprintf(stderr, "%s: min_dblock_size = %Zu\n", FUNC, min_dblock_size); +#endif /* QAK */ /* * Check arguments. @@ -1810,6 +1813,7 @@ H5HF_man_iblock_place_dblock(H5HF_t *hdr, hid_t dxpl_id, size_t min_dblock_size, /* Check for creating first indirect block */ if(hdr->man_dtable.curr_root_rows == 0) { H5HF_direct_t *dblock; /* Pointer to direct block to query */ + hbool_t have_direct_block; /* Flag to indicate a direct block already exists */ unsigned nrows; /* Number of rows for root indirect block */ #ifdef QAK @@ -1844,7 +1848,8 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") /* Check if there's already a direct block as root) */ - if(H5F_addr_defined(hdr->man_dtable.table_addr)) { + have_direct_block = H5F_addr_defined(hdr->man_dtable.table_addr); + if(have_direct_block) { /* Lock first (root) direct block */ if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, &hdr->man_dtable.cparam.start_block_size, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block") @@ -1872,7 +1877,9 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); if(H5HF_man_iblock_inc_loc(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") } /* end if */ - else { + + /* Check for skipping over direct blocks, in order to get to large enough block */ + if(min_dblock_size > iblock->next_size) { H5HF_section_free_node_t *sec_node; /* Pointer to free list section for range */ size_t dblock_free_space; /* Size of free space for direct block */ hsize_t range; /* Size range skipped over */ @@ -1880,7 +1887,7 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); unsigned u, v; /* Local index variables */ /* Initialize information for rows skipped over */ - cur_entry = 0; + cur_entry = (unsigned)have_direct_block; range = 0; for(u = 0; u < (nrows - 1); u++) { /* Compute free space in direct blocks for this row */ @@ -1889,7 +1896,11 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr)); /* Initialize information for this row */ - for(v = 0; v < hdr->man_dtable.cparam.width; v++) { + if(u == 0 && have_direct_block) + v = 1; + else + v = 0; + for(; v < hdr->man_dtable.cparam.width; v++) { /* Initialize entry for this row */ iblock->ents[cur_entry].addr = HADDR_UNDEF; iblock->ents[cur_entry].free_space = dblock_free_space; @@ -1915,18 +1926,18 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); /* Create free space section for blocks skipped over */ - /* Create free list section node */ + /* Create free list section node for blocks skipped over */ if(NULL == (sec_node = H5FL_MALLOC(H5HF_section_free_node_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct block free list section") /* Set section's information */ - sec_node->sect_addr = 0; /* Range starts at offset 0 in the heap */ + sec_node->sect_addr = (hsize_t)have_direct_block * hdr->man_dtable.row_block_size[0]; /* Range starts at offset 0 in the heap */ sec_node->sect_size = dblock_free_space; sec_node->type = H5HF_SECT_RANGE; sec_node->u.range.iblock_addr = iblock->addr; sec_node->u.range.iblock_nrows = iblock->nrows; - sec_node->u.range.entry = 0; - sec_node->u.range.num_entries = cur_entry; + sec_node->u.range.entry = (unsigned)have_direct_block; + sec_node->u.range.num_entries = cur_entry - (unsigned)have_direct_block; sec_node->u.range.range = range; /* Add new free space to the global list of space */ diff --git a/test/fheap.c b/test/fheap.c index af28b12..8f2bbc7 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -496,7 +496,7 @@ test_abs_insert_first(hid_t fapl, H5HF_create_t *cparam) HDmemset(heap_id, 0, sizeof(heap_id)); if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, heap_id) < 0) FAIL_STACK_ERROR - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)1)) FAIL_STACK_ERROR @@ -586,7 +586,7 @@ test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam) HDmemset(heap_id, 0, sizeof(heap_id)); if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, heap_id) < 0) FAIL_STACK_ERROR - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)1)) FAIL_STACK_ERROR @@ -600,7 +600,7 @@ test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam) HDmemset(heap_id, 0, sizeof(heap_id)); if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj2), obj2, heap_id) < 0) FAIL_STACK_ERROR - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + (sizeof(obj2) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + (sizeof(obj2) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)2)) FAIL_STACK_ERROR @@ -770,7 +770,7 @@ test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam) /* Increment object count */ nobjs++; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)(2 * cparam->managed.start_block_size), (hsize_t)(2 * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)nobjs)) FAIL_STACK_ERROR @@ -951,7 +951,7 @@ test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam) /* Increment object count */ tot_nobjs++; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)(3 * cparam->managed.start_block_size), (hsize_t)(3 * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -1135,7 +1135,7 @@ test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam) /* Increment object count */ tot_nobjs++; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)((cparam->managed.width + 1) * cparam->managed.start_block_size), (hsize_t)((cparam->managed.width + 1) * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -1339,7 +1339,7 @@ test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam) heap_size = (2 * cparam->managed.width) * cparam->managed.start_block_size + (2 * cparam->managed.start_block_size); - free_space = (2 * cparam->managed.start_block_size) - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = (2 * cparam->managed.start_block_size) - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -1648,7 +1648,7 @@ test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) tot_nobjs++; heap_size += cparam->managed.start_block_size; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -1782,7 +1782,7 @@ test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) tot_nobjs++; heap_size += cparam->managed.start_block_size; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -2058,7 +2058,7 @@ test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) tot_nobjs++; heap_size += cparam->managed.start_block_size; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -2489,7 +2489,7 @@ test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) tot_nobjs++; heap_size += cparam->managed.start_block_size; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -2775,7 +2775,7 @@ test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) tot_nobjs++; heap_size += cparam->managed.start_block_size; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -3538,7 +3538,7 @@ test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) tot_nobjs++; heap_size += cparam->managed.start_block_size; - free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR @@ -5347,6 +5347,127 @@ error: /*------------------------------------------------------------------------- + * Function: test_abs_skip_2nd_block + * + * Purpose: Test inserting object into absolute heap which is small + * enough for starting block size, then add object too large + * for any blocks in first row of direct blocks, to force + * early creation of indirect block (and range of skipped blocks) + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Saturday, April 1, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned char obj[10]; /* Buffer for first object to insert */ + unsigned char robj[10]; /* Buffer for reading first object */ + unsigned char *obj2; /* Buffer for second object to insert */ + unsigned char *robj2; /* Buffer for reading second object */ + unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ + size_t obj2_size; /* Size of object to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned u; /* Local index variable */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + + /* Initialize object buffers */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u; + obj2_size = cparam->managed.start_block_size + 1; + obj2 = H5MM_malloc(obj2_size); + for(u = 0; u < obj2_size; u++) + obj2[u] = u + 10; + + /* + * Test inserting first (small) object into absolute heap + */ + TESTING("inserting two (small) objects into absolute heap"); + HDmemset(heap_id, 0, sizeof(heap_id)); + if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, heap_id) < 0) + FAIL_STACK_ERROR + free_space = cparam->managed.start_block_size - ((sizeof(obj) + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)1)) + FAIL_STACK_ERROR + + /* Check reading back in the first object */ + if(H5HF_read(f, dxpl, fh_addr, heap_id, robj) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj, robj, sizeof(obj))) + FAIL_STACK_ERROR + + /* Insert second object, to force creation of indirect block and + * range of skipped blocks that are too small to hold the second object + */ + HDmemset(heap_id, 0, sizeof(heap_id)); + if(H5HF_insert(f, dxpl, fh_addr, obj2_size, obj2, heap_id) < 0) + FAIL_STACK_ERROR + free_space += (cparam->managed.start_block_size - (OBJ_PREFIX_LEN + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8))) * (cparam->managed.width - 1); /* Rest of first row */ + free_space += (cparam->managed.start_block_size - (OBJ_PREFIX_LEN + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8))) * cparam->managed.width; /* All of second row (blocks are same size as first row) */ + free_space += (2 * cparam->managed.start_block_size) - ((obj2_size + OBJ_PREFIX_LEN) + OBJ_PREFIX_LEN +DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + heap_size = cparam->managed.start_block_size + (2 * cparam->managed.start_block_size); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)2)) + FAIL_STACK_ERROR + + /* Check reading back in the second object */ + robj2 = H5MM_malloc(obj2_size); + if(H5HF_read(f, dxpl, fh_addr, heap_id, robj2) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj2, robj2, obj2_size)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + H5MM_xfree(obj2); + H5MM_xfree(robj2); + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + H5MM_xfree(obj2); + H5MM_xfree(robj2); + return(1); +} /* test_abs_skip_2nd_block() */ + + +/*------------------------------------------------------------------------- * Function: run_tests * * Purpose: Test the fractal heap code, with different file access property @@ -5413,6 +5534,7 @@ HDfprintf(stderr, "Uncomment tests!\n"); nerrors += test_abs_skip_start_block(fapl, cparam); nerrors += test_abs_skip_start_block_add_back(fapl, cparam); nerrors += test_abs_skip_start_block_add_skipped(fapl, cparam); + nerrors += test_abs_skip_2nd_block(fapl, cparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ -- cgit v0.12