diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-03-21 02:59:06 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-03-21 02:59:06 (GMT) |
commit | 2db47ff504a58278019957f9e5bc446d58894fed (patch) | |
tree | 68c74feaf21d39a5dfbd2612210ceed8dd7ba513 /src/H5HFint.c | |
parent | a2f9ebb3ab3228563835681a19cdd88fc095b2ff (diff) | |
download | hdf5-2db47ff504a58278019957f9e5bc446d58894fed.zip hdf5-2db47ff504a58278019957f9e5bc446d58894fed.tar.gz hdf5-2db47ff504a58278019957f9e5bc446d58894fed.tar.bz2 |
[svn-r12125] Purpose:
Code checkpoint
Description:
Update fractal heap code to insert & read heaps up to 64MB in size
(with my current configuration paramaters) and add initial support for
iteratively walking down nested indirect blocks.
Platforms tested:
FreeBSD 4.11 (sleipnir)
Linux 2.4 (chicago)
Solaris 9 (shanti)
Linux 2.4 (mir) w/64-bit
Diffstat (limited to 'src/H5HFint.c')
-rw-r--r-- | src/H5HFint.c | 474 |
1 files changed, 300 insertions, 174 deletions
diff --git a/src/H5HFint.c b/src/H5HFint.c index bbae6a2..e25ad64 100644 --- a/src/H5HFint.c +++ b/src/H5HFint.c @@ -98,7 +98,7 @@ static H5HF_indirect_t * H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t d size_t min_dblock_size, haddr_t *addr_p, size_t *entry_p, size_t *dblock_size); static herr_t H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id, - hsize_t block_off, unsigned nrows, unsigned max_dir_rows, haddr_t *addr_p); + hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p); /*********************/ /* Package Variables */ @@ -119,11 +119,8 @@ H5FL_DEFINE(H5HF_section_free_node_t); /* Declare a free list to manage the H5HF_indirect_t struct */ H5FL_DEFINE(H5HF_indirect_t); -/* Declare a free list to manage the H5HF_indirect_dblock_ent_t sequence information */ -H5FL_SEQ_DEFINE(H5HF_indirect_dblock_ent_t); - -/* Declare a free list to manage the H5HF_indirect_iblock_ent_t sequence information */ -H5FL_SEQ_DEFINE(H5HF_indirect_iblock_ent_t); +/* Declare a free list to manage the H5HF_indirect_ent_t sequence information */ +H5FL_SEQ_DEFINE(H5HF_indirect_ent_t); /*****************************/ @@ -171,18 +168,18 @@ H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable) /* Compute/cache some values */ dtable->first_row_bits = H5V_log2_of2(dtable->cparam.start_block_size) + H5V_log2_of2(dtable->cparam.width); - dtable->max_root_indirect_rows = (dtable->cparam.max_index - dtable->first_row_bits) + 1; + dtable->max_root_rows = (dtable->cparam.max_index - dtable->first_row_bits) + 1; dtable->max_direct_rows = (H5V_log2_of2(dtable->cparam.max_direct_size) - H5V_log2_of2(dtable->cparam.start_block_size)) + 2; dtable->num_id_first_row = dtable->cparam.start_block_size * dtable->cparam.width; dtable->max_dir_blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dtable->cparam.max_direct_size); /* Build table of block sizes for each row */ - if(NULL == (dtable->row_block_size = H5MM_malloc(dtable->max_root_indirect_rows * sizeof(hsize_t)))) + if(NULL == (dtable->row_block_size = H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table block size table") tmp_block_size = dtable->cparam.start_block_size; dtable->row_block_size[0] = dtable->cparam.start_block_size; - for(u = 1; u < dtable->max_root_indirect_rows; u++) { + for(u = 1; u < dtable->max_root_rows; u++) { dtable->row_block_size[u] = tmp_block_size; tmp_block_size *= 2; } /* end for */ @@ -266,6 +263,8 @@ H5HF_shared_alloc(H5F_t *f) /* Set the internal parameters for the heap */ shared->f = f; + shared->sizeof_size = H5F_SIZEOF_SIZE(f); + shared->sizeof_addr = H5F_SIZEOF_ADDR(f); /* Set the return value */ ret_value = shared; @@ -338,17 +337,16 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_shared_create(H5F_t *f, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) +H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) { - H5HF_shared_t *shared = NULL; /* Shared fractal heap information */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_create) + FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_init) /* * Check arguments. */ - HDassert(f); + HDassert(shared); HDassert(fh); HDassert(cparam); @@ -363,14 +361,10 @@ H5HF_shared_create(H5F_t *f, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two") if(cparam->managed.max_direct_size < cparam->standalone_size) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not large enough to hold all managed blocks") - if(cparam->managed.max_index > (8 * H5F_SIZEOF_SIZE(f)) || cparam->managed.max_index == 0) + if(cparam->managed.max_index > (8 * shared->sizeof_size) || cparam->managed.max_index == 0) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two") #endif /* NDEBUG */ - /* Allocate & basic initialization for the shared info struct */ - if(NULL == (shared = H5HF_shared_alloc(f))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for shared heap info") - /* Set the creation parameters for the heap */ shared->heap_addr = fh_addr; shared->addrmap = cparam->addrmap; @@ -394,7 +388,7 @@ done: H5HF_shared_free(shared); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_shared_create() */ +} /* end H5HF_shared_init() */ /*------------------------------------------------------------------------- @@ -451,8 +445,9 @@ static herr_t H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) { H5HF_shared_t *shared; /* Pointer to shared heap info */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iblock_inc_loc) + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_inc_loc) /* * Check arguments. @@ -463,33 +458,44 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) shared = H5RC_GET_OBJ(iblock->shared); HDassert(shared); + /* Increment block entry */ + iblock->next_entry++; + /* Increment column */ - iblock->next_dir_col++; + iblock->next_col++; /* Check for walking off end of column */ - if(iblock->next_dir_col == shared->man_dtable.cparam.width) { + if(iblock->next_col == shared->man_dtable.cparam.width) { /* Reset column */ - iblock->next_dir_col = 0; + iblock->next_col = 0; - /* Increment row & direct block size */ - iblock->next_dir_row++; - iblock->next_dir_size *= 2; + /* Increment row & block size */ + iblock->next_row++; + iblock->next_size *= 2; - /* Check for filling up all direct block entries in indirect block */ - if(iblock->next_dir_row == iblock->max_direct_rows) - iblock->dir_full = TRUE; + /* Check for filling up indirect block */ + if(iblock->next_row == iblock->max_rows) { + /* Check for "full" heap */ + if(iblock->parent == NULL) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location") + + /* Increment location for parent indirect block */ + iblock = H5RC_GET_OBJ(iblock->parent); + if(H5HF_man_iblock_inc_loc(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location") + } /* end if */ } /* end if */ #ifdef QAK -HDfprintf(stderr, "%s: iblock->next_dir_row = %u\n", "H5HF_man_iblock_inc_loc", iblock->next_dir_row); -HDfprintf(stderr, "%s: iblock->next_dir_col = %u\n", "H5HF_man_iblock_inc_loc", iblock->next_dir_col); -HDfprintf(stderr, "%s: iblock->next_dir_size = %Zu\n", "H5HF_man_iblock_inc_loc", iblock->next_dir_size); -HDfprintf(stderr, "%s: iblock->dir_full = %u\n", "H5HF_man_iblock_inc_loc", (unsigned)iblock->dir_full); +HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row); +HDfprintf(stderr, "%s: iblock->next_col = %u\n", FUNC, iblock->next_col); +HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size); #endif /* QAK */ /* Mark heap header as modified */ shared->dirty = TRUE; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_iblock_inc_loc() */ @@ -851,7 +857,7 @@ HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt); #ifdef QAK HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_free", iblock->child_free_space); #endif /* QAK */ - iblock->dblock_ents[dblock->parent_entry].free_space += amt; + iblock->ents[dblock->parent_entry].free_space += amt; iblock->child_free_space += amt; /* Mark indirect block as dirty */ @@ -867,7 +873,7 @@ HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_f HDassert(iblock); /* Adjust this indirect block's child free space */ - iblock->iblock_ents[parent_entry].free_space += amt; + iblock->ents[parent_entry].free_space += amt; iblock->child_free_space += amt; /* Mark indirect block as dirty */ @@ -988,14 +994,10 @@ HDfprintf(stderr, "%s: dblock_size = %Zu\n", FUNC, dblock_size); #ifdef QAK HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr); -HDfprintf(stderr, "%s: shared->man_dtable.next_dir_block = %Hu\n", FUNC, shared->man_dtable.next_dir_block); #endif /* QAK */ /* Point indirect block at new direct block */ - iblock->dblock_ents[dblock_entry].addr = dblock_addr; - - /* Increment size of next block from this indirect block */ - H5HF_man_iblock_inc_loc(iblock); + iblock->ents[dblock_entry].addr = dblock_addr; /* Mark indirect block as modified */ iblock->dirty = TRUE; @@ -1287,8 +1289,14 @@ done: herr_t H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj) { + H5HF_parent_shared_t par_shared; /* Parent shared information */ H5HF_shared_t *shared; /* Pointer to shared heap info */ - unsigned row, col; /* Row & column for object's block */ + H5HF_direct_t *dblock; /* Pointer to direct block to query */ + size_t blk_off; /* Offset of object in block */ + uint8_t *p; /* Temporary pointer to obj info in block */ + size_t obj_size; /* Size of object */ + haddr_t dblock_addr; /* Direct block address */ + size_t dblock_size; /* Direct block size */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_read) @@ -1306,52 +1314,125 @@ H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj) /* Check for root direct block */ if(shared->man_dtable.curr_root_rows == 0) { - H5HF_parent_shared_t par_shared; /* Parent shared information */ - H5HF_direct_t *dblock; /* Pointer to direct block to query */ - size_t blk_off; /* Offset of object in block */ - uint8_t *p; /* Temporary pointer to obj info in block */ - size_t obj_size; /* Size of object */ + /* Set direct block info */ + par_shared.shared = fh_shared; + par_shared.parent = NULL; + par_shared.parent_entry = 0; + par_shared.parent_free_space = shared->total_man_free; + + dblock_addr = shared->man_dtable.table_addr; + dblock_size = shared->man_dtable.cparam.start_block_size; + + /* Lock direct block */ + if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") + } /* end if */ + else { + haddr_t iblock_addr; /* Indirect block's address */ + H5HF_indirect_t *iblock; /* Pointer to indirect block */ + unsigned row, col; /* Row & column for object's block */ + size_t entry; /* Entry of block */ -#ifdef QAK /* Look up row & column for object */ if(H5HF_dtable_lookup(&shared->man_dtable, obj_off, &row, &col) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object") +#ifdef QAK HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col); #endif /* QAK */ - /* Lock first (root) direct block */ + /* Set initial indirect block info */ + iblock_addr = shared->man_dtable.table_addr; + + /* Lock indirect block */ par_shared.shared = fh_shared; par_shared.parent = NULL; par_shared.parent_entry = 0; par_shared.parent_free_space = shared->total_man_free; - if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.cparam.start_block_size, &par_shared, H5AC_READ))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block") + if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") - /* Compute offset of object within block */ - HDassert((obj_off - dblock->block_off) < (hsize_t)shared->man_dtable.cparam.start_block_size); - blk_off = (size_t)(obj_off - dblock->block_off); + /* Check for indirect block row */ + while(row >= shared->man_dtable.max_direct_rows) { + haddr_t new_iblock_addr; /* New indirect block's address */ + H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */ + unsigned nrows; /* Number of rows in new indirect block */ - /* Point to location for object */ - p = dblock->blk + blk_off; + /* Compute # of rows in child indirect block */ + nrows = (H5V_log2_gen(shared->man_dtable.row_block_size[row]) - shared->man_dtable.first_row_bits) + 1; - /* Decode the length */ - UINT64DECODE_VAR(p, obj_size, dblock->blk_off_size); + /* Compute indirect block's entry */ + entry = (row * shared->man_dtable.cparam.width) + col; - /* Skip over the free fragment size & ref count */ - p += 1 + (shared->ref_count_obj ? shared->ref_count_size : 0); + /* Locate child indirect block */ + new_iblock_addr = iblock->ents[entry].addr; - /* Copy the object's data into the heap */ - HDmemcpy(obj, p, obj_size); + /* Lock new indirect block */ + par_shared.shared = fh_shared; + par_shared.parent = iblock->self; + par_shared.parent_entry = entry; + par_shared.parent_free_space = iblock->ents[entry].free_space; + if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + + /* Release the current indirect block (possibly marked as dirty) */ + if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") + + /* Switch variables to use new indirect block */ + iblock = new_iblock; + iblock_addr = new_iblock_addr; + + /* Look up row & column in new indirect block for object */ + if(H5HF_dtable_lookup(&shared->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object") + } /* end while */ - /* Unlock first (root) direct block */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap direct block") - dblock = NULL; - } /* end if */ - else { -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "root indirect blocks not supported yet") + /* Compute direct block's entry */ + entry = (row * shared->man_dtable.cparam.width) + col; +#ifdef QAK +HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->dblock_ents[entry].addr); +#endif /* QAK */ + + /* Set direct block info */ + par_shared.shared = fh_shared; + par_shared.parent = iblock->self; + par_shared.parent_entry = entry; + par_shared.parent_free_space = iblock->ents[entry].free_space; + + dblock_addr = iblock->ents[entry].addr; + dblock_size = shared->man_dtable.row_block_size[row]; + + /* Lock direct block */ + if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") + + /* Unlock indirect block */ + if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") + iblock = NULL; } /* end else */ + /* Compute offset of object within block */ + HDassert((obj_off - dblock->block_off) < (hsize_t)dblock_size); + blk_off = (size_t)(obj_off - dblock->block_off); + + /* Point to location for object */ + p = dblock->blk + blk_off; + + /* Decode the length */ + UINT64DECODE_VAR(p, obj_size, dblock->blk_off_size); + + /* Skip over the free fragment size & ref count */ + p += 1 + (shared->ref_count_obj ? shared->ref_count_size : 0); + + /* Copy the object's data into the heap */ + HDmemcpy(obj, p, obj_size); + + /* Unlock direct block */ + if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block") + dblock = NULL; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_read() */ @@ -1390,10 +1471,8 @@ HDfprintf(stderr, "%s: Freeing indirect block\n", "H5HF_iblock_free"); H5RC_DEC(iblock->parent); /* Release entry tables */ - if(iblock->dblock_ents) - H5FL_SEQ_FREE(H5HF_indirect_dblock_ent_t, iblock->dblock_ents); - if(iblock->iblock_ents) - H5FL_SEQ_FREE(H5HF_indirect_iblock_ent_t, iblock->iblock_ents); + if(iblock->ents) + H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents); /* Free fractal heap indirect block info */ H5FL_FREE(H5HF_indirect_t, iblock); @@ -1425,6 +1504,7 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_parent_shared_t par_shared; /* Parent shared information */ H5HF_shared_t *shared; /* Pointer to shared heap info */ H5HF_indirect_t *iblock; /* Pointer to indirect block */ + haddr_t iblock_addr; /* Indirect block's address */ H5HF_indirect_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_place_dblock) @@ -1445,26 +1525,20 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_direct_t *dblock; /* Pointer to direct block to query */ unsigned nrows; /* Number of rows for root indirect block */ - /* Check for skipping over blocks */ - if(min_dblock_size != shared->man_dtable.cparam.start_block_size) { -HDfprintf(stderr, "%s: Skipping direct block sizes not supported\n", FUNC); -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "skipping direct block sizes not supported yet") - } /* end if */ - #ifdef QAK HDfprintf(stderr, "%s: creating first indirect block\n", FUNC); #endif /* QAK */ /* Check for allocating entire root indirect block initially */ if(shared->man_dtable.cparam.start_root_rows == 0) - nrows = shared->man_dtable.max_root_indirect_rows; + nrows = shared->man_dtable.max_root_rows; else nrows = shared->man_dtable.cparam.start_root_rows; /* Allocate root indirect block */ - if(H5HF_man_iblock_create(fh_shared, dxpl_id, (hsize_t)0, nrows, shared->man_dtable.max_direct_rows, addr_p) < 0) + if(H5HF_man_iblock_create(fh_shared, dxpl_id, (hsize_t)0, nrows, shared->man_dtable.max_root_rows, &iblock_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block") #ifdef QAK -HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p); +HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); #endif /* QAK */ /* Move current direct block (used as root) into new indirect block */ @@ -1474,7 +1548,7 @@ HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p); par_shared.parent = NULL; par_shared.parent_entry = 0; par_shared.parent_free_space = 0; - if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, &nrows, &par_shared, H5AC_WRITE))) + if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &nrows, &par_shared, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") /* Lock first (root) direct block */ @@ -1483,8 +1557,8 @@ HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p); HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block") /* Point indirect block at direct block to add */ - iblock->dblock_ents[0].addr = shared->man_dtable.table_addr; - iblock->dblock_ents[0].free_space = dblock->blk_free_space; + iblock->ents[0].addr = shared->man_dtable.table_addr; + iblock->ents[0].free_space = dblock->blk_free_space; iblock->child_free_space += dblock->blk_free_space; /* Make direct block share parent indirect block */ @@ -1499,23 +1573,18 @@ HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p); /* Increment size of next block from this indirect block */ /* (account for the already existing direct block */ - H5HF_man_iblock_inc_loc(iblock); + if(H5HF_man_iblock_inc_loc(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") /* Mark indirect block as modified */ iblock->dirty = TRUE; /* Point heap header at new indirect block */ shared->man_dtable.curr_root_rows = nrows; - shared->man_dtable.table_addr = *addr_p; + shared->man_dtable.table_addr = iblock_addr; /* Mark heap header as modified */ shared->dirty = TRUE; - - /* Set entry for direct block */ - *entry_p = 1; - - /* Set size of direct block to create */ - *dblock_size = iblock->next_dir_size; } /* end if */ else { #ifdef QAK @@ -1527,62 +1596,44 @@ HDfprintf(stderr, "%s: searching root indirect block\n", FUNC); par_shared.parent = NULL; par_shared.parent_entry = 0; par_shared.parent_free_space = shared->total_man_free; - if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE))) + iblock_addr = shared->man_dtable.table_addr; + if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") #ifdef QAK -HDfprintf(stderr, "%s: iblock->next_dir_row = %u\n", FUNC, iblock->next_dir_row); -HDfprintf(stderr, "%s: iblock->next_dir_col = %u\n", FUNC, iblock->next_dir_col); -HDfprintf(stderr, "%s: iblock->next_dir_size = %Zu\n", FUNC, iblock->next_dir_size); -HDfprintf(stderr, "%s: iblock->dir_full = %u\n", FUNC, (unsigned)iblock->dir_full); +HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); #endif /* QAK */ - /* Check for full direct block entries in root */ - if(iblock->dir_full) { -HDfprintf(stderr, "%s: Adding nested indirect block to heap not supported\n", FUNC); -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "Adding nested indirect block not supported yet") - } /* end if */ - - /* Check for skipping over blocks */ - if(min_dblock_size > iblock->next_dir_size) { -HDfprintf(stderr, "%s: Skipping direct block sizes not supported\n", FUNC); -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "skipping direct block sizes not supported yet") - } /* end if */ - - /* Check if we need a direct block past current allocation */ - if(iblock->next_dir_row == iblock->ndir_rows) { - haddr_t old_addr; /* Old address of indirect block */ + /* Check if we need a block past current allocation */ + if(iblock->next_row == iblock->nrows) { haddr_t new_addr; /* New address of indirect block */ unsigned new_nrows; /* New # of direct rows */ size_t u; /* Local index variable */ /* Check for special case of second row, which has blocks the same size as first row */ - if(iblock->next_dir_row == 1) - iblock->next_dir_size = shared->man_dtable.cparam.start_block_size; + if(iblock->next_row == 1) + iblock->next_size = shared->man_dtable.cparam.start_block_size; /* Compute new # of rows in indirect block */ - new_nrows = 2 * iblock->ndir_rows; - if(new_nrows > iblock->max_direct_rows) - new_nrows = iblock->max_direct_rows; + new_nrows = MIN(2 * iblock->nrows, iblock->max_rows); #ifdef QAK HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows); #endif /* QAK */ /* Currently, the old chunk data is "thrown away" after the space is reallocated, - * so avoid data copy in H5MF_realloc() call by just free'ing the space and - * allocating new space. - * - * This should keep the file smaller also, by freeing the space and then - * allocating new space, instead of vice versa (in H5MF_realloc). - * - * QAK - 3/14/2006 - */ +* so avoid data copy in H5MF_realloc() call by just free'ing the space and +* allocating new space. +* +* This should keep the file smaller also, by freeing the space and then +* allocating new space, instead of vice versa (in H5MF_realloc). +* +* QAK - 3/14/2006 +*/ /* Free previous indirect block disk space */ - old_addr = shared->man_dtable.table_addr; - if(H5MF_xfree(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, old_addr, (hsize_t)iblock->size)<0) + if(H5MF_xfree(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock_addr, (hsize_t)iblock->size)<0) HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, NULL, "unable to free fractal heap indirect block") /* Compute size of buffer needed for new indirect block */ - iblock->ndir_rows = new_nrows; + iblock->nrows = new_nrows; iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock); /* Allocate space for the new indirect block on disk */ @@ -1590,31 +1641,31 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows); HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, NULL, "file allocation failed for fractal heap indirect block") /* Re-allocate direct block entry table */ - if(NULL == (iblock->dblock_ents = H5FL_SEQ_REALLOC(H5HF_indirect_dblock_ent_t, iblock->dblock_ents, (iblock->ndir_rows * shared->man_dtable.cparam.width)))) + if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * shared->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries") /* Initialize new direct block entries */ - for(u = (iblock->next_dir_row * shared->man_dtable.cparam.width); - u < (iblock->ndir_rows * shared->man_dtable.cparam.width); + for(u = (iblock->next_row * shared->man_dtable.cparam.width); + u < (iblock->nrows * shared->man_dtable.cparam.width); u++) { - iblock->dblock_ents[u].addr = HADDR_UNDEF; - iblock->dblock_ents[u].free_space = 0; + iblock->ents[u].addr = HADDR_UNDEF; + iblock->ents[u].free_space = 0; } /* end for */ /* Mark indirect block as dirty */ iblock->dirty = TRUE; /* Release the indirect block (marked as dirty) */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, old_addr, iblock, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block") /* Move object in cache */ - if(H5AC_rename(shared->f, H5AC_FHEAP_IBLOCK, old_addr, new_addr) < 0) + if(H5AC_rename(shared->f, H5AC_FHEAP_IBLOCK, iblock_addr, new_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, NULL, "unable to move fractal heap root indirect block") /* Update other shared header info */ shared->man_dtable.curr_root_rows = new_nrows; - shared->man_dtable.table_addr = new_addr; + shared->man_dtable.table_addr = iblock_addr = new_addr; /* Mark heap header as modified */ shared->dirty = TRUE; @@ -1624,20 +1675,113 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows); par_shared.parent = NULL; par_shared.parent_entry = 0; par_shared.parent_free_space = shared->total_man_free; - if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE))) + if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") } /* end if */ - /* Set address of indirect block */ - *addr_p = shared->man_dtable.table_addr; +#ifdef QAK +HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row); +HDfprintf(stderr, "%s: iblock->next_col = %u\n", FUNC, iblock->next_col); +HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size); +HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry); +#endif /* QAK */ + /* Check for full direct block entries in current indirect block */ + while(iblock->next_row >= shared->man_dtable.max_direct_rows) { + haddr_t new_iblock_addr; /* New indirect block's address */ + H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */ + unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for header */ + unsigned nrows; /* Number of rows in new indirect block */ + + /* Compute # of rows in child indirect block */ + nrows = (H5V_log2_gen(iblock->next_size) - shared->man_dtable.first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->next_size, nrows); +#endif /* QAK */ + + /* Check for allocating new indirect block */ + if(!H5F_addr_defined(iblock->ents[iblock->next_entry].addr)) { +#ifdef QAK +HDfprintf(stderr, "%s: Allocating new indirect block\n", FUNC); +#endif /* QAK */ + /* Allocate new indirect block */ + if(H5HF_man_iblock_create(fh_shared, dxpl_id, shared->man_dtable.next_dir_block, nrows, nrows, &new_iblock_addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block") + + /* Lock new indirect block */ + par_shared.shared = fh_shared; + par_shared.parent = iblock->self; + par_shared.parent_entry = iblock->next_entry; + par_shared.parent_free_space = 0; + if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") +#ifdef QAK +HDfprintf(stderr, "%s: new_iblock->next_row = %u\n", FUNC, new_iblock->next_row); +HDfprintf(stderr, "%s: new_iblock->next_col = %u\n", FUNC, new_iblock->next_col); +HDfprintf(stderr, "%s: new_iblock->next_size = %Zu\n", FUNC, new_iblock->next_size); +HDfprintf(stderr, "%s: new_iblock->next_entry = %u\n", FUNC, new_iblock->next_entry); +#endif /* QAK */ + + /* Point current indirect block at new indirect block */ + iblock->ents[iblock->next_entry].addr = new_iblock_addr; - /* Set entry for direct block */ - *entry_p = iblock->next_dir_entry; + /* Increment location of next block from current indirect block */ + if(H5HF_man_iblock_inc_loc(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") - /* Set size of direct block to create */ - *dblock_size = iblock->next_dir_size; + /* Mark current indirect block as modified */ + iblock->dirty = TRUE; + + /* Release the current indirect block (marked as dirty) */ + hdr_flags |= H5AC__DIRTIED_FLAG; + } /* end if */ + else { +#ifdef QAK +HDfprintf(stderr, "%s: Descending existing indirect block\n", FUNC); +#endif /* QAK */ + /* Locate child indirect block */ + new_iblock_addr = iblock->ents[iblock->next_entry].addr; + + /* Lock new indirect block */ + par_shared.shared = fh_shared; + par_shared.parent = iblock->self; + par_shared.parent_entry = iblock->next_entry; + par_shared.parent_free_space = iblock->ents[iblock->next_entry].free_space; + if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") + } /* end else */ + + /* Release the current indirect block (possibly marked as dirty) */ + if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, hdr_flags) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block") + + /* Switch variables to use new indirect block */ + iblock = new_iblock; + iblock_addr = new_iblock_addr; +#ifdef QAK +HDfprintf(stderr, "%s: new_iblock_addr = %a\n", FUNC, new_iblock_addr); +#endif /* QAK */ + } /* end while */ } /* end else */ + /* Check for skipping over blocks */ + if(min_dblock_size > iblock->next_size) { +HDfprintf(stderr, "%s: Skipping direct block sizes not supported\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "skipping direct block sizes not supported yet") + } /* end if */ + + /* Set address of indirect block that's the immediate parent of new direct block */ + *addr_p = iblock_addr; + + /* Set entry for new direct block to use */ + *entry_p = iblock->next_entry; + + /* Set size of direct block to create */ + *dblock_size = iblock->next_size; + + /* Increment location of next block from this indirect block */ + if(H5HF_man_iblock_inc_loc(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") + /* Set return value */ ret_value = iblock; @@ -1661,7 +1805,7 @@ done: */ static herr_t H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id, - hsize_t block_off, unsigned nrows, unsigned max_dir_rows, haddr_t *addr_p) + hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p) { H5HF_shared_t *shared; /* Pointer to shared heap info */ H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */ @@ -1699,7 +1843,7 @@ H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for indirect fractal heap block") #ifdef QAK -HDfprintf(stderr, "%s: nrows = %u\n", FUNC, nrows); +HDfprintf(stderr, "%s: nrows = %u, max_nrows = %u\n", FUNC, nrows, max_nrows); #endif /* QAK */ /* Set info for direct block */ iblock->parent = NULL; /* Temporary, except for root indirect block */ @@ -1707,41 +1851,24 @@ HDfprintf(stderr, "%s: nrows = %u\n", FUNC, nrows); iblock->block_off = block_off; iblock->child_free_space = 0; iblock->nrows = nrows; - iblock->dir_full = FALSE; - iblock->next_dir_col = 0; - iblock->next_dir_row = 0; - iblock->next_dir_entry = 0; - iblock->next_dir_size = shared->man_dtable.cparam.start_block_size; - iblock->max_direct_rows = max_dir_rows; - if(iblock->nrows > shared->man_dtable.max_direct_rows) { - iblock->ndir_rows = shared->man_dtable.max_direct_rows; - iblock->nindir_rows = iblock->nrows - iblock->ndir_rows; - } /* end if */ - else { - iblock->ndir_rows = iblock->nrows; - iblock->nindir_rows = 0; - } /* end else */ + iblock->max_rows = max_rows; + iblock->next_col = 0; + iblock->next_row = 0; + iblock->next_entry = 0; + iblock->next_size = shared->man_dtable.cparam.start_block_size; /* Compute size of buffer needed for indirect block */ iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock); /* Allocate indirect block entry tables */ - if(NULL == (iblock->dblock_ents = H5FL_SEQ_MALLOC(H5HF_indirect_dblock_ent_t, (iblock->ndir_rows * shared->man_dtable.cparam.width)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct entries") - if(iblock->nindir_rows > 0) { - if(NULL == (iblock->iblock_ents = H5FL_SEQ_MALLOC(H5HF_indirect_iblock_ent_t, (iblock->nindir_rows * shared->man_dtable.cparam.width)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for indirect entries") - } /* end if */ - else - iblock->iblock_ents = NULL; + if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * shared->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries") /* Initialize indirect block entry tables */ - for(u = 0; u < (iblock->ndir_rows * shared->man_dtable.cparam.width); u++) { - iblock->dblock_ents[u].addr = HADDR_UNDEF; - iblock->dblock_ents[u].free_space = 0; + for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) { + iblock->ents[u].addr = HADDR_UNDEF; + iblock->ents[u].free_space = 0; } /* end for */ - for(u = 0; u < (iblock->nindir_rows * shared->man_dtable.cparam.width); u++) - iblock->iblock_ents[u].addr = HADDR_UNDEF; /* Allocate space for the indirect block on disk */ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) @@ -1751,7 +1878,6 @@ HDfprintf(stderr, "%s: nrows = %u\n", FUNC, nrows); #ifdef LATER /* Update shared heap info */ shared->total_man_free += dblock->blk_free_space; - shared->man_dtable.next_dir_block += dblock->size; shared->total_size += dblock->size; shared->man_size += dblock->size; |