summaryrefslogtreecommitdiffstats
path: root/src/H5HFiblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5HFiblock.c')
-rw-r--r--src/H5HFiblock.c164
1 files changed, 37 insertions, 127 deletions
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c
index cdffa80..d9462c8 100644
--- a/src/H5HFiblock.c
+++ b/src/H5HFiblock.c
@@ -444,6 +444,9 @@ HDfprintf(stderr, "%s: acc_row_dblock_free_space = %Zu\n", FUNC, acc_row_dblock_
/* Advance outer loop index */
u += row_entries;
} /* end for */
+#ifdef QAK
+HDfprintf(stderr, "%s: sect_off = %Zu\n", FUNC, sect_off);
+#endif /* QAK */
/* Advance the allocated heap size/new block iterator */
if(H5HF_hdr_inc_alloc(hdr, sect_off, nentries) < 0)
@@ -658,7 +661,7 @@ HDfprintf(stderr, "%s: Extending root indirect block\n", FUNC);
#ifdef QAK
HDfprintf(stderr, "%s: min_nrows = %u, new_nrows = %u\n", FUNC, min_nrows, new_nrows);
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
-HDfprintf(stderr, "%s: old_next_entry = %u, iblock->next_entry = %u\n", FUNC, old_next_entry, iblock->next_entry);
+HDfprintf(stderr, "%s: new_next_entry = %u\n", FUNC, new_next_entry);
#endif /* QAK */
/* Currently, the old block data is "thrown away" after the space is reallocated,
@@ -672,7 +675,7 @@ HDfprintf(stderr, "%s: old_next_entry = %u, iblock->next_entry = %u\n", FUNC, ol
*/
/* Free previous indirect block disk space */
if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size)<0)
- HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block")
/* Compute size of buffer needed for new indirect block */
iblock->nrows = new_nrows;
@@ -680,7 +683,7 @@ HDfprintf(stderr, "%s: old_next_entry = %u, iblock->next_entry = %u\n", FUNC, ol
/* Allocate space for the new indirect block on disk */
if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
- HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
#ifdef QAK
HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr);
#endif /* QAK */
@@ -710,9 +713,10 @@ HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr);
if(H5HF_iblock_dirty(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
- /* Move object in cache */
- if(H5AC_rename(hdr->f, H5AC_FHEAP_IBLOCK, iblock->addr, new_addr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, FAIL, "unable to move fractal heap root indirect block")
+ /* Move object in cache, if it actually was relocated */
+ if(H5F_addr_ne(iblock->addr, new_addr))
+ if(H5AC_rename(hdr->f, H5AC_FHEAP_IBLOCK, iblock->addr, new_addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, FAIL, "unable to move fractal heap root indirect block")
/* Update other shared header info */
hdr->man_dtable.curr_root_rows = new_nrows;
@@ -731,11 +735,22 @@ HDfprintf(stderr, "%s: acc_dblock_free = %Hu\n", FUNC, acc_dblock_free);
if(H5HF_hdr_dirty(hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark header as dirty")
+/* XXX: Sanity check until can rename pinned entry in metadata cache */
+#ifndef NDEBUG
+{
+H5HF_indirect_t *old_root_iblock = iblock;
+#endif /* NDEBUG */
+
/* Lock root indirect block (again) */
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_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")
iblock->addr = new_addr;
+#ifndef NDEBUG
+ HDassert(old_root_iblock == iblock);
+}
+#endif /* NDEBUG */
+
/* Update the indirect block pointer in iterator */
/* (pins the indirect block after it's in the new location) */
if(H5HF_man_iter_update_iblock(&hdr->next_block, iblock) < 0)
@@ -830,7 +845,7 @@ HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row);
HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry);
#endif /* QAK */
/* Check for skipping over blocks in the current block */
- if(min_dblock_row > next_row) {
+ if(min_dblock_row > next_row && next_row < iblock->nrows) {
unsigned min_entry; /* Min entry for direct block requested */
unsigned skip_entries; /* Number of entries to skip in the current block */
@@ -853,6 +868,11 @@ HDfprintf(stderr, "%s: min_entry = %u, skip_entries = %u\n", FUNC, min_entry, sk
&next_entry, &iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to retrieve current block iterator location")
} /* end if */
+
+ do {
+ /* Reset conditions for leaving loop */
+ walked_up = walked_down = FALSE;
+
#ifdef QAK
HDfprintf(stderr, "%s: Check 2.0\n", FUNC);
HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock);
@@ -861,10 +881,6 @@ HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row);
HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry);
#endif /* QAK */
- do {
- /* Reset conditions for leaving loop */
- walked_up = walked_down = FALSE;
-
/* Check for walking off end of indirect block */
/* (walk up iterator) */
while(next_row >= iblock->nrows) {
@@ -899,7 +915,7 @@ HDfprintf(stderr, "%s: Walking up a level\n", FUNC);
/* Indicate that we walked up */
walked_up = TRUE;
- } /* end if */
+ } /* end while */
#ifdef QAK
HDfprintf(stderr, "%s: Check 3.0\n", FUNC);
HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock);
@@ -946,6 +962,8 @@ HDfprintf(stderr, "%s: Skipping indirect block row that is too small\n", FUNC);
child_rows_needed = (H5V_log2_of2(min_dblock_size) - H5V_log2_of2(hdr->man_dtable.cparam.start_block_size)) + 2;
HDassert(child_rows_needed > child_nrows);
child_entry = (next_row + (child_rows_needed - child_nrows)) * hdr->man_dtable.cparam.width;
+ if(child_entry > (iblock->nrows * hdr->man_dtable.cparam.width))
+ child_entry = iblock->nrows * hdr->man_dtable.cparam.width;
#ifdef QAK
HDfprintf(stderr, "%s: child_rows_needed = %u\n", FUNC, child_rows_needed);
HDfprintf(stderr, "%s: child_entry = %u\n", FUNC, child_entry);
@@ -1035,7 +1053,7 @@ HDfprintf(stderr, "%s: Skipping rows in new child indirect block - new_entry = %
/* Indicate that we walked down */
walked_down = TRUE;
- } /* end while */
+ } /* end if */
} while(walked_down || walked_up);
} /* end else */
@@ -1074,78 +1092,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_man_iblock_alloc_single
- *
- * Purpose: Update the memory information for a 'single' free section
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * May 8 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5HF_man_iblock_alloc_single(H5HF_hdr_t *hdr, hid_t dxpl_id,
- H5HF_free_section_t *sec_node)
-{
- H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
- unsigned sec_entry; /* Entry within section indirect block */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_alloc_single)
-
- /*
- * Check arguments.
- */
- HDassert(hdr);
- HDassert(sec_node);
- HDassert(sec_node->sect_info.state == H5FS_SECT_SERIALIZED);
-
- /* Check for root direct block */
- if(hdr->man_dtable.curr_root_rows == 0) {
- /* Set the information for the section */
- sec_node->u.single.parent = NULL;
- sec_node->u.single.par_entry = 0;
-
- /* Set direct block info */
- HDassert(H5F_addr_defined(hdr->man_dtable.table_addr));
- sec_node->u.single.dblock_addr = hdr->man_dtable.table_addr;
- sec_node->u.single.dblock_size = hdr->man_dtable.cparam.start_block_size;
- } /* end if */
- else {
- /* Look up indirect block containing direct blocks for range */
- if(H5HF_man_locate_block(hdr, dxpl_id, sec_node->sect_info.addr, FALSE, &sec_iblock, &sec_entry, H5AC_READ) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
-
- /* Increment reference count on indirect block that free section is in */
- if(H5HF_iblock_incr(sec_iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
-
- /* Set the information for the section */
- sec_node->u.single.parent = sec_iblock;
- sec_node->u.single.par_entry = sec_entry;
-
- /* Set direct block info */
- sec_node->u.single.dblock_addr = sec_iblock->ents[sec_entry].addr;
- sec_node->u.single.dblock_size = hdr->man_dtable.row_block_size[sec_entry / hdr->man_dtable.cparam.width];
-
- /* Unlock indirect block */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, sec_iblock->addr, sec_iblock, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
- sec_iblock = NULL;
- } /* end else */
-
- /* Section is "live" now */
- sec_node->sect_info.state = H5FS_SECT_LIVE;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_man_iblock_alloc_single() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5HF_man_iblock_alloc_range
*
* Purpose: Allocate a "single" section for an object, out of a "range"
@@ -1182,27 +1128,9 @@ H5HF_man_iblock_alloc_range(H5HF_hdr_t *hdr, hid_t dxpl_id,
/* Check for serialized section */
if(old_sec_node->sect_info.state == H5FS_SECT_SERIALIZED) {
- H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
- unsigned sec_entry; /* Entry within section indirect block */
-
- /* Look up indirect block containing direct blocks for range */
- if(H5HF_man_locate_block(hdr, dxpl_id, old_sec_node->sect_info.addr, FALSE, &sec_iblock, &sec_entry, H5AC_READ) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
-
- /* Increment reference count on indirect block that free section is in */
- if(H5HF_iblock_incr(sec_iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
-
- /* Set the pointer to the section's indirect block */
- old_sec_node->u.range.iblock = sec_iblock;
-
- /* Unlock indirect block */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, sec_iblock->addr, sec_iblock, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
- sec_iblock = NULL;
-
- /* Section is "live" now */
- old_sec_node->sect_info.state = H5FS_SECT_LIVE;
+ /* Revive range section */
+ if(H5HF_sect_range_revive(hdr, dxpl_id, old_sec_node) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTREVIVE, FAIL, "can't revive range section")
} /* end if */
/* Compute info about range */
@@ -1309,27 +1237,9 @@ H5HF_man_iblock_alloc_indirect(H5HF_hdr_t *hdr, hid_t dxpl_id,
/* Check for serialized section */
if(old_sec_node->sect_info.state == H5FS_SECT_SERIALIZED) {
- H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
- unsigned sec_entry; /* Entry within section indirect block */
-
- /* Look up indirect block containing indirect blocks for section */
- if(H5HF_man_locate_block(hdr, dxpl_id, old_sec_node->sect_info.addr, TRUE, &sec_iblock, &sec_entry, H5AC_READ) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
-
- /* Increment reference count on indirect block that free section is in */
- if(H5HF_iblock_incr(sec_iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
-
- /* Set the pointer to the section's indirect block */
- old_sec_node->u.indirect.iblock = sec_iblock;
-
- /* Unlock indirect block */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, sec_iblock->addr, sec_iblock, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
- sec_iblock = NULL;
-
- /* Section is "live" now */
- old_sec_node->sect_info.state = H5FS_SECT_LIVE;
+ /* Revive indirect section */
+ if(H5HF_sect_indirect_revive(hdr, dxpl_id, old_sec_node) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTREVIVE, FAIL, "can't revive indirect section")
} /* end if */
/* Compute info about range */