summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-10-29 02:17:07 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-10-29 02:17:07 (GMT)
commit02bba16ee0b5c9da300608896d1ea9bc97c9ab1a (patch)
tree63d98a79c1c5d01f786cfe078eec407719ff79fa /src
parentc6c63ab6c64f4a29b3f379673e5236b2d614b422 (diff)
downloadhdf5-02bba16ee0b5c9da300608896d1ea9bc97c9ab1a.zip
hdf5-02bba16ee0b5c9da300608896d1ea9bc97c9ab1a.tar.gz
hdf5-02bba16ee0b5c9da300608896d1ea9bc97c9ab1a.tar.bz2
[svn-r12823] Description:
Add support for compress heap blocks in "managed" heaps. Also, fix bug when the first direct block moves between having a parent and not having one (and vice versa), which occurs when the heap moves between having a direct root block and having an indirect root block. Tested on: FreeBSD 4.11 (sleipnir) w/threadsafe Linux/32 2.4 (heping) w/C++ & FORTRAN Linux/64 2.4 (mir) w/build-all & 1.6 compat
Diffstat (limited to 'src')
-rw-r--r--src/H5FSprivate.h2
-rw-r--r--src/H5HF.c18
-rw-r--r--src/H5HFcache.c201
-rw-r--r--src/H5HFdbg.c31
-rw-r--r--src/H5HFdblock.c37
-rw-r--r--src/H5HFiblock.c34
-rw-r--r--src/H5HFman.c30
-rw-r--r--src/H5HFpkg.h22
-rw-r--r--src/H5HFsection.c233
9 files changed, 496 insertions, 112 deletions
diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h
index 0b3b84b..9a70c4c 100644
--- a/src/H5FSprivate.h
+++ b/src/H5FSprivate.h
@@ -113,7 +113,7 @@ typedef enum H5FS_section_state_t {
/* Free space section info */
struct H5FS_section_info_t {
- haddr_t addr; /* Address of free space section in the address space */
+ haddr_t addr; /* Offset of free space section in the address space */
hsize_t size; /* Size of free space section */
unsigned type; /* Type of free space section (i.e. class) */
H5FS_section_state_t state; /* Whether the section is in "serialized" or "live" form */
diff --git a/src/H5HF.c b/src/H5HF.c
index 29b2e4d..425fa85 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -781,8 +781,24 @@ HDfprintf(stderr, "%s: hdr->fs_addr = %a\n", FUNC, hdr->fs_addr);
HDfprintf(stderr, "%s: hdr->man_dtable.table_addr = %a\n", FUNC, hdr->man_dtable.table_addr);
#endif /* QAK */
if(hdr->man_dtable.curr_root_rows == 0) {
+ hsize_t dblock_size; /* Size of direct block */
+
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0) {
+ dblock_size = (hsize_t)hdr->pline_root_direct_size;
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->pline_root_direct_size = %Zu\n", FUNC, hdr->pline_root_direct_size);
+#endif /* QAK */
+
+ /* Reset the header's pipeline information */
+ hdr->pline_root_direct_size = 0;
+ hdr->pline_root_direct_filter_mask = 0;
+ } /* end else */
+ else
+ dblock_size = (hsize_t)hdr->man_dtable.cparam.start_block_size;
+
/* Delete root direct block */
- if(H5HF_man_dblock_delete(f, dxpl_id, hdr->man_dtable.table_addr, (hsize_t)hdr->man_dtable.cparam.start_block_size) < 0)
+ if(H5HF_man_dblock_delete(f, dxpl_id, hdr->man_dtable.table_addr, dblock_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap root direct block")
} /* end if */
else {
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index 41e79e6..8661af7 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -35,6 +35,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5HFpkg.h" /* Fractal heaps */
+#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Vprivate.h" /* Vectors and arrays */
@@ -1199,14 +1200,6 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size,
if(H5HF_hdr_incr(hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header")
-#ifdef LATER
- /* Check for I/O filters on this heap */
- if(hdr->filter_len > 0) {
-HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC);
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "I/O filters not supported yet")
- } /* end if */
-#endif /* LATER */
-
/* Set block's internal information */
dblock->size = *size;
dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size);
@@ -1216,10 +1209,77 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "I/O filters not supported yet")
if((dblock->blk = H5FL_BLK_MALLOC(direct_block, (size_t)dblock->size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- /* Read direct block from disk */
- if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, (size_t)dblock->size, dxpl_id, dblock->blk) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block")
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0) {
+ H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */
+ size_t nbytes; /* Number of bytes used in buffer, after applying reverse filters */
+ void *read_buf; /* Pointer to buffer to read in */
+ size_t read_size; /* Size of filtered direct block to read */
+ unsigned filter_mask; /* Excluded filters for direct block */
+
+ /* Check for root direct block */
+ if(par_info->iblock == NULL) {
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->pline_root_direct_size = %Zu, hdr->pline_root_direct_filter_mask = %x\n", FUNC, hdr->pline_root_direct_size, hdr->pline_root_direct_filter_mask);
+HDfprintf(stderr, "%s: hdr->man_dtable.table_addr = %a, addr = %a\n", FUNC, hdr->man_dtable.table_addr, addr);
+#endif /* QAK */
+ /* Sanity check */
+ HDassert(H5F_addr_eq(hdr->man_dtable.table_addr, addr));
+
+ /* Set up parameters to read filtered direct block */
+ read_size = hdr->pline_root_direct_size;
+ filter_mask = hdr->pline_root_direct_filter_mask;
+ } /* end if */
+ else {
+#ifdef QAK
+HDfprintf(stderr, "%s: par_info->iblock = %p, par_info->entry = %u\n", FUNC, par_info->iblock, par_info->entry);
+HDfprintf(stderr, "%s: par_info->iblock->filt_ents[%u].size = %Zu, par_info->iblock->filt_ents[%u].filter_mask = %x\n", FUNC, par_info->entry, par_info->iblock->filt_ents[par_info->entry].size, par_info->entry, par_info->iblock->filt_ents[par_info->entry].filter_mask);
+HDfprintf(stderr, "%s: par_info->iblock->ents[%u].addr = %a, addr = %a\n", FUNC, par_info->entry, par_info->iblock->ents[par_info->entry].addr, addr);
+#endif /* QAK */
+ /* Sanity check */
+ HDassert(H5F_addr_eq(par_info->iblock->ents[par_info->entry].addr, addr));
+
+ /* Set up parameters to read filtered direct block */
+ read_size = par_info->iblock->filt_ents[par_info->entry].size;
+ filter_mask = par_info->iblock->filt_ents[par_info->entry].filter_mask;
+ } /* end else */
+
+ /* Allocate buffer to perform I/O filtering on */
+ if(NULL == (read_buf = H5MM_malloc(read_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "memory allocation failed for pipeline buffer")
+#ifdef QAK
+HDfprintf(stderr, "%s: read_size = %Zu, read_buf = %p\n", FUNC, read_size, read_buf);
+#endif /* QAK */
+
+ /* Read filtered direct block from disk */
+ if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, read_size, dxpl_id, read_buf) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block")
+
+ /* Push direct block data through I/O filter pipeline */
+ nbytes = read_size;
+ if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_ENABLE_EDC,
+ filter_cb, &nbytes, &read_size, &read_buf) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, NULL, "output pipeline failed")
+#ifdef QAK
+HDfprintf(stderr, "%s: nbytes = %Zu, read_size = %Zu, read_buf = %p\n", FUNC, nbytes, read_size, read_buf);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(nbytes == dblock->size);
+ /* Copy un-filtered data into block's buffer */
+ HDmemcpy(dblock->blk, read_buf, dblock->size);
+
+ /* Release the read buffer */
+ H5MM_xfree(read_buf);
+ } /* end if */
+ else {
+ /* Read direct block from disk */
+ if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, dblock->size, dxpl_id, dblock->blk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block")
+ } /* end else */
+
+ /* Start decoding direct block */
p = dblock->blk;
/* Magic number */
@@ -1358,7 +1418,6 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
/* Sanity check */
HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr));
-#ifdef LATER
/* Check for I/O filters on this heap */
if(hdr->filter_len > 0) {
H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */
@@ -1376,21 +1435,129 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_ENABLE_EDC,
filter_cb, &nbytes, &write_size, &write_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "output pipeline failed")
+#ifdef QAK
HDfprintf(stderr, "%s: nbytes = %Zu, write_size = %Zu, write_buf = %p\n", FUNC, nbytes, write_size, write_buf);
+HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
HDfprintf(stderr, "%s: dblock->size = %Zu, dblock->blk = %p\n", FUNC, dblock->size, dblock->blk);
+HDfprintf(stderr, "%s: dblock->parent = %p, dblock->par_entry = %u\n", FUNC, dblock->parent, dblock->par_entry);
+#endif /* QAK */
+
+ /* Use the compressed number of bytes as the size to write */
+ write_size = nbytes;
-HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC);
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "I/O filters not supported yet")
+ /* Check for root direct block */
+ if(dblock->parent == NULL) {
+ hbool_t hdr_changed = FALSE; /* Whether the header information changed */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->pline_root_direct_size = %Zu, hdr->pline_root_direct_filter_mask = %x\n", FUNC, hdr->pline_root_direct_size, hdr->pline_root_direct_filter_mask);
+HDfprintf(stderr, "%s: hdr->man_dtable.table_addr = %a, addr = %a\n", FUNC, hdr->man_dtable.table_addr, addr);
+#endif /* QAK */
+ /* Sanity check */
+ HDassert(H5F_addr_eq(hdr->man_dtable.table_addr, addr));
+ HDassert(hdr->pline_root_direct_size > 0);
+
+ /* Check if the filter mask changed */
+ if(hdr->pline_root_direct_filter_mask != filter_mask) {
+ hdr->pline_root_direct_filter_mask = filter_mask;
+ hdr_changed = TRUE;
+ } /* end if */
+
+ /* Check if we need to re-size the block on disk */
+ if(hdr->pline_root_direct_size != write_size) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Need to re-allocate root direct block!\n", FUNC);
+#endif /* QAK */
+ /* Release direct block's current disk space */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)hdr->pline_root_direct_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+
+ /* Allocate space for the compressed direct block */
+ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+
+ /* Let the metadata cache know, if the block moved */
+ if(!H5F_addr_eq(hdr->man_dtable.table_addr, addr))
+ if(H5AC_rename(f, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move direct block")
+
+ /* Update information about compressed direct block's location & size */
+ hdr->man_dtable.table_addr = addr;
+ hdr->pline_root_direct_size = write_size;
+
+ /* Note that heap header was modified */
+ hdr_changed = TRUE;
+ } /* end if */
+
+ /* Check if heap header was modified */
+ if(hdr_changed)
+ if(H5HF_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end if */
+ else {
+ hbool_t par_changed = FALSE; /* Whether the parent's information changed */
+ H5HF_indirect_t *par_iblock; /* Parent indirect block */
+ unsigned par_entry; /* Entry in parent indirect block */
+
+ /* Get parent information */
+ par_iblock = dblock->parent;
+ par_entry = dblock->par_entry;
+
+#ifdef QAK
+HDfprintf(stderr, "%s: par_iblock->filt_ents[%u].size = %Zu, par_iblock->filt_ents[%u].filter_mask = %x\n", FUNC, par_entry, par_iblock->filt_ents[par_entry].size, par_entry, par_iblock->filt_ents[par_entry].filter_mask);
+HDfprintf(stderr, "%s: par_iblock->ents[%u].addr = %a, addr = %a\n", FUNC, par_entry, par_iblock->ents[par_entry].addr, addr);
+#endif /* QAK */
+ /* Sanity check */
+ HDassert(H5F_addr_eq(par_iblock->ents[par_entry].addr, addr));
+ HDassert(par_iblock->filt_ents[par_entry].size > 0);
+
+ /* Check if the filter mask changed */
+ if(par_iblock->filt_ents[par_entry].filter_mask != filter_mask) {
+ par_iblock->filt_ents[par_entry].filter_mask = filter_mask;
+ par_changed = TRUE;
+ } /* end if */
+
+ /* Check if we need to re-size the block on disk */
+ if(par_iblock->filt_ents[par_entry].size != write_size) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Need to re-allocate non-root direct block!\n", FUNC);
+#endif /* QAK */
+ /* Release direct block's current disk space */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)par_iblock->filt_ents[par_entry].size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
+
+ /* Allocate space for the compressed direct block */
+ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
+
+ /* Let the metadata cache know, if the block moved */
+ if(!H5F_addr_eq(par_iblock->ents[par_entry].addr, addr))
+ if(H5AC_rename(f, H5AC_FHEAP_DBLOCK, par_iblock->ents[par_entry].addr, addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move direct block")
+
+ /* Update information about compressed direct block's location & size */
+ par_iblock->ents[par_entry].addr = addr;
+ par_iblock->filt_ents[par_entry].size = write_size;
+
+ /* Note that parent was modified */
+ par_changed = TRUE;
+ } /* end if */
+
+ /* Check if parent was modified */
+ if(par_changed)
+ if(H5HF_iblock_dirty(par_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end else */
} /* end if */
else {
-#endif /* LATER */
write_buf = dblock->blk;
write_size = dblock->size;
-#ifdef LATER
} /* end else */
-#endif /* LATER */
/* Write the direct block */
+#ifdef QAK
+HDfprintf(stderr, "%s: addr = %a, write_size = %Zu\n", FUNC, addr, write_size);
+#endif /* QAK */
if(H5F_block_write(f, H5FD_MEM_FHEAP_DBLOCK, addr, write_size, dxpl_id, write_buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap direct block to disk")
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index ce17e60..8553b15 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -212,6 +212,9 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
/*
* Print the values.
*/
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Heap is:",
+ hdr->man_dtable.curr_root_rows > 0 ? "Indirect" : "Direct");
HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
"Objects stored in 'debugging' format:",
hdr->debug_objs);
@@ -251,7 +254,7 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"ID of next 'huge' object:",
hdr->huge_next_id);
- HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
"Address of v2 B-tree for 'huge' objects:",
hdr->huge_bt2_addr);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
@@ -267,6 +270,14 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
/* Print information about I/O filters */
if(hdr->filter_len > 0) {
HDfprintf(stream, "%*sI/O filter Info...\n", indent, "");
+ if(hdr->man_dtable.curr_root_rows == 0) {
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Compressed size of root direct block:",
+ hdr->pline_root_direct_size);
+ HDfprintf(stream, "%*s%-*s %x\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Filter mask for root direct block:",
+ hdr->pline_root_direct_filter_mask);
+ } /* end if */
H5O_debug_id(H5O_PLINE_ID, f, dxpl_id, &(hdr->pline), stream,
indent + 3, MAX(0, fwidth - 3));
} /* end if */
@@ -564,7 +575,10 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
hdr->man_dtable.max_direct_rows);
/* Print the entry tables */
- HDfprintf(stream, "%*sDirect Block Entries: (address)\n", indent, "");
+ if(hdr->filter_len > 0)
+ HDfprintf(stream, "%*sDirect Block Entries: (address/compressed size/filter mask)\n", indent, "");
+ else
+ HDfprintf(stream, "%*sDirect Block Entries: (address)\n", indent, "");
for(u = 0; u < hdr->man_dtable.max_direct_rows && u < iblock->nrows; u++) {
sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)hdr->man_dtable.row_block_size[u]);
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
@@ -573,9 +587,16 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
size_t off = (u * hdr->man_dtable.cparam.width) + v;
sprintf(temp_str, "Col #%u:", (unsigned)v);
- HDfprintf(stream, "%*s%-*s %9a\n", indent + 6, "", MAX(0, fwidth - 6),
- temp_str,
- iblock->ents[off].addr);
+ if(hdr->filter_len > 0)
+ HDfprintf(stream, "%*s%-*s %9a/%6Zu/%x\n", indent + 6, "", MAX(0, fwidth - 6),
+ temp_str,
+ iblock->ents[off].addr,
+ iblock->filt_ents[off].size,
+ iblock->filt_ents[off].filter_mask);
+ else
+ HDfprintf(stream, "%*s%-*s %9a\n", indent + 6, "", MAX(0, fwidth - 6),
+ temp_str,
+ iblock->ents[off].addr);
} /* end for */
} /* end for */
HDfprintf(stream, "%*sIndirect Block Entries:\n", indent, "");
diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c
index 6082d38..1007412 100644
--- a/src/H5HFdblock.c
+++ b/src/H5HFdblock.c
@@ -147,7 +147,7 @@ H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblo
HDmemset(dblock->blk, 0, dblock->size);
#endif /* H5_USING_PURIFY */
- /* Allocate space for the header on disk */
+ /* Allocate space for the direct block on disk */
if(HADDR_UNDEF == (dblock_addr = 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
@@ -163,7 +163,7 @@ HDfprintf(stderr, "%s: direct block address = %a\n", FUNC, dblock_addr);
/* 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, dblock_addr, dblock->size)))
+ free_space, dblock->parent, dblock->par_entry)))
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 */
@@ -218,6 +218,7 @@ herr_t
H5HF_man_dblock_destroy(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_direct_t *dblock,
haddr_t dblock_addr)
{
+ hsize_t dblock_size; /* Size of direct block on disk */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_destroy)
@@ -233,6 +234,27 @@ HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
HDassert(hdr);
HDassert(dblock);
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0) {
+ /* Check for root direct block */
+ if(dblock->parent == NULL)
+ /* Get direct block's actual size */
+ dblock_size = (hsize_t)hdr->pline_root_direct_size;
+ else {
+ H5HF_indirect_t *par_iblock; /* Parent indirect block */
+ unsigned par_entry; /* Entry in parent indirect block */
+
+ /* Get parent information */
+ par_iblock = dblock->parent;
+ par_entry = dblock->par_entry;
+
+ /* Get direct block's actual size */
+ dblock_size = (hsize_t)par_iblock->filt_ents[par_entry].size;
+ } /* end else */
+ } /* end if */
+ else
+ dblock_size = (hsize_t)dblock->size;
+
/* Check for root direct block */
if(hdr->man_dtable.curr_root_rows == 0) {
#ifdef QAK
@@ -298,11 +320,12 @@ HDfprintf(stderr, "%s: Reversing iterator\n", FUNC);
dblock->par_entry = 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);
+HDfprintf(stderr, "%s: Before releasing direct block's space, dblock_addr = %a, dblock_size = %Hu\n", FUNC, dblock_addr, dblock_size);
#endif /* QAK */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, (hsize_t)dblock->size) < 0)
+
+ /* Release direct block's disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, dblock_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
/* Remove direct block from metadata cache */
@@ -381,6 +404,10 @@ HDfprintf(stderr, "%s: root direct block, dblock_addr = %a\n", FUNC, dblock_addr
/* Point root at new direct block */
hdr->man_dtable.curr_root_rows = 0;
hdr->man_dtable.table_addr = dblock_addr;
+ if(hdr->filter_len > 0) {
+ hdr->pline_root_direct_size = hdr->man_dtable.cparam.start_block_size;
+ hdr->pline_root_direct_filter_mask = 0;
+ } /* end if */
/* Extend heap to cover new direct block */
if(H5HF_hdr_adjust_heap(hdr, (hsize_t)hdr->man_dtable.cparam.start_block_size, (hssize_t)hdr->man_dtable.row_tot_dblock_free[0]) < 0)
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c
index 503846b..ac31933 100644
--- a/src/H5HFiblock.c
+++ b/src/H5HFiblock.c
@@ -441,6 +441,17 @@ HDfprintf(stderr, "%s: have_direct_block = %u\n", FUNC, (unsigned)have_direct_bl
if(H5HF_man_iblock_attach(iblock, 0, hdr->man_dtable.table_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't attach root direct block to parent indirect block")
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0) {
+ /* Set the pipeline filter information from the header */
+ iblock->filt_ents[0].size = hdr->pline_root_direct_size;
+ iblock->filt_ents[0].filter_mask = hdr->pline_root_direct_filter_mask;
+
+ /* Reset the header's pipeline information */
+ hdr->pline_root_direct_size = 0;
+ hdr->pline_root_direct_filter_mask = 0;
+ } /* end if */
+
/* Unlock first (previously the root) direct block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
@@ -862,9 +873,18 @@ HDfprintf(stderr, "%s: Reverting root indirect block\n", FUNC);
/* Get pointer to last direct block */
if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, root_iblock, 0, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block")
+ HDassert(dblock->parent == root_iblock);
+ HDassert(dblock->par_entry == 0);
+
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0) {
+ /* Set the header's pipeline information from the indirect block */
+ hdr->pline_root_direct_size = root_iblock->filt_ents[0].size;
+ hdr->pline_root_direct_filter_mask = root_iblock->filt_ents[0].filter_mask;
+ } /* end if */
/* Detach direct block from parent */
- if(H5HF_man_iblock_detach(dblock->parent, dxpl_id, dblock->par_entry) < 0)
+ if(H5HF_man_iblock_detach(dblock->parent, dxpl_id, 0) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't detach direct block from parent indirect block")
dblock->parent = NULL;
dblock->par_entry = 0;
@@ -1345,7 +1365,7 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC,
/* Compute row for entry */
row = entry / iblock->hdr->man_dtable.cparam.width;
- /* If this is a direct block, set its initial size */
+ /* If this is a direct block, reset its initial size */
if(row < iblock->hdr->man_dtable.max_direct_rows) {
iblock->filt_ents[entry].size = 0;
iblock->filt_ents[entry].filter_mask = 0;
@@ -1503,8 +1523,16 @@ HDfprintf(stderr, "%s: iblock_addr = %a, iblock_nrows = %u\n", FUNC, iblock_addr
/* Are we in a direct or indirect block row */
if(row < hdr->man_dtable.max_direct_rows) {
+ hsize_t dblock_size; /* Size of direct block on disk */
+
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0)
+ dblock_size = iblock->filt_ents[entry].size;
+ else
+ dblock_size = row_block_size;
+
/* Delete child direct block */
- if(H5HF_man_dblock_delete(hdr->f, dxpl_id, iblock->ents[entry].addr, row_block_size) < 0)
+ if(H5HF_man_dblock_delete(hdr->f, dxpl_id, iblock->ents[entry].addr, dblock_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap child direct block")
} /* end if */
else {
diff --git a/src/H5HFman.c b/src/H5HFman.c
index cc56759..56f24ca 100644
--- a/src/H5HFman.c
+++ b/src/H5HFman.c
@@ -96,6 +96,7 @@ H5HF_man_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t obj_size, const void *obj
H5HF_free_section_t *sec_node; /* Pointer to free space section */
H5HF_direct_t *dblock = NULL; /* Pointer to direct block to modify */
haddr_t dblock_addr = HADDR_UNDEF; /* Direct block address */
+ size_t dblock_size; /* Direct block size */
uint8_t *id = (uint8_t *)_id; /* Pointer to ID buffer */
size_t blk_off; /* Offset of object within block */
htri_t node_found; /* Whether an existing free list node was found */
@@ -153,7 +154,9 @@ HDfprintf(stderr, "%s: sec_node->u.row.num_entries = %u\n", FUNC, sec_node->u.ro
} /* end if */
HDassert(sec_node->sect_info.state == H5FS_SECT_LIVE);
- /* Lock direct block */
+ /* Retrieve direct block address from section */
+ if(H5HF_sect_single_dblock_info(hdr, dxpl_id, sec_node, &dblock_addr, &dblock_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve direct block information")
#ifdef QAK
HDfprintf(stderr, "%s: sec_node->sect_info.addr = %a\n", FUNC, sec_node->sect_info.addr);
HDfprintf(stderr, "%s: sec_node->sect_info.size = %Hu\n", FUNC, sec_node->sect_info.size);
@@ -161,11 +164,10 @@ HDfprintf(stderr, "%s: sec_node->u.single.parent = %p\n", FUNC, sec_node->u.sing
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 = 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)))
+
+ /* Lock direct block */
+ if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, 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 */
@@ -470,7 +472,6 @@ H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
hbool_t did_protect; /* Whether we protected the indirect block or not */
hsize_t obj_off; /* Object's offset in heap */
size_t obj_len; /* Object's length in heap */
- haddr_t dblock_addr; /* Direct block address */
size_t dblock_size; /* Direct block size */
hsize_t dblock_block_off; /* Offset of the direct block within the heap's address space */
unsigned dblock_entry; /* Entry of direct block in parent indirect block */
@@ -516,7 +517,6 @@ HDfprintf(stderr, "%s: hdr->man_dtable.cparam.max_direct_size = %Zu\n", FUNC, hd
HDfprintf(stderr, "%s: direct root block\n", FUNC);
#endif /* QAK */
/* Set direct block info */
- dblock_addr = hdr->man_dtable.table_addr;
dblock_size = hdr->man_dtable.cparam.start_block_size;
dblock_block_off = 0;
dblock_entry = 0;
@@ -532,14 +532,13 @@ HDfprintf(stderr, "%s: indirect root block\n", FUNC);
HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[dblock_entry].addr);
#endif /* QAK */
- /* Set direct block info */
- dblock_addr = iblock->ents[dblock_entry].addr;
- dblock_size = hdr->man_dtable.row_block_size[dblock_entry / hdr->man_dtable.cparam.width];
-
/* Check for offset of invalid direct block */
- if(!H5F_addr_defined(dblock_addr))
+ if(!H5F_addr_defined(iblock->ents[dblock_entry].addr))
HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "fractal heap ID not in allocated direct block")
+ /* Set direct block info */
+ dblock_size = hdr->man_dtable.row_block_size[dblock_entry / hdr->man_dtable.cparam.width];
+
/* Compute the direct block's offset in the heap's address space */
/* (based on parent indirect block's block offset) */
dblock_block_off = iblock->block_off;
@@ -547,7 +546,7 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[dblock_entry].a
dblock_block_off += hdr->man_dtable.row_block_size[dblock_entry / hdr->man_dtable.cparam.width] * (dblock_entry % hdr->man_dtable.cparam.width);
} /* end else */
#ifdef QAK
-HDfprintf(stderr, "%s: dblock_addr = %a, dblock_size = %Zu\n", FUNC, dblock_addr, dblock_size);
+HDfprintf(stderr, "%s: dblock_size = %Zu\n", FUNC, dblock_size);
#endif /* QAK */
/* Compute offset of object within block */
@@ -566,8 +565,7 @@ HDfprintf(stderr, "%s: blk_off = %Zu\n", FUNC, blk_off);
HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "object overruns end of direct block")
/* Create free space section node */
- if(NULL == (sec_node = H5HF_sect_single_new(obj_off, obj_len, iblock,
- dblock_entry, dblock_addr, dblock_size)))
+ if(NULL == (sec_node = H5HF_sect_single_new(obj_off, obj_len, iblock, dblock_entry)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create section for direct block's free space")
#ifdef QAK
HDfprintf(stderr, "%s: sec_node->sect_info.addr = %a\n", FUNC, sec_node->sect_info.addr);
@@ -576,8 +574,6 @@ HDfprintf(stderr, "%s: sec_node->u.single.parent = %p\n", FUNC, sec_node->u.sing
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 */
/* Unlock indirect block */
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 638d996..e927e4d 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -251,11 +251,6 @@ typedef struct H5HF_free_section_t {
struct {
H5HF_indirect_t *parent; /* Indirect block parent for free section's direct block */
unsigned par_entry; /* Entry of free section's direct block in parent indirect block */
- /* (Needed to retrieve direct block) */
-
- haddr_t dblock_addr; /* Address of direct block for free section */
- size_t dblock_size; /* Size of direct block */
- /* (Needed to retrieve root direct block) */
} single;
struct {
struct H5HF_free_section_t *under; /* Pointer to indirect block underlying row section */
@@ -270,7 +265,7 @@ typedef struct H5HF_free_section_t {
/* Holds either a pointer to an indirect block (if its "live") or
* the block offset of it's indirect block (if its "serialized")
* (This allows the indirect block that the section is within to
- * be compared with other sections, whether its serialized
+ * be compared with other sections, whether it's serialized
* or not)
*/
union {
@@ -322,14 +317,14 @@ typedef struct H5HF_hdr_t {
haddr_t fs_addr; /* Address of free space header on disk */
/* "Huge" object support (stored in header) */
- uint32_t max_man_size; /* Max. size of object to manage in doubling table */
- hsize_t huge_next_id; /* Next ID to use for indirectly tracked 'huge' object */
- haddr_t huge_bt2_addr; /* Address of v2 B-tree for tracking "huge" object info */
+ uint32_t max_man_size; /* Max. size of object to manage in doubling table */
+ hsize_t huge_next_id; /* Next ID to use for indirectly tracked 'huge' object */
+ haddr_t huge_bt2_addr; /* Address of v2 B-tree for tracking "huge" object info */
/* I/O filter support (stored in header, if any are used) */
H5O_pline_t pline; /* I/O filter pipeline for heap objects */
- size_t pline_root_direct_size; /* Size of filtered root direct block */
- unsigned pline_root_direct_filter_mask; /* I/O filter mask for filtered root direct block */
+ size_t pline_root_direct_size; /* Size of filtered root direct block */
+ unsigned pline_root_direct_filter_mask; /* I/O filter mask for filtered root direct block */
/* Statistics for heap (stored in header) */
hsize_t man_size; /* Total amount of 'managed' space in heap */
@@ -698,10 +693,11 @@ H5_DLL herr_t H5HF_space_sect_change_class(H5HF_hdr_t *hdr, hid_t dxpl_id,
/* Free space section routines */
H5_DLL H5HF_free_section_t *H5HF_sect_single_new(hsize_t sect_off,
- size_t sect_size, H5HF_indirect_t *parent, unsigned par_entry,
- haddr_t dblock_addr, size_t dblock_size);
+ size_t sect_size, H5HF_indirect_t *parent, unsigned par_entry);
H5_DLL herr_t H5HF_sect_single_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *sect);
+H5_DLL herr_t H5HF_sect_single_dblock_info(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_free_section_t *sect, haddr_t *dblock_addr, size_t *dblock_size);
H5_DLL herr_t H5HF_sect_single_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *sect, size_t amt);
H5_DLL herr_t H5HF_sect_row_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index 717c7f8..807beb3 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -77,6 +77,8 @@ static herr_t H5HF_sect_node_free(H5HF_free_section_t *sect,
H5HF_indirect_t *parent);
/* 'single' section routines */
+static herr_t H5HF_sect_single_locate_parent(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ hbool_t refresh, H5HF_free_section_t *sect);
static herr_t H5HF_sect_single_full_dblock(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *sect);
@@ -480,8 +482,7 @@ done:
*/
H5HF_free_section_t *
H5HF_sect_single_new(hsize_t sect_off, size_t sect_size,
- H5HF_indirect_t *parent, unsigned par_entry,
- haddr_t dblock_addr, size_t dblock_size)
+ H5HF_indirect_t *parent, unsigned par_entry)
{
H5HF_free_section_t *sect = NULL; /* 'Single' free space section to add */
hbool_t par_incr = FALSE; /* Indicate that parent iblock has been incremented */
@@ -506,8 +507,6 @@ H5HF_sect_single_new(hsize_t sect_off, size_t sect_size,
par_incr = TRUE;
} /* end if */
sect->u.single.par_entry = par_entry;
- sect->u.single.dblock_addr = dblock_addr;
- sect->u.single.dblock_size = dblock_size;
/* Set return value */
ret_value = sect;
@@ -530,6 +529,70 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_single_locate_parent
+ *
+ * Purpose: Locate the parent indirect block for a single section
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * October 24 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_sect_single_locate_parent(H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t refresh,
+ H5HF_free_section_t *sect)
+{
+ H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
+ unsigned sec_entry; /* Entry within section indirect block */
+ hbool_t did_protect; /* Whether we protected the indirect block or not */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_locate_parent)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(hdr->man_dtable.curr_root_rows > 0);
+ HDassert(sect);
+
+ /* Look up indirect block containing direct blocks for range */
+ if(H5HF_man_dblock_locate(hdr, dxpl_id, sect->sect_info.addr, &sec_iblock, &sec_entry, &did_protect, 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_CANTINC, FAIL, "can't increment reference count on shared indirect block")
+
+ /* Check for refreshing existing parent information */
+ if(refresh) {
+ if(sect->u.single.parent) {
+ /* Release hold on previous parent indirect block */
+ if(H5HF_iblock_decr(sect->u.single.parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
+ } /* end if */
+ } /* end if */
+ else
+ HDassert(sect->u.single.parent == NULL);
+
+ /* Set the information for the section */
+ sect->u.single.parent = sec_iblock;
+ sect->u.single.par_entry = sec_entry;
+
+ /* Unlock indirect block */
+ if(H5HF_man_iblock_unprotect(sec_iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
+ sec_iblock = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_sect_single_locate_parent() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_sect_single_revive
*
* Purpose: Update the memory information for a 'single' free section
@@ -546,8 +609,6 @@ herr_t
H5HF_sect_single_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *sect)
{
- 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_sect_single_revive)
@@ -562,45 +623,107 @@ H5HF_sect_single_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
/* Check for root direct block */
if(hdr->man_dtable.curr_root_rows == 0) {
/* Set the information for the section */
+ HDassert(H5F_addr_defined(hdr->man_dtable.table_addr));
sect->u.single.parent = NULL;
sect->u.single.par_entry = 0;
-
- /* Set direct block info */
- HDassert(H5F_addr_defined(hdr->man_dtable.table_addr));
- sect->u.single.dblock_addr = hdr->man_dtable.table_addr;
- sect->u.single.dblock_size = hdr->man_dtable.cparam.start_block_size;
} /* end if */
else {
- hbool_t did_protect; /* Whether we protected the indirect block or not */
+ /* Look up indirect block information for section */
+ if(H5HF_sect_single_locate_parent(hdr, dxpl_id, FALSE, sect) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get section's parent info")
+ } /* end else */
- /* Look up indirect block containing direct blocks for range */
- if(H5HF_man_dblock_locate(hdr, dxpl_id, sect->sect_info.addr, &sec_iblock, &sec_entry, &did_protect, H5AC_READ) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
+ /* Section is "live" now */
+ sect->sect_info.state = H5FS_SECT_LIVE;
- /* 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")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_sect_single_revive() */
- /* Set the information for the section */
- sect->u.single.parent = sec_iblock;
- sect->u.single.par_entry = sec_entry;
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_single_dblock_info
+ *
+ * Purpose: Retrieve the direct block information for a single section
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * October 24 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_single_dblock_info(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_free_section_t *sect, haddr_t *dblock_addr, size_t *dblock_size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Set direct block info */
- sect->u.single.dblock_addr = sec_iblock->ents[sec_entry].addr;
- sect->u.single.dblock_size = hdr->man_dtable.row_block_size[sec_entry / hdr->man_dtable.cparam.width];
+ FUNC_ENTER_NOAPI(H5HF_sect_single_dblock_info, FAIL)
- /* Unlock indirect block */
- if(H5HF_man_iblock_unprotect(sec_iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
- sec_iblock = NULL;
- } /* end else */
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(sect);
+ HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE);
+ HDassert(sect->sect_info.state == H5FS_SECT_LIVE);
+ HDassert(dblock_addr);
+ HDassert(dblock_size);
- /* Section is "live" now */
- sect->sect_info.state = H5FS_SECT_LIVE;
+ /* Check for section in first direct block of heap */
+ if(sect->sect_info.addr < hdr->man_dtable.cparam.start_block_size) {
+ /* Check for heap changing from direct <-> indirect root (or vice versa)
+ * while section was live.
+ */
+ if(sect->u.single.parent) {
+ /* Check for heap converting from indirect root to direct root while section was live */
+ if(hdr->man_dtable.curr_root_rows == 0) {
+ /* Release hold on parent indirect block */
+ if(H5HF_iblock_decr(sect->u.single.parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
+
+ /* Reset parent information */
+ sect->u.single.parent = NULL;
+ sect->u.single.par_entry = 0;
+ } /* end if */
+ else {
+ /* Check for heap converting from indirect to direct and back
+ * to indirect again, which would indicate a different
+ * indirect root block would be used for the parent of
+ * this section and the actual root indirect block.
+ */
+ if(H5HF_sect_single_locate_parent(hdr, dxpl_id, TRUE, sect) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get section's parent info")
+ } /* end else */
+ } /* end if */
+ else {
+ /* Check for heap converting from direct root to indirect root while section was live */
+ if(hdr->man_dtable.curr_root_rows != 0) {
+ /* Look up indirect block information for section */
+ if(H5HF_sect_single_locate_parent(hdr, dxpl_id, FALSE, sect) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get section's parent info")
+ } /* end if */
+ } /* end else */
+ } /* end if */
+
+ /* Check for root direct block */
+ if(hdr->man_dtable.curr_root_rows == 0) {
+ /* Retrieve direct block info from heap header */
+ HDassert(H5F_addr_defined(hdr->man_dtable.table_addr));
+ *dblock_addr = hdr->man_dtable.table_addr;
+ *dblock_size = hdr->man_dtable.cparam.start_block_size;
+ } /* end if */
+ else {
+ /* Retrieve direct block info from parent indirect block */
+ *dblock_addr = sect->u.single.parent->ents[sect->u.single.par_entry].addr;
+ *dblock_size = hdr->man_dtable.row_block_size[sect->u.single.par_entry / hdr->man_dtable.cparam.width];
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_sect_single_revive() */
+} /* end H5HF_sect_single_dblock_info() */
/*-------------------------------------------------------------------------
@@ -676,6 +799,7 @@ static herr_t
H5HF_sect_single_full_dblock(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *sect)
{
+ haddr_t dblock_addr; /* Section's direct block's address */
size_t dblock_size; /* Section's direct block's size */
size_t dblock_overhead; /* Direct block's overhead */
herr_t ret_value = SUCCEED; /* Return value */
@@ -691,9 +815,12 @@ H5HF_sect_single_full_dblock(H5HF_hdr_t *hdr, hid_t dxpl_id,
HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
#endif /* QAK */
+ /* Retrieve direct block address from section */
+ if(H5HF_sect_single_dblock_info(hdr, dxpl_id, sect, &dblock_addr, &dblock_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve direct block information")
+
/* Check for section occupying entire direct block */
/* (and not the root direct block) */
- dblock_size = sect->u.single.dblock_size;
dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
#ifdef QAK
HDfprintf(stderr, "%s: dblock_size = %u\n", FUNC, dblock_size);
@@ -703,10 +830,7 @@ HDfprintf(stderr, "%s: hdr->man_dtable.curr_root_rows = %u\n", FUNC, hdr->man_dt
if((dblock_size - dblock_overhead) == sect->sect_info.size &&
hdr->man_dtable.curr_root_rows > 0) {
H5HF_direct_t *dblock; /* Pointer to direct block for section */
- haddr_t dblock_addr; /* Section's direct block's address */
- /* Protect the direct block for the section */
- dblock_addr = sect->u.single.dblock_addr;
#ifdef QAK
HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
#endif /* QAK */
@@ -1031,8 +1155,9 @@ H5HF_sect_single_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
- H5HF_direct_t *dblock; /* Pointer to direct block for section */
- haddr_t dblock_addr; /* Section's direct block's address */
+ H5HF_direct_t *dblock; /* Pointer to direct block for section */
+ haddr_t dblock_addr; /* Section's direct block's address */
+ size_t dblock_size; /* Section's direct block's size */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_shrink)
@@ -1051,17 +1176,20 @@ HDfprintf(stderr, "%s: (*sect).sect_info = {%a, %Hu, %u}\n", FUNC, (*sect)->sect
if(H5HF_sect_single_revive(hdr, dxpl_id, (*sect)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section")
+ /* Retrieve direct block address from section */
+ if(H5HF_sect_single_dblock_info(hdr, dxpl_id, (*sect), &dblock_addr, &dblock_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve direct block information")
+
/* Protect the direct block for the section */
/* (should be a root direct block) */
- dblock_addr = (*sect)->u.single.dblock_addr;
HDassert(dblock_addr == hdr->man_dtable.table_addr);
#ifdef QAK
HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
#endif /* QAK */
if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr,
- (*sect)->u.single.dblock_size, (*sect)->u.single.parent, (*sect)->u.single.par_entry, H5AC_READ)))
+ dblock_size, (*sect)->u.single.parent, (*sect)->u.single.par_entry, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block")
- HDassert(H5F_addr_eq(dblock->block_off + (*sect)->u.single.dblock_size, (*sect)->sect_info.addr + (*sect)->sect_info.size));
+ HDassert(H5F_addr_eq(dblock->block_off + dblock_size, (*sect)->sect_info.addr + (*sect)->sect_info.size));
/* Destroy direct block */
if(H5HF_man_dblock_destroy(hdr, dxpl_id, dblock, dblock_addr) < 0)
@@ -1153,28 +1281,34 @@ HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_single
/* (not enough information to check on a single section in a root direct block) */
if(sect->u.single.parent != NULL) {
H5HF_indirect_t *iblock; /* Indirect block that section's direct block resides in */
+ haddr_t dblock_addr; /* Direct block address */
+ size_t dblock_size; /* Direct block size */
size_t dblock_overhead; /* Direct block's overhead */
unsigned dblock_status = 0; /* Direct block's status in the metadata cache */
herr_t status; /* Generic status value */
#ifdef QAK
-HDfprintf(stderr, "%s: sect->u.single = {%p, %u, %a, %Zu}\n", "H5HF_sect_single_valid", sect->u.single.parent, sect->u.single.par_entry, sect->u.single.dblock_addr, sect->u.single.dblock_size);
+HDfprintf(stderr, "%s: sect->u.single = {%p, %u, %a, %Zu}\n", "H5HF_sect_single_valid", sect->u.single.parent, sect->u.single.par_entry);
#endif /* QAK */
/* Sanity check settings for section's direct block's parent */
iblock = sect->u.single.parent;
HDassert(H5F_addr_defined(iblock->ents[sect->u.single.par_entry].addr));
- HDassert(H5F_addr_eq(iblock->ents[sect->u.single.par_entry].addr,
- sect->u.single.dblock_addr));
+
+ /* Retrieve direct block address from section */
+ status = H5HF_sect_single_dblock_info(iblock->hdr, H5AC_dxpl_id, sect, &dblock_addr, &dblock_size);
+ HDassert(status >= 0);
+ HDassert(H5F_addr_eq(iblock->ents[sect->u.single.par_entry].addr, dblock_addr));
+ HDassert(dblock_size > 0);
/* Check if the section is actually within the heap */
HDassert(sect->sect_info.addr < iblock->hdr->man_iter_off);
/* Check that the direct block has been merged correctly */
dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(iblock->hdr);
- HDassert((sect->sect_info.size + dblock_overhead) < sect->u.single.dblock_size);
+ HDassert((sect->sect_info.size + dblock_overhead) < dblock_size);
/* Check the direct block's status in the metadata cache */
- status = H5AC_get_entry_status(iblock->hdr->f, sect->u.single.dblock_addr, &dblock_status);
+ status = H5AC_get_entry_status(iblock->hdr->f, dblock_addr, &dblock_status);
HDassert(status >= 0);
/* If the direct block for the section isn't already protected,
@@ -1185,19 +1319,18 @@ HDfprintf(stderr, "%s: sect->u.single = {%p, %u, %a, %Zu}\n", "H5HF_sect_single_
H5HF_direct_t *dblock; /* Direct block for section */
/* Protect the direct block for the section */
- dblock = H5HF_man_dblock_protect(iblock->hdr, H5AC_dxpl_id, sect->u.single.dblock_addr, sect->u.single.dblock_size, iblock, sect->u.single.par_entry, H5AC_READ);
+ dblock = H5HF_man_dblock_protect(iblock->hdr, H5AC_dxpl_id, dblock_addr, dblock_size, iblock, sect->u.single.par_entry, H5AC_READ);
HDassert(dblock);
/* Sanity check settings for section */
- HDassert(sect->u.single.dblock_size > 0);
- HDassert(sect->u.single.dblock_size == dblock->size);
+ HDassert(dblock_size == dblock->size);
HDassert(dblock->size > sect->sect_info.size);
HDassert(H5F_addr_lt(dblock->block_off, sect->sect_info.addr));
HDassert(H5F_addr_ge((dblock->block_off + dblock->size),
(sect->sect_info.addr + sect->sect_info.size)));
/* Release direct block */
- status = H5AC_unprotect(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_DBLOCK, sect->u.single.dblock_addr, dblock, H5AC__NO_FLAGS_SET);
+ status = H5AC_unprotect(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET);
HDassert(status >= 0);
} /* end if */
} /* end if */