diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-04-30 13:32:41 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-04-30 13:32:41 (GMT) |
commit | 4965bf1839b4219c3063e27d37bc59a777cc1fb5 (patch) | |
tree | 925c87307aa9c13c66c301b0d3ca9283e9b20d32 /src/H5HFint.c | |
parent | eb96132022da938d4b54ae4dd482919a178c4ee5 (diff) | |
download | hdf5-4965bf1839b4219c3063e27d37bc59a777cc1fb5.zip hdf5-4965bf1839b4219c3063e27d37bc59a777cc1fb5.tar.gz hdf5-4965bf1839b4219c3063e27d37bc59a777cc1fb5.tar.bz2 |
[svn-r12317] Purpose:
Code checkpoint
Description:
More progress on fractal heap, can now re-open an existing heap, although
the free space algorithm still needs work.
Also, use the new "pinned entry" metadata cache code.
Platforms tested:
FreeBSD 4.11 (sleipnir)
Linux 2.4 (heping)
Solaris 9 (shanti)
Linux 2.4/64 (mir)
Diffstat (limited to 'src/H5HFint.c')
-rw-r--r-- | src/H5HFint.c | 227 |
1 files changed, 197 insertions, 30 deletions
diff --git a/src/H5HFint.c b/src/H5HFint.c index 64de9c4..e8b380d 100644 --- a/src/H5HFint.c +++ b/src/H5HFint.c @@ -57,6 +57,7 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5HF_man_start_freelist(H5HF_hdr_t *hdr, hid_t dxpl_id); /*********************/ @@ -93,20 +94,135 @@ H5FL_DEFINE(H5HF_free_section_t); *------------------------------------------------------------------------- */ herr_t -H5HF_free_section_free_cb(void *item, void UNUSED *key, void UNUSED *op_data) +H5HF_free_section_free_cb(void *_sect, void UNUSED *key, void UNUSED *op_data) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_free_section_free_cb) + H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; + H5HF_indirect_t *iblock = NULL; /* Indirect block referenced */ + herr_t ret_value = 0; /* Return value */ - HDassert(item); + FUNC_ENTER_NOAPI_NOINIT(H5HF_free_section_free_cb) + + HDassert(sect); + + /* Find indirect block that free section references */ + switch(sect->type) { + case H5HF_SECT_SINGLE: + iblock = sect->u.single.parent; + break; + + case H5HF_SECT_OPAQUE: + iblock = sect->u.opaque.iblock; + break; + + case H5HF_SECT_RANGE: + iblock = sect->u.range.iblock; + break; + + case H5HF_SECT_INDIRECT: + iblock = sect->u.indirect.iblock; + break; + } /* end switch */ + + /* Release indirect block, if there was one */ + if(iblock) + if(H5HF_iblock_decr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") /* Release the sections */ - H5FL_FREE(H5HF_free_section_t, item); + H5FL_FREE(H5HF_free_section_t, sect); - FUNC_LEAVE_NOAPI(0) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5HF_free_section_free_cb() */ /*------------------------------------------------------------------------- + * Function: H5HF_man_start_freelist + * + * Purpose: Start free list for existing heap, by bringing in root direct + * or indirect block and it's free space sections. + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_man_start_freelist(H5HF_hdr_t *hdr, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_start_freelist) + + /* + * Check arguments. + */ + HDassert(hdr); + + /* Check for empty heap */ + if(!H5F_addr_defined(hdr->man_dtable.table_addr)) { +#ifdef QAK +HDfprintf(stderr, "%s: Empty heap to [not] start\n", FUNC); +#endif /* QAK */ + /* Nothing to do */ + ; + } /* end if */ + /* Check for root direct block */ + else if(hdr->man_dtable.curr_root_rows == 0) { + H5HF_direct_t *dblock; /* Pointer to direct block to query */ + haddr_t dblock_addr; /* Direct block address */ + size_t dblock_size; /* Direct block size */ + +#ifdef QAK +HDfprintf(stderr, "%s: Root direct block to start\n", FUNC); +#endif /* QAK */ + /* Bring root direct block into memory */ + /* (which will parse it's free list) */ + /* (Could create an "opaque" section for it, but it doesn't seem worthwhile) */ + dblock_addr = hdr->man_dtable.table_addr; + dblock_size = hdr->man_dtable.cparam.start_block_size; + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, NULL, 0, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") + + /* Unlock direct block */ + if(H5AC_unprotect(hdr->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; + } /* end if */ + /* Must be a root indirect block */ + else { + H5HF_indirect_t *iblock; /* Pointer to root indirect block to query */ + haddr_t iblock_addr; /* Indirect block's address */ + +#ifdef QAK +HDfprintf(stderr, "%s: Root indirect block to start\n", FUNC); +#endif /* QAK */ + /* Get indirect block info */ + iblock_addr = hdr->man_dtable.table_addr; + + /* Lock root indirect block */ + /* (which will parse it's free space) */ + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, hdr->man_dtable.curr_root_rows, NULL, 0, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + + /* Release the root indirect block */ + if(H5AC_unprotect(hdr->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 */ + + /* Mark heap as being in sync now */ + hdr->freelist_sync = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_start_freelist() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_man_find * * Purpose: Find space for an object in a managed obj. heap @@ -121,10 +237,11 @@ H5HF_free_section_free_cb(void *item, void UNUSED *key, void UNUSED *op_data) *------------------------------------------------------------------------- */ herr_t -H5HF_man_find(H5HF_t *hdr, hid_t dxpl_id, size_t request, +H5HF_man_find(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t request, H5HF_free_section_t **sec_node/*out*/) { htri_t node_found; /* Whether an existing free list node was found */ + hbool_t search_again; /* Whether to search again for another free section */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_find) @@ -139,14 +256,51 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); HDassert(request > 0); HDassert(sec_node); - /* Look for free space in global free list */ - if((node_found = H5HF_flist_find(hdr->flist, request, (void **)sec_node)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block") + /* Search for free space in the globel free list, until a non-opaque node is found */ + do { + /* Done searching, unless opaque node found */ + search_again = FALSE; + + /* Look for free space in global free list */ + if((node_found = H5HF_flist_find(hdr->flist, request, (void **)sec_node)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block") + + /* Check for opaque section */ + if(node_found) { + if((*sec_node)->type == H5HF_SECT_OPAQUE) { + /* Break opaque section down into component sections */ + if(H5HF_man_iblock_alloc_opaque(hdr, dxpl_id, sec_node) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't break up opaque free section") + + /* Search again */ + search_again = TRUE; + } /* end if */ + } /* end if */ + /* If we didn't find a node, check if we've looked in all the direct blocks in the heap for space */ + else { +#ifdef QAK +HDfprintf(stderr, "%s: hdr->freelist_sync = %u\n", FUNC, (unsigned)hdr->freelist_sync); +#endif /* QAK */ + if(!hdr->freelist_sync) { +#ifdef QAK +HDfprintf(stderr, "%s: Start free list for existing blocks in heap\n", FUNC); +#endif /* QAK */ + /* Start freelist for existing heap */ + if(H5HF_man_start_freelist(hdr, dxpl_id) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't start fractal heap free list") + + /* Search again */ + search_again = TRUE; + } /* end if */ + } /* end else */ + } while(search_again); -/* XXX: Make certain we've loaded all the direct blocks in the heap */ /* If we didn't find a node, go make one big enough to hold the requested block */ if(!node_found) { +#ifdef QAK +HDfprintf(stderr, "%s: Allocate new direct block\n", FUNC); +#endif /* QAK */ /* Allocate direct block big enough to hold requested size */ if(H5HF_man_dblock_new(hdr, dxpl_id, request) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create fractal heap direct block") @@ -158,10 +312,9 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); } /* end if */ HDassert(*sec_node); #ifdef QAK -HDfprintf(stderr, "%s: (*sec_node)->block_addr = %a\n", FUNC, (*sec_node)->block_addr); -HDfprintf(stderr, "%s: (*sec_node)->block_size = %Zu\n", FUNC, (*sec_node)->block_size); HDfprintf(stderr, "%s: (*sec_node)->sect_addr = %a\n", FUNC, (*sec_node)->sect_addr); HDfprintf(stderr, "%s: (*sec_node)->sect_size = %Zu\n", FUNC, (*sec_node)->sect_size); +HDfprintf(stderr, "%s: (*sec_node)->type = %u\n", FUNC, (unsigned)(*sec_node)->type); #endif /* QAK */ done: @@ -183,7 +336,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_insert(H5HF_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node, +H5HF_man_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node, size_t obj_size, const void *obj, void *id) { H5HF_direct_t *dblock = NULL; /* Pointer to direct block to modify */ @@ -205,8 +358,9 @@ H5HF_man_insert(H5HF_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node, #ifdef QAK HDfprintf(stderr, "%s: sec_node->sect_addr = %a\n", FUNC, sec_node->sect_addr); HDfprintf(stderr, "%s: sec_node->sect_size = %Zu\n", FUNC, sec_node->sect_size); -HDfprintf(stderr, "%s: sec_node->u.indirect.iblock_addr = %a\n", FUNC, sec_node->u.indirect.iblock_addr); -HDfprintf(stderr, "%s: sec_node->u.indirect.iblock_nrows = %u\n", FUNC, sec_node->u.indirect.iblock_nrows); +HDfprintf(stderr, "%s: sec_node->u.indirect.iblock = %p\n", FUNC, sec_node->u.indirect.iblock); +if(sec_node->u.indirect.iblock) + HDfprintf(stderr, "%s: sec_node->u.indirect.iblock->addr = %a\n", FUNC, sec_node->u.indirect.iblock->addr); HDfprintf(stderr, "%s: sec_node->u.indirect.row = %u\n", FUNC, sec_node->u.indirect.row); HDfprintf(stderr, "%s: sec_node->u.indirect.col = %u\n", FUNC, sec_node->u.indirect.col); HDfprintf(stderr, "%s: sec_node->u.indirect.num_entries = %u\n", FUNC, sec_node->u.indirect.num_entries); @@ -215,7 +369,7 @@ HDfprintf(stderr, "%s: sec_node->u.indirect.indir_nrows = %u\n", FUNC, sec_node- #endif /* QAK */ /* Allocate 'single' selection out of 'indirect' selection */ - if(H5HF_man_iblock_alloc_indirect(hdr, dxpl_id, &sec_node, obj_size) < 0) + if(H5HF_man_iblock_alloc_indirect(hdr, dxpl_id, &sec_node) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't break up indirect free section") } /* end if */ /* Check for range section */ @@ -223,14 +377,15 @@ HDfprintf(stderr, "%s: sec_node->u.indirect.indir_nrows = %u\n", FUNC, sec_node- #ifdef QAK HDfprintf(stderr, "%s: sec_node->sect_addr = %a\n", FUNC, sec_node->sect_addr); HDfprintf(stderr, "%s: sec_node->sect_size = %Zu\n", FUNC, sec_node->sect_size); -HDfprintf(stderr, "%s: sec_node->u.range.iblock_addr = %a\n", FUNC, sec_node->u.range.iblock_addr); -HDfprintf(stderr, "%s: sec_node->u.range.iblock_nrows = %u\n", FUNC, sec_node->u.range.iblock_nrows); +HDfprintf(stderr, "%s: sec_node->u.range.iblock = %p\n", FUNC, sec_node->u.range.iblock); +if(sec_node->u.range.iblock) + HDfprintf(stderr, "%s: sec_node->u.range.iblock->addr = %a\n", FUNC, sec_node->u.range.iblock->addr); HDfprintf(stderr, "%s: sec_node->u.range.row = %u\n", FUNC, sec_node->u.range.row); HDfprintf(stderr, "%s: sec_node->u.range.col = %u\n", FUNC, sec_node->u.range.col); HDfprintf(stderr, "%s: sec_node->u.range.num_entries = %u\n", FUNC, sec_node->u.range.num_entries); #endif /* QAK */ /* Allocate 'single' selection out of 'range' selection */ - if(H5HF_man_iblock_alloc_range(hdr, dxpl_id, &sec_node, obj_size) < 0) + if(H5HF_man_iblock_alloc_range(hdr, dxpl_id, &sec_node) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't break up range free section") } /* end if */ @@ -238,11 +393,15 @@ HDfprintf(stderr, "%s: sec_node->u.range.num_entries = %u\n", FUNC, sec_node->u. #ifdef QAK HDfprintf(stderr, "%s: sec_node->sect_addr = %a\n", FUNC, sec_node->sect_addr); HDfprintf(stderr, "%s: sec_node->sect_size = %Zu\n", FUNC, sec_node->sect_size); +HDfprintf(stderr, "%s: sec_node->u.single.parent = %p\n", FUNC, sec_node->u.single.parent); +if(sec_node->u.single.parent) + HDfprintf(stderr, "%s: sec_node->u.single.parent->addr = %a\n", FUNC, sec_node->u.single.parent->addr); +HDfprintf(stderr, "%s: sec_node->u.single.par_entry = %u\n", FUNC, sec_node->u.single.par_entry); HDfprintf(stderr, "%s: sec_node->u.single.dblock_addr = %a\n", FUNC, sec_node->u.single.dblock_addr); HDfprintf(stderr, "%s: sec_node->u.single.dblock_size = %Zu\n", FUNC, sec_node->u.single.dblock_size); #endif /* QAK */ dblock_addr = sec_node->u.single.dblock_addr; - if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &sec_node->u.single.dblock_size, hdr, H5AC_WRITE))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, sec_node->u.single.dblock_size, sec_node->u.single.parent, sec_node->u.single.par_entry, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block") /* Insert object into block */ @@ -314,6 +473,14 @@ HDfprintf(stderr, "%s: node->size = %Zu\n", FUNC, node->size); free_frag_size = (unsigned char )(node->size - full_obj_size); whole_node = TRUE; + /* Drop reference count on parent indirect block of direct block that free section is in */ + HDassert(dblock->parent == NULL || + sec_node->u.single.parent == NULL || + dblock->parent == sec_node->u.single.parent); + if(sec_node->u.single.parent) + if(H5HF_iblock_decr(sec_node->u.single.parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + /* Release the memory for the free list node & section */ H5FL_FREE(H5HF_direct_free_node_t, node); H5FL_FREE(H5HF_free_section_t, sec_node); @@ -350,7 +517,7 @@ HDfprintf(stderr, "%s: full_obj_size = %Zu\n", FUNC, full_obj_size); HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size); #endif /* QAK */ /* Reduce space available in parent block(s) */ - if(H5HF_man_dblock_adj_free(dxpl_id, dblock, -(ssize_t)free_obj_size) < 0) + if(H5HF_man_dblock_adj_free(dblock, -(ssize_t)free_obj_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for direct block & parents") /* Encode the object in the block */ @@ -391,7 +558,7 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "inserting within mapped managed bl hdr->nobjs++; /* Mark heap header as modified */ - if(H5HF_hdr_dirty(dxpl_id, hdr) < 0) + if(H5HF_hdr_dirty(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") done: @@ -417,7 +584,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_read(H5HF_t *hdr, hid_t dxpl_id, hsize_t obj_off, size_t obj_len, void *obj) +H5HF_man_read(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t obj_off, size_t obj_len, void *obj) { H5HF_direct_t *dblock; /* Pointer to direct block to query */ size_t blk_off; /* Offset of object in block */ @@ -441,11 +608,11 @@ HDfprintf(stderr, "%s: obj_off = %Hu, obj_len = %Zu\n", FUNC, obj_off, obj_len); /* Check for root direct block */ if(hdr->man_dtable.curr_root_rows == 0) { /* Set direct block info */ - dblock_addr = hdr->man_dtable.table_addr; - dblock_size = hdr->man_dtable.cparam.start_block_size; + dblock_addr = hdr->man_dtable.table_addr; + dblock_size = hdr->man_dtable.cparam.start_block_size; /* Lock direct block */ - if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, NULL, 0, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") } /* end if */ else { @@ -467,8 +634,8 @@ HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col); HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); #endif /* QAK */ - /* Lock indirect block */ - if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_READ))) + /* Lock root indirect block */ + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, hdr->man_dtable.curr_root_rows, NULL, 0, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") /* Check for indirect block row */ @@ -490,7 +657,7 @@ HDfprintf(stderr, "%s: entry = %Zu\n", FUNC, entry); new_iblock_addr = iblock->ents[entry].addr; /* Lock new indirect block */ - if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_READ))) + if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_iblock_addr, nrows, iblock, entry, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") /* Release the current indirect block */ @@ -525,7 +692,7 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr); dblock_size = hdr->man_dtable.row_block_size[row]; /* Lock direct block */ - if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, iblock, entry, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") /* Unlock indirect block */ |