summaryrefslogtreecommitdiffstats
path: root/src/H5HFdblock.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-06-19 10:06:10 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-06-19 10:06:10 (GMT)
commit9db9e82cd1c4e35c6e64fbb2da5eb1db95a0fb55 (patch)
treedf8aaa72b1094bcfacc740a8d33b255c84e1d34e /src/H5HFdblock.c
parent54e2de04d3b7a0359c80cc995f94b63123f4a4da (diff)
downloadhdf5-9db9e82cd1c4e35c6e64fbb2da5eb1db95a0fb55.zip
hdf5-9db9e82cd1c4e35c6e64fbb2da5eb1db95a0fb55.tar.gz
hdf5-9db9e82cd1c4e35c6e64fbb2da5eb1db95a0fb55.tar.bz2
[svn-r12424] Purpose:
Code checkpoint Description: Add in more new features for the fractal heap code, mostly bringing in more ability for deleting objects (which isn't completely working yet). Also, checkpoint free space manager code, which is essentially complete (although it needs some more work after the metadata cache has some additional features) Platforms tested: FreeBSD 4.11 (sleipnir) Linux 2.4 (chicago) h5committest
Diffstat (limited to 'src/H5HFdblock.c')
-rw-r--r--src/H5HFdblock.c184
1 files changed, 111 insertions, 73 deletions
diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c
index 88c4e90..a4f1815 100644
--- a/src/H5HFdblock.c
+++ b/src/H5HFdblock.c
@@ -92,8 +92,7 @@ H5FL_DEFINE(H5HF_direct_t);
*/
herr_t
H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblock,
- unsigned par_entry, size_t block_size, hsize_t block_off, haddr_t *addr_p,
- H5HF_free_section_t **ret_sec_node)
+ unsigned par_entry, haddr_t *addr_p, H5HF_free_section_t **ret_sec_node)
{
H5HF_free_section_t *sec_node; /* Pointer to free space section for block */
H5HF_direct_t *dblock = NULL; /* Pointer to direct block */
@@ -106,7 +105,6 @@ H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblo
* Check arguments.
*/
HDassert(hdr);
- HDassert(block_size > 0);
HDassert(addr_p);
/*
@@ -124,49 +122,49 @@ H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblo
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header")
/* Set info for direct block */
-#ifdef QAK
-HDfprintf(stderr, "%s: size = %Zu, block_off = %Hu\n", FUNC, block_size, block_off);
-#endif /* QAK */
- dblock->parent = par_iblock;
- if(dblock->parent) {
- if(H5HF_iblock_incr(par_iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block")
+ if(par_iblock) {
+ unsigned par_row = par_entry / hdr->man_dtable.cparam.width; /* Row for block */
+
+ /* Compute offset & size, based on parent's information */
+ dblock->block_off = par_iblock->block_off;
+ dblock->block_off += hdr->man_dtable.row_block_off[par_row];
+ dblock->block_off += hdr->man_dtable.row_block_size[par_row] * (par_entry % hdr->man_dtable.cparam.width);
+ dblock->size = hdr->man_dtable.row_block_size[par_row];
} /* end if */
- dblock->par_entry = par_entry;
- dblock->size = block_size;
- dblock->block_off = block_off;
- dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(block_size);
- free_space = block_size - H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
+ else {
+ /* Must be the root direct block */
+ dblock->block_off = 0;
+ dblock->size = hdr->man_dtable.cparam.start_block_size;
+ } /* end else */
+ dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size);
+ free_space = dblock->size - H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
/* Allocate buffer for block */
/* XXX: Change to using free-list factories */
- if((dblock->blk = H5FL_BLK_MALLOC(direct_block, block_size)) == NULL)
+ if((dblock->blk = H5FL_BLK_MALLOC(direct_block, dblock->size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
#ifdef H5_USING_PURIFY
HDmemset(dblock->blk, 0, dblock->size);
#endif /* H5_USING_PURIFY */
/* Allocate space for the header on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)block_size)))
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+#ifdef QAK
+HDfprintf(stderr, "%s: direct block address = %a\n", FUNC, *addr_p);
+#endif /* QAK */
- /* Create free space section node */
- if(NULL == (sec_node = H5FL_MALLOC(H5HF_free_section_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section")
-
- /* Set section's information */
- sec_node->sect_info.addr = block_off + H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
- sec_node->sect_info.size = free_space;
- sec_node->sect_info.cls = &hdr->sect_cls[H5FS_SECT_FHEAP_SINGLE];
- sec_node->sect_info.state = H5FS_SECT_LIVE;
- sec_node->u.single.parent = dblock->parent;
- if(dblock->parent) {
- if(H5HF_iblock_incr(dblock->parent) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block")
- } /* end if */
- sec_node->u.single.par_entry = dblock->par_entry;
- sec_node->u.single.dblock_addr = *addr_p;
- sec_node->u.single.dblock_size = block_size;
+ /* Attach to parent indirect block, if there is one */
+ dblock->parent = par_iblock;
+ if(dblock->parent)
+ if(H5HF_man_iblock_attach(dblock->parent, par_entry, *addr_p) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't attach direct block to parent indirect block")
+ dblock->par_entry = par_entry;
+
+ /* Create a new 'single' section for the free space in the block */
+ if(NULL == (sec_node = H5HF_sect_single_new((dblock->block_off + H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)),
+ free_space, dblock->parent, dblock->par_entry, *addr_p, dblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create section for new direct block's free space")
/* Check what to do with section node */
if(ret_sec_node)
@@ -182,6 +180,10 @@ HDmemset(dblock->blk, 0, dblock->size);
if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, *addr_p, dblock, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap direct block to cache")
+ /* Increase the allocated heap size */
+ if(H5HF_hdr_inc_alloc(hdr, dblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size")
+
done:
if(ret_value < 0)
if(dblock)
@@ -196,6 +198,10 @@ done:
*
* Purpose: Destroy a managed direct block
*
+ * Note: This routine does _not_ insert a range section for the
+ * destroyed direct block, that must be handled by the
+ * caller.
+ *
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
@@ -230,6 +236,10 @@ HDfprintf(stderr, "%s: root direct block\n", FUNC);
/* Sanity check block iterator */
HDassert(!H5HF_man_iter_ready(&hdr->next_block));
+ /* Reset root pointer information */
+ hdr->man_dtable.curr_root_rows = 0;
+ hdr->man_dtable.table_addr = HADDR_UNDEF;
+
/* Reset header information back to "empty heap" state */
if(H5HF_hdr_empty(hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't make heap empty")
@@ -239,21 +249,51 @@ HDfprintf(stderr, "%s: root direct block\n", FUNC);
HDfprintf(stderr, "%s: root indirect block\n", FUNC);
#endif /* QAK */
-/* Remove from parent indirect block */
+ /* Detach from parent indirect block */
+ if(H5HF_man_iblock_detach(dblock->parent, dxpl_id, dblock->par_entry) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't detach from parent indirect block")
+ dblock->parent = NULL;
+ dblock->par_entry = 0;
-/* If this is the last block in the heap, move block iterator backwards */
+ /* Adjust heap statistics */
+ hdr->man_alloc_size -= dblock->size;
-/* Detect the last direct block (of the starting block size) and make it the root direct block */
-
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "destroying non-root direct block not supported yet")
+#ifdef QAK
+HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
+HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
+#endif /* QAK */
+ /* Check for this direct block being the highest in the heap */
+ if((dblock->block_off + dblock->size) == hdr->man_iter_off) {
+ /* Move 'next block' iterator backwards (may shrink heap) */
+ if(H5HF_hdr_reverse_iter(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reverse 'next block' iterator")
+ } /* end if */
+#if 0
+ else {
+ unsigned par_row, par_col; /* Row & column in parent indirect block */
+
+ /* Compute row & column in parent indirect block */
+ par_row = dblock->par_entry / hdr->man_dtable.cparam.width;
+ par_col = dblock->par_entry % hdr->man_dtable.cparam.width;
+
+ /* Add a 'range' section for the space in the destroyed block */
+ if(H5HF_sect_range_add(hdr, dxpl_id, dblock->block_off, hdr->man_dtable.row_dblock_free[par_row],
+ dblock->parent, par_row, par_col, 1) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't create range section for direct block being destroyed")
+ } /* end else */
+#endif /* 0 */
} /* end else */
/* Release direct block's disk space */
+#ifdef QAK
+HDfprintf(stderr, "%s: Before releasing direct block's space, dblock_addr = %a\n", FUNC, dblock_addr);
+#endif /* QAK */
if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, (hsize_t)dblock->size)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
/* Remove direct block from metadata cache */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DELETED_FLAG) < 0)
+ /* (direct block "destroy" callback will be called by cache) */
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
dblock = NULL;
@@ -277,11 +317,10 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_man_dblock_new(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t request)
+H5HF_man_dblock_new(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t request,
+ H5HF_free_section_t **ret_sec_node)
{
haddr_t dblock_addr; /* Address of new direct block */
- hsize_t dblock_off; /* Direct block offset in heap address space */
- size_t dblock_size; /* Size of new direct block */
size_t min_dblock_size; /* Min. size of direct block to allocate */
herr_t ret_value = SUCCEED; /* Return value */
@@ -319,13 +358,11 @@ HDfprintf(stderr, "%s: Check 2 - min_dblock_size = %Zu\n", FUNC, min_dblock_size
if(!H5F_addr_defined(hdr->man_dtable.table_addr) &&
min_dblock_size == hdr->man_dtable.cparam.start_block_size) {
/* Create new direct block at starting offset */
- dblock_size = hdr->man_dtable.cparam.start_block_size;
- dblock_off = 0;
- if(H5HF_man_dblock_create(dxpl_id, hdr, NULL, 0, dblock_size, dblock_off, &dblock_addr, NULL) < 0)
+ if(H5HF_man_dblock_create(dxpl_id, hdr, NULL, 0, &dblock_addr, ret_sec_node) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block")
#ifdef QAK
-HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
+HDfprintf(stderr, "%s: root direct block, dblock_addr = %a\n", FUNC, dblock_addr);
#endif /* QAK */
/* Point root at new direct block */
@@ -333,49 +370,50 @@ HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
hdr->man_dtable.table_addr = dblock_addr;
/* Extend heap to cover new direct block */
- if(H5HF_hdr_extend_heap(hdr, (hsize_t)dblock_size, hdr->man_dtable.row_dblock_free[0]) < 0)
+ if(H5HF_hdr_adjust_heap(hdr, (hsize_t)hdr->man_dtable.cparam.start_block_size, (hssize_t)hdr->man_dtable.row_dblock_free[0]) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "can't increase space to cover root direct block")
} /* end if */
- /* Root entry already exists, go get indirect block for new direct block */
+ /* Root entry already exists, allocate direct block from root indirect block */
else {
H5HF_indirect_t *iblock; /* Pointer to indirect block to create */
- size_t dblock_entry; /* Direct entry for new direct block */
+ unsigned next_row; /* Iterator's next block row */
+ unsigned next_entry; /* Iterator's next block entry */
+ size_t next_size; /* Size of next direct block to create */
+
+ /* Update iterator to reflect any previous increments as well as allow for requested direct block size */
+ if(H5HF_hdr_update_iter(hdr, dxpl_id, min_dblock_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUPDATE, FAIL, "unable to update block iterator")
+
+ /* Retrieve information about current iterator position */
+ if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, &next_entry, &iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to retrieve current block iterator location")
+ HDassert(next_row < iblock->nrows);
+ next_size = hdr->man_dtable.row_block_size[next_row];
+
+ /* Check for skipping over blocks */
+ if(min_dblock_size > next_size) {
+HDfprintf(stderr, "%s: Skipping direct block sizes not supported, min_dblock_size = %Zu, next_size = %Zu\n", FUNC, min_dblock_size, next_size);
+HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "skipping direct block sizes not supported yet")
+ } /* end if */
+
+ /* Advance "next block" iterator to next direct block entry */
+ if(H5HF_hdr_inc_iter(hdr, (hsize_t)next_size, 1) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment 'next block' iterator")
- /* Find indirect block with room for block of correct size */
- if(NULL == (iblock = H5HF_man_iblock_place_dblock(hdr, dxpl_id, min_dblock_size, &dblock_entry, &dblock_size)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to locate indirect block with space for direct block")
#ifdef QAK
HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock);
HDfprintf(stderr, "%s: iblock->addr = %a\n", FUNC, iblock->addr);
-HDfprintf(stderr, "%s: dblock_entry = %Zu\n", FUNC, dblock_entry);
-HDfprintf(stderr, "%s: dblock_size = %Zu\n", FUNC, dblock_size);
+HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry);
#endif /* QAK */
- /* Compute the direct block's offset in the heap's address space */
- dblock_off = iblock->block_off;
- dblock_off += hdr->man_dtable.row_block_off[dblock_entry / hdr->man_dtable.cparam.width];
- dblock_off += hdr->man_dtable.row_block_size[dblock_entry / hdr->man_dtable.cparam.width] * (dblock_entry % hdr->man_dtable.cparam.width);
-
/* Create new direct block at current location*/
- if(H5HF_man_dblock_create(dxpl_id, hdr, iblock, dblock_entry, dblock_size, dblock_off, &dblock_addr, NULL) < 0)
+ if(H5HF_man_dblock_create(dxpl_id, hdr, iblock, next_entry, &dblock_addr, ret_sec_node) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block")
-
#ifdef QAK
HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
#endif /* QAK */
-
- /* Point indirect block at new direct block */
- iblock->ents[dblock_entry].addr = dblock_addr;
-
- /* Mark indirect block as modified */
- if(H5HF_iblock_dirty(iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
} /* end else */
- /* Advance the allocated heap size/new block iterator */
- if(H5HF_hdr_inc_alloc(hdr, dblock_off + dblock_size, 1) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_dblock_new() */