summaryrefslogtreecommitdiffstats
path: root/src/H5HFint.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-05-15 04:35:53 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-05-15 04:35:53 (GMT)
commit7b6db1046b044d2f433a02b2c64f9297988e8b50 (patch)
tree3fd3b9fc87d5f4534c66b4d0598a48704d0b727b /src/H5HFint.c
parent84b03a51c7104f2b691c7067d0d82b28880b9086 (diff)
downloadhdf5-7b6db1046b044d2f433a02b2c64f9297988e8b50.zip
hdf5-7b6db1046b044d2f433a02b2c64f9297988e8b50.tar.gz
hdf5-7b6db1046b044d2f433a02b2c64f9297988e8b50.tar.bz2
[svn-r12349] Purpose:
Code checkpoint Description: Checkpoint fractal heap improvements, as well as move the free space manager code that it's using into a separate package. Platforms tested: FreeBSD 4.11 (sleipnir) Linux 2.4/64 (mir) w/C++ & FORTRAN Linux 2.4/32 (heping) Solaris 2.9 (shanti) AIX 5.? (copper) w/FORTRAN & parallel
Diffstat (limited to 'src/H5HFint.c')
-rw-r--r--src/H5HFint.c465
1 files changed, 133 insertions, 332 deletions
diff --git a/src/H5HFint.c b/src/H5HFint.c
index e8b380d..5b49c6d 100644
--- a/src/H5HFint.c
+++ b/src/H5HFint.c
@@ -57,16 +57,12 @@
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5HF_man_start_freelist(H5HF_hdr_t *hdr, hid_t dxpl_id);
/*********************/
/* Package Variables */
/*********************/
-/* Declare a free list to manage the H5HF_free_section_t struct */
-H5FL_DEFINE(H5HF_free_section_t);
-
/*****************************/
/* Library Private Variables */
@@ -80,146 +76,122 @@ H5FL_DEFINE(H5HF_free_section_t);
/*-------------------------------------------------------------------------
- * Function: H5HF_free_section_free_cb
- *
- * Purpose: Free a free section node
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, March 13, 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5HF_free_section_free_cb(void *_sect, void UNUSED *key, void UNUSED *op_data)
-{
- 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 */
-
- 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, sect);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5HF_free_section_free_cb() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HF_man_start_freelist
+ * Function: H5HF_man_locate_block
*
- * Purpose: Start free list for existing heap, by bringing in root direct
- * or indirect block and it's free space sections.
+ * Purpose: Locate a block in a managed heap
*
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * Apr 25 2006
+ * May 8 2006
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5HF_man_start_freelist(H5HF_hdr_t *hdr, hid_t dxpl_id)
+herr_t
+H5HF_man_locate_block(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t obj_off,
+ hbool_t locate_indirect,
+ H5HF_indirect_t **ret_iblock, unsigned *ret_entry,
+ H5AC_protect_t rw)
{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5HF_man_start_freelist)
+ haddr_t iblock_addr; /* Indirect block's address */
+ H5HF_indirect_t *iblock; /* Pointer to indirect block */
+ unsigned bot_row, top_row; /* Bottom & top acceptable rows */
+ unsigned row, col; /* Row & column for object's block */
+ size_t entry; /* Entry of block */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_locate_block)
+#ifdef QAK
+HDfprintf(stderr, "%s: obj_off = %Hu\n", FUNC, obj_off);
+#endif /* QAK */
/*
* Check arguments.
*/
HDassert(hdr);
+ HDassert(hdr->man_dtable.curr_root_rows); /* Only works for heaps with indirect root block */
- /* Check for empty heap */
- if(!H5F_addr_defined(hdr->man_dtable.table_addr)) {
+ /* Set up target bottom & top rows */
+ if(locate_indirect) {
+ bot_row = hdr->man_dtable.max_direct_rows;
+ top_row = hdr->man_dtable.max_direct_rows + (H5V_log2_of2(hdr->man_dtable.cparam.width) + 1);
+ } /* end if */
+ else {
+ bot_row = 0;
+ top_row = hdr->man_dtable.max_direct_rows;
+ } /* end else */
#ifdef QAK
-HDfprintf(stderr, "%s: Empty heap to [not] start\n", FUNC);
+HDfprintf(stderr, "%s: bot_row = %u, top_row = %u\n", FUNC, bot_row, top_row);
#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 */
+ /* Look up row & column for object */
+ if(H5HF_dtable_lookup(&hdr->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: Root direct block to start\n", FUNC);
+HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
#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 */
+ /* Set initial indirect block info */
+ iblock_addr = hdr->man_dtable.table_addr;
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
+#endif /* QAK */
+
+ /* Lock root indirect block */
+ if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, hdr->man_dtable.curr_root_rows, NULL, 0, rw)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
+ /* Check for indirect block row */
+ while(row < bot_row || row >= top_row) {
+ 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 */
+
+ /* Compute # of rows in child indirect block */
+ nrows = (H5V_log2_gen(hdr->man_dtable.row_block_size[row]) - hdr->man_dtable.first_row_bits) + 1;
+
+ /* Compute indirect block's entry */
+ entry = (row * hdr->man_dtable.cparam.width) + col;
#ifdef QAK
-HDfprintf(stderr, "%s: Root indirect block to start\n", FUNC);
+HDfprintf(stderr, "%s: entry = %Zu\n", FUNC, entry);
#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)))
+ /* Locate child indirect block */
+ new_iblock_addr = iblock->ents[entry].addr;
+
+ /* Lock new indirect block */
+ if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_iblock_addr, nrows, iblock, entry, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
- /* Release the root indirect block */
+ /* Release the current 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 */
+ HGOTO_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;
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
+HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
+#endif /* QAK */
+
+ /* Look up row & column in new indirect block for object */
+ if(H5HF_dtable_lookup(&hdr->man_dtable, (obj_off - iblock->block_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 */
+ } /* end while */
- /* Mark heap as being in sync now */
- hdr->freelist_sync = TRUE;
+ /* Set return parameters */
+ *ret_entry = (row * hdr->man_dtable.cparam.width) + col;
+ *ret_iblock = iblock;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_man_start_freelist() */
+} /* end H5HF_man_locate_block() */
/*-------------------------------------------------------------------------
@@ -241,7 +213,6 @@ 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)
@@ -256,45 +227,9 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request);
HDassert(request > 0);
HDassert(sec_node);
- /* 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);
-
+ /* Look for free space */
+ if((node_found = H5HF_space_find(hdr, dxpl_id, (hsize_t)request, sec_node)) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
/* If we didn't find a node, go make one big enough to hold the requested block */
if(!node_found) {
@@ -305,10 +240,10 @@ HDfprintf(stderr, "%s: Allocate new direct block\n", FUNC);
if(H5HF_man_dblock_new(hdr, dxpl_id, request) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create fractal heap direct block")
- /* Request space from the free list */
+ /* Request space from the free space */
/* (Ought to be able to be filled, now) */
- if(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")
+ if(H5HF_space_find(hdr, dxpl_id, (hsize_t)request, sec_node) <= 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
} /* end if */
HDassert(*sec_node);
#ifdef QAK
@@ -354,12 +289,12 @@ H5HF_man_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node,
HDassert(id);
/* Check for indirect section */
- if(sec_node->type == H5HF_SECT_INDIRECT) {
+ if(sec_node->sect_info.cls->type == H5FS_SECT_FHEAP_INDIRECT) {
#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->sect_info.addr = %a\n", FUNC, sec_node->sect_info.addr);
+HDfprintf(stderr, "%s: sec_node->sect_info.size = %Zu\n", FUNC, sec_node->sect_info.size);
HDfprintf(stderr, "%s: sec_node->u.indirect.iblock = %p\n", FUNC, sec_node->u.indirect.iblock);
-if(sec_node->u.indirect.iblock)
+if(sec_node->sect_info.state == H5FS_SECT_LIVE && 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);
@@ -373,12 +308,12 @@ HDfprintf(stderr, "%s: sec_node->u.indirect.indir_nrows = %u\n", FUNC, sec_node-
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't break up indirect free section")
} /* end if */
/* Check for range section */
- else if(sec_node->type == H5HF_SECT_RANGE) {
+ else if(sec_node->sect_info.cls->type == H5FS_SECT_FHEAP_RANGE) {
#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->sect_info.addr = %a\n", FUNC, sec_node->sect_info.addr);
+HDfprintf(stderr, "%s: sec_node->sect_info.size = %Zu\n", FUNC, sec_node->sect_info.size);
HDfprintf(stderr, "%s: sec_node->u.range.iblock = %p\n", FUNC, sec_node->u.range.iblock);
-if(sec_node->u.range.iblock)
+if(sec_node->sect_info.state == H5FS_SECT_LIVE && 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);
@@ -388,6 +323,14 @@ HDfprintf(stderr, "%s: sec_node->u.range.num_entries = %u\n", FUNC, sec_node->u.
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 */
+ HDassert(sec_node->sect_info.cls->type == H5FS_SECT_FHEAP_SINGLE);
+
+ /* Check for serialized 'single' section */
+ if(sec_node->sect_info.state == H5FS_SECT_SERIALIZED) {
+ if(H5HF_man_iblock_alloc_single(hdr, dxpl_id, sec_node) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize direct block for single free section")
+ } /* end if */
+ HDassert(sec_node->sect_info.state == H5FS_SECT_LIVE);
/* Lock direct block */
#ifdef QAK
@@ -408,71 +351,23 @@ HDfprintf(stderr, "%s: sec_node->u.single.dblock_size = %Zu\n", FUNC, sec_node->
/* Check for address mapping type */
if(hdr->addrmap == H5HF_ABSOLUTE) {
- H5HF_direct_free_node_t *node; /* Block's free list node */
uint8_t *p; /* Temporary pointer to obj info in block */
- size_t obj_off; /* Offset of object within block */
- size_t full_obj_size; /* Size of object including metadata */
- size_t alloc_obj_size; /* Size of object including metadata & any free space fragment */
- size_t free_obj_size; /* Size of space to free for object */
- hbool_t whole_node = FALSE; /* Whether we've used the whole node or not */
- unsigned char free_frag_size; /* Size of free space fragment */
-
- /* Locate "local" free list node for section */
-/* XXX: Change to using skip list? */
- obj_off = sec_node->sect_addr - dblock->block_off;
- node = dblock->free_list->first;
- while(node->my_offset != obj_off)
- node = node->next;
-
- /* Compute full object size, with metadata for object */
- full_obj_size = obj_size + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr);
+ size_t blk_off; /* Offset of object within block */
+
+ /* Set the offset of the object within the block */
+ blk_off = sec_node->sect_info.addr - dblock->block_off;
/* Sanity checks */
#ifdef QAK
HDfprintf(stderr, "%s: hdr->total_man_free = %Hu\n", FUNC, hdr->total_man_free);
-HDfprintf(stderr, "%s: dblock->blk_free_space = %Zu\n", FUNC, dblock->blk_free_space);
HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
#endif /* QAK */
- HDassert(dblock->blk_free_space >= obj_size);
- HDassert(dblock->free_list);
- HDassert(node->size >= full_obj_size);
+ HDassert(sec_node->sect_info.size >= obj_size);
- /* Check for using entire node */
- free_frag_size = 0;
#ifdef QAK
-HDfprintf(stderr, "%s: node->size = %Zu\n", FUNC, node->size);
+HDfprintf(stderr, "%s: sec_node->sect_info.size = %Zu\n", FUNC, sec_node->sect_info.size);
#endif /* QAK */
- if(node->size <= (full_obj_size + H5HF_MAN_ABS_DIRECT_FREE_NODE_SIZE(dblock))) {
- /* Set the offset of the object within the block */
- obj_off = node->my_offset;
-
- /* Check for allocating from first node in list */
- if(node->prev == NULL) {
- /* Make the next node in the free list the list head */
- dblock->free_list->first = node->next;
- dblock->free_list_head = node->next_offset;
- } /* end if */
- else {
- H5HF_direct_free_node_t *prev_node; /* Pointer to previous free list node for block */
-
- /* Excise node from list */
- prev_node = node->prev;
- prev_node->next = node->next;
- if(node->next) {
- H5HF_direct_free_node_t *next_node; /* Pointer to next free list node for block */
-
- next_node = node->next;
- next_node->prev = prev_node;
- prev_node->next_offset = next_node->my_offset;
- } /* end if */
- else
- prev_node->next_offset = 0;
- } /* end if */
-
- /* Set the free fragment size */
- free_frag_size = (unsigned char )(node->size - full_obj_size);
- whole_node = TRUE;
-
+ if(sec_node->sect_info.size == obj_size) {
/* 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 ||
@@ -481,73 +376,43 @@ HDfprintf(stderr, "%s: node->size = %Zu\n", FUNC, node->size);
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);
+ /* Release the memory for the free space section */
H5FL_FREE(H5HF_free_section_t, sec_node);
} /* end if */
else {
- /* Allocate object from end of free space node */
- /* (so we don't have to adjust with any other node's info */
- obj_off = (node->my_offset + node->size) - full_obj_size;
- node->size -= full_obj_size;
-
/* Adjust information for section node */
- sec_node->sect_size -= full_obj_size;
+ sec_node->sect_info.addr += obj_size;
+ sec_node->sect_info.size -= obj_size;
- /* Re-insert section node onto global list */
- if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list")
+ /* Re-insert section node into heap's free space */
+ if(H5HF_space_add(hdr, dxpl_id, sec_node) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space")
} /* end else */
- /* Mark free list as dirty */
- dblock->free_list->dirty = TRUE;
-
- /* Compute the size of the space to actually allocate */
- /* (includes the metadata for the object & the free space fragment) */
- alloc_obj_size = full_obj_size + free_frag_size;
-
- /* Compute the size of the free space to reduce */
- /* (does not include the object prefix if this object uses a whole node) */
- free_obj_size = obj_size + (whole_node ? free_frag_size : H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr));
-
#ifdef QAK
-HDfprintf(stderr, "%s: obj_off = %Zu\n", FUNC, obj_off);
-HDfprintf(stderr, "%s: free_frag_size = %Zu\n", FUNC, free_frag_size);
-HDfprintf(stderr, "%s: full_obj_size = %Zu\n", FUNC, full_obj_size);
-HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size);
+HDfprintf(stderr, "%s: blk_off = %Zu\n", FUNC, blk_off);
#endif /* QAK */
- /* Reduce space available in parent block(s) */
- 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")
+ /* Reduce space available in heap */
+ if(H5HF_hdr_adj_free(hdr, -(ssize_t)obj_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for heap")
/* Encode the object in the block */
/* Point to location for object */
- p = dblock->blk + obj_off;
-
- /* Encode the free fragment size */
- *p++ = free_frag_size;
+ p = dblock->blk + blk_off;
/* Copy the object's data into the heap */
HDmemcpy(p, obj, obj_size);
p += obj_size;
-#ifdef H5_USING_PURIFY
- /* Zero out the free space fragment */
- HDmemset(p, 0, free_frag_size);
-#endif /* H5_USING_PURIFY */
-#ifndef NDEBUG
- p += free_frag_size;
-#endif /* NDEBUG */
-
/* Sanity check */
- HDassert((size_t)(p - (dblock->blk + obj_off)) == alloc_obj_size);
+ HDassert((size_t)(p - (dblock->blk + blk_off)) == obj_size);
/* Set the heap ID for the new object (heap offset & obj length) */
#ifdef QAK
HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
#endif /* QAK */
- UINT64ENCODE_VAR(id, (dblock->block_off + obj_off), hdr->heap_off_size);
+ UINT64ENCODE_VAR(id, (dblock->block_off + blk_off), hdr->heap_off_size);
UINT64ENCODE_VAR(id, obj_size, hdr->id_len);
} /* end if */
else {
@@ -616,88 +481,27 @@ HDfprintf(stderr, "%s: obj_off = %Hu, obj_len = %Zu\n", FUNC, obj_off, obj_len);
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 */
-
- /* Look up row & column for object */
- if(H5HF_dtable_lookup(&hdr->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 */
-
- /* Set initial indirect block info */
- iblock_addr = hdr->man_dtable.table_addr;
-#ifdef QAK
-HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
-#endif /* QAK */
-
- /* 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 */
- while(row >= hdr->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 */
-
- /* Compute # of rows in child indirect block */
- nrows = (H5V_log2_gen(hdr->man_dtable.row_block_size[row]) - hdr->man_dtable.first_row_bits) + 1;
-
- /* Compute indirect block's entry */
- entry = (row * hdr->man_dtable.cparam.width) + col;
-#ifdef QAK
-HDfprintf(stderr, "%s: entry = %Zu\n", FUNC, entry);
-#endif /* QAK */
-
- /* Locate child indirect block */
- new_iblock_addr = iblock->ents[entry].addr;
-
- /* Lock new indirect block */
- 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 */
- 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")
-
- /* Switch variables to use new indirect block */
- iblock = new_iblock;
- iblock_addr = new_iblock_addr;
-#ifdef QAK
-HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
-HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
-#endif /* QAK */
-
- /* Look up row & column in new indirect block for object */
- if(H5HF_dtable_lookup(&hdr->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
+ unsigned entry; /* Entry of block */
-#ifdef QAK
-HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
-#endif /* QAK */
- } /* end while */
-
- /* Compute direct block's entry */
- entry = (row * hdr->man_dtable.cparam.width) + col;
+ /* Look up indirect block containing direct block */
+ if(H5HF_man_locate_block(hdr, dxpl_id, obj_off, FALSE, &iblock, &entry, H5AC_READ) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
#ifdef QAK
HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr);
#endif /* QAK */
/* Set direct block info */
dblock_addr = iblock->ents[entry].addr;
- dblock_size = hdr->man_dtable.row_block_size[row];
+ dblock_size = hdr->man_dtable.row_block_size[entry / hdr->man_dtable.cparam.width];
/* Lock direct block */
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 */
- 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")
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
iblock = NULL;
} /* end else */
#ifdef QAK
@@ -711,15 +515,12 @@ HDfprintf(stderr, "%s: dblock_addr = %a, dblock_size = %Zu\n", FUNC, dblock_addr
/* Point to location for object */
p = dblock->blk + blk_off;
- /* Skip over the free fragment size */
- p++;
-
/* Copy the object's data into the heap */
HDmemcpy(obj, p, obj_len);
/* 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")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
dblock = NULL;
done: