summaryrefslogtreecommitdiffstats
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
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
-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
-rw-r--r--test/fheap.c468
10 files changed, 920 insertions, 156 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 */
diff --git a/test/fheap.c b/test/fheap.c
index 1b701fd..d11208e 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -110,6 +110,13 @@ typedef enum {
FHEAP_TEST_FILL_N /* The number of different ways to test filling heap blocks, must be last */
} fheap_test_fill_t;
+/* Whether to compress blocks (during random tests) */
+typedef enum {
+ FHEAP_TEST_NO_COMPRESS, /* Don't compress direct blocks */
+ FHEAP_TEST_COMPRESS, /* Compress direct blocks */
+ FHEAP_TEST_COMP_N /* The number of different ways to test compressing heap blocks, must be last */
+} fheap_test_comp_t;
+
/* Testing parameters */
typedef struct fheap_test_param_t {
fheap_test_type_t reopen_heap; /* Whether to re-open the heap during the test */
@@ -117,6 +124,7 @@ typedef struct fheap_test_param_t {
fheap_test_del_drain_t drain_half; /* Whether to drain half of the objects & refill, when deleting objects */
fheap_test_fill_t fill; /* How to "bulk" fill heap blocks */
size_t actual_id_len; /* The actual length of heap IDs for a test */
+ fheap_test_comp_t comp; /* Whether to compressed the blocks or not */
} fheap_test_param_t;
/* Heap state information */
@@ -14082,10 +14090,9 @@ error:
#endif /* QAK */
#endif /* QAK2 */
-#ifdef NOT_YET
/*-------------------------------------------------------------------------
- * Function: test_filtered_man_one
+ * Function: test_filtered_man_root_direct
*
* Purpose: Test storing one 'managed' object in a heap with I/O filters
*
@@ -14098,7 +14105,7 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_filtered_man_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
+test_filtered_man_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
@@ -14135,8 +14142,8 @@ test_filtered_man_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa
TEST_ERROR
- /* Insert object small enough to fit into 'normal' heap blocks */
- obj_size = DBLOCK_SIZE(fh, 0) + 1;
+ /* Insert object small enough to fit into direct heap block */
+ obj_size = DBLOCK_SIZE(fh, 0) / 2;
if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0)
FAIL_STACK_ERROR
if(H5HF_get_id_type_test(heap_id, &obj_type) < 0)
@@ -14148,8 +14155,6 @@ test_filtered_man_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa
if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0)
TEST_ERROR
-/* QAK */
-#ifdef QAK
/* Close the fractal heap */
if(H5HF_close(fh, dxpl) < 0)
FAIL_STACK_ERROR
@@ -14160,7 +14165,7 @@ test_filtered_man_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa
FAIL_STACK_ERROR
/* Re-open the file */
- if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
FAIL_STACK_ERROR
/* Get a pointer to the internal file object */
@@ -14170,18 +14175,11 @@ test_filtered_man_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa
/* Re-open the heap */
if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr)))
FAIL_STACK_ERROR
-#endif /* QAK */
-/* QAK */
/* Check up on heap... */
- state.man_size = tmp_cparam.managed.width * DBLOCK_SIZE(fh, 0);
- state.man_size += tmp_cparam.managed.width * DBLOCK_SIZE(fh, 1);
- state.man_size += tmp_cparam.managed.width * DBLOCK_SIZE(fh, 2);
- state.man_alloc_size = DBLOCK_SIZE(fh, 2);
- state.man_free_space = tmp_cparam.managed.width * DBLOCK_FREE(fh, 0);
- state.man_free_space += tmp_cparam.managed.width * DBLOCK_FREE(fh, 1);
- state.man_free_space += DBLOCK_FREE(fh, 2) - obj_size;
- state.man_free_space += (tmp_cparam.managed.width - 1) * DBLOCK_FREE(fh, 2);
+ state.man_size = DBLOCK_SIZE(fh, 0);
+ state.man_alloc_size = DBLOCK_SIZE(fh, 0);
+ state.man_free_space = DBLOCK_FREE(fh, 0) - obj_size;
state.man_nobjs++;
if(check_stats(fh, &state))
TEST_ERROR
@@ -14257,8 +14255,315 @@ error:
H5Fclose(file);
} H5E_END_TRY;
return(1);
-} /* test_filtered_man_one() */
+} /* test_filtered_man_root_direct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_filtered_man_root_indirect
+ *
+ * Purpose: Test storing several objects in a 'managed heap with I/O filters
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 24, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_filtered_man_root_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ H5HF_t *fh = NULL; /* Fractal heap wrapper */
+ haddr_t fh_addr; /* Address of fractal heap */
+ H5HF_create_t tmp_cparam; /* Local heap creation parameters */
+ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
+ off_t empty_size; /* Size of a file with an empty heap */
+#ifdef NOT_YET
+ off_t file_size; /* Size of file currently */
#endif /* NOT_YET */
+ unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for object #1 */
+ unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for object #2 */
+ size_t obj_size; /* Size of object */
+ size_t robj_size; /* Size of object read */
+ unsigned char obj_type; /* Type of storage for object */
+ fheap_heap_state_t state; /* State of fractal heap */
+ unsigned deflate_level; /* Deflation level */
+ const char *base_desc = "insert two 'managed' objects into heap with I/O filters, then remove %s"; /* Test description */
+
+ /* Copy heap creation properties */
+ HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
+
+ /* Set an I/O filter for heap data */
+ deflate_level = 6;
+ if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
+ FAIL_STACK_ERROR
+
+ /* Perform common file & heap open operations */
+ if(open_heap(filename, fapl, dxpl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
+ TEST_ERROR
+
+ /* Perform common test initialization operations */
+ if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0)
+ TEST_ERROR
+
+
+ /* Insert object #1, small enough to fit into direct heap block */
+ obj_size = DBLOCK_SIZE(fh, 0) / 2;
+ if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id1) < 0)
+ FAIL_STACK_ERROR
+ if(H5HF_get_id_type_test(heap_id1, &obj_type) < 0)
+ FAIL_STACK_ERROR
+ if(obj_type != H5HF_ID_TYPE_MAN)
+ TEST_ERROR
+
+ /* Check for closing & re-opening the heap */
+ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0)
+ TEST_ERROR
+
+ /* Insert object #2, small enough to fit into direct heap block */
+ obj_size = DBLOCK_SIZE(fh, 0) / 2;
+ if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0)
+ FAIL_STACK_ERROR
+ if(H5HF_get_id_type_test(heap_id2, &obj_type) < 0)
+ FAIL_STACK_ERROR
+ if(obj_type != H5HF_ID_TYPE_MAN)
+ TEST_ERROR
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ FAIL_STACK_ERROR
+
+ /* Re-open the file */
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ FAIL_STACK_ERROR
+
+ /* Re-open the heap */
+ if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr)))
+ FAIL_STACK_ERROR
+
+ /* Check up on heap... */
+ state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0);
+ state.man_alloc_size = 2 * DBLOCK_SIZE(fh, 0);
+ state.man_free_space = (cparam->managed.width * DBLOCK_FREE(fh, 0)) - (obj_size * 2);
+ state.man_nobjs += 2;
+ if(check_stats(fh, &state))
+ TEST_ERROR
+
+ /* Read in ('normal') object #1 */
+ if(H5HF_get_obj_len(fh, dxpl, heap_id1, &robj_size) < 0)
+ FAIL_STACK_ERROR
+ if(obj_size != robj_size)
+ TEST_ERROR
+ HDmemset(shared_robj_g, 0, obj_size);
+ if(H5HF_read(fh, dxpl, heap_id1, shared_robj_g) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size))
+ TEST_ERROR
+
+ /* Read in ('normal') object #2 */
+ if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0)
+ FAIL_STACK_ERROR
+ if(obj_size != robj_size)
+ TEST_ERROR
+ HDmemset(shared_robj_g, 0, obj_size);
+ if(H5HF_read(fh, dxpl, heap_id2, shared_robj_g) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size))
+ TEST_ERROR
+
+ /* Delete individual objects, if we won't be deleting the entire heap later */
+ if(tparam->del_dir != FHEAP_DEL_HEAP) {
+ if(tparam->del_dir == FHEAP_DEL_FORWARD) {
+ /* Remove object #1 from heap */
+ if(H5HF_get_obj_len(fh, dxpl, heap_id1, &robj_size) < 0)
+ FAIL_STACK_ERROR
+ if(H5HF_remove(fh, dxpl, heap_id1) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ FAIL_STACK_ERROR
+
+ /* Re-open the file */
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ FAIL_STACK_ERROR
+
+ /* Re-open the heap */
+ if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr)))
+ FAIL_STACK_ERROR
+
+ /* Remove object #2 from heap */
+ if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0)
+ FAIL_STACK_ERROR
+ if(H5HF_remove(fh, dxpl, heap_id2) < 0)
+ FAIL_STACK_ERROR
+
+ /* Check up on heap... */
+ HDmemset(&state, 0, sizeof(fheap_heap_state_t));
+ if(check_stats(fh, &state))
+ TEST_ERROR
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ FAIL_STACK_ERROR
+
+ /* Re-open the file */
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ FAIL_STACK_ERROR
+
+ /* Re-open the heap */
+ if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr)))
+ FAIL_STACK_ERROR
+
+ /* Check up on heap... */
+ HDmemset(&state, 0, sizeof(fheap_heap_state_t));
+ if(check_stats(fh, &state))
+ TEST_ERROR
+ } /* end if */
+ else {
+ /* Remove object #2 from heap */
+ if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0)
+ FAIL_STACK_ERROR
+ if(H5HF_remove(fh, dxpl, heap_id2) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ FAIL_STACK_ERROR
+
+ /* Re-open the file */
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ FAIL_STACK_ERROR
+
+ /* Re-open the heap */
+ if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr)))
+ FAIL_STACK_ERROR
+
+ /* Remove object #1 from heap */
+ if(H5HF_get_obj_len(fh, dxpl, heap_id1, &robj_size) < 0)
+ FAIL_STACK_ERROR
+ if(H5HF_remove(fh, dxpl, heap_id1) < 0)
+ FAIL_STACK_ERROR
+
+ /* Check up on heap... */
+ HDmemset(&state, 0, sizeof(fheap_heap_state_t));
+ if(check_stats(fh, &state))
+ TEST_ERROR
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ FAIL_STACK_ERROR
+
+ /* Re-open the file */
+ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ FAIL_STACK_ERROR
+
+ /* Re-open the heap */
+ if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr)))
+ FAIL_STACK_ERROR
+
+ /* Check up on heap... */
+ HDmemset(&state, 0, sizeof(fheap_heap_state_t));
+ if(check_stats(fh, &state))
+ TEST_ERROR
+ } /* end else */
+ } /* end if */
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, H5P_DATASET_XFER_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+ fh = NULL;
+
+ /* Check for deleting the entire heap */
+ if(tparam->del_dir == FHEAP_DEL_HEAP) {
+ /* Delete heap */
+ if(H5HF_delete(f, dxpl, fh_addr) < 0)
+ FAIL_STACK_ERROR
+ } /* end if */
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ FAIL_STACK_ERROR
+
+#ifdef NOT_YET
+ /* Get the size of the file */
+ if((file_size = h5_get_file_size(filename)) < 0)
+ TEST_ERROR
+#ifdef QAK
+HDfprintf(stderr, "empty_size = %lu, file_size = %lu\n", (unsigned long)empty_size, (unsigned long)file_size);
+#endif /* QAK */
+
+ /* Verify the file is correct size */
+ if(file_size != empty_size)
+ TEST_ERROR
+#endif /* NOT_YET */
+
+ /* Free resources */
+ H5O_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
+
+ /* All tests passed */
+ PASSED()
+
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ if(fh)
+ H5HF_close(fh, dxpl);
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_filtered_man_root_indirect() */
#ifndef QAK
@@ -14288,6 +14593,7 @@ test_random(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_pa
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
+ H5HF_create_t tmp_cparam; /* Local heap creation parameters */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
unsigned long seed = 0; /* Random # seed */
@@ -14299,8 +14605,21 @@ test_random(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_pa
fheap_heap_state_t state; /* State of fractal heap */
size_t u; /* Local index variable */
+ /* Copy heap creation properties */
+ HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
+
+ /* Check if we are compressing the blocks */
+ if(tparam->comp == FHEAP_TEST_COMPRESS) {
+ unsigned deflate_level; /* Deflation level */
+
+ /* Set an I/O filter for heap data */
+ deflate_level = 6;
+ if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
+ FAIL_STACK_ERROR
+ } /* end if */
+
/* Perform common file & heap open operations */
- if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
+ if(open_heap(filename, fapl, dxpl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR
/* Get information about heap ID lengths */
@@ -14312,10 +14631,18 @@ test_random(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_pa
/*
* Display testing message
*/
- if(tparam->del_dir == FHEAP_DEL_HEAP)
- TESTING("inserting random-sized objects, then remove all objects (all - deleting heap)")
- else
- TESTING("inserting random-sized objects, then remove all objects (all - random)")
+ if(tparam->del_dir == FHEAP_DEL_HEAP) {
+ if(tparam->comp == FHEAP_TEST_COMPRESS)
+ TESTING("inserting random-sized objects in heap with compressed blocks, then remove all objects (all - deleting heap)")
+ else
+ TESTING("inserting random-sized objects, then remove all objects (all - deleting heap)")
+ } /* end if */
+ else {
+ if(tparam->comp == FHEAP_TEST_COMPRESS)
+ TESTING("inserting random-sized objects in heap with compressed blocks, then remove all objects (all - random)")
+ else
+ TESTING("inserting random-sized objects, then remove all objects (all - random)")
+ } /* end else */
/* Initialize the heap ID structure */
HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t));
@@ -14332,8 +14659,8 @@ HDfprintf(stderr, "Random # seed was: %lu\n", seed);
total_obj_added = 0;
while(total_obj_added < size_limit) {
/* Choose a random size of object (from 1 up to above standalone block size limit) */
- obj_size = (HDrandom() % (cparam->max_man_size + 255)) + 1;
- obj_loc = (cparam->max_man_size + 255) - obj_size;
+ obj_size = (HDrandom() % (tmp_cparam.max_man_size + 255)) + 1;
+ obj_loc = (tmp_cparam.max_man_size + 255) - obj_size;
/* Insert object */
if(add_obj(fh, dxpl, obj_loc, obj_size, NULL, &keep_ids))
@@ -14416,6 +14743,10 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size);
TEST_ERROR
/* Free resources */
+ if(tparam->comp == FHEAP_TEST_COMPRESS)
+ H5O_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
+
+ /* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
@@ -14466,6 +14797,7 @@ test_random_pow2(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_te
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
+ H5HF_create_t tmp_cparam; /* Local heap creation parameters */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */
unsigned long seed = 0; /* Random # seed */
@@ -14477,8 +14809,21 @@ test_random_pow2(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_te
fheap_heap_state_t state; /* State of fractal heap */
size_t u; /* Local index variable */
+ /* Copy heap creation properties */
+ HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t));
+
+ /* Check if we are compressing the blocks */
+ if(tparam->comp == FHEAP_TEST_COMPRESS) {
+ unsigned deflate_level; /* Deflation level */
+
+ /* Set an I/O filter for heap data */
+ deflate_level = 6;
+ if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0)
+ FAIL_STACK_ERROR
+ } /* end if */
+
/* Perform common file & heap open operations */
- if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
+ if(open_heap(filename, fapl, dxpl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0)
TEST_ERROR
/* Get information about heap ID lengths */
@@ -14490,10 +14835,18 @@ test_random_pow2(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_te
/*
* Display testing message
*/
- if(tparam->del_dir == FHEAP_DEL_HEAP)
- TESTING("inserting random-sized objects with power of 2 distribution, then remove all objects (all - deleting heap)")
- else
- TESTING("inserting random-sized objects with power of 2 distribution, then remove all objects (all - random)")
+ if(tparam->del_dir == FHEAP_DEL_HEAP) {
+ if(tparam->comp == FHEAP_TEST_COMPRESS)
+ TESTING("inserting random-sized objects with power of 2 distribution in heap with compressed blocks, then remove all objects (all - deleting heap)")
+ else
+ TESTING("inserting random-sized objects with power of 2 distribution, then remove all objects (all - deleting heap)")
+ } /* end if */
+ else {
+ if(tparam->comp == FHEAP_TEST_COMPRESS)
+ TESTING("inserting random-sized objects with power of 2 distribution in heap with compressed blocks, then remove all objects (all - random)")
+ else
+ TESTING("inserting random-sized objects with power of 2 distribution, then remove all objects (all - random)")
+ } /* end else */
/* Initialize the heap ID structure */
HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t));
@@ -14509,21 +14862,21 @@ HDfprintf(stderr, "Random # seed was: %lu\n", seed);
/* Loop over adding objects to the heap, until the size limit is reached */
total_obj_added = 0;
while(total_obj_added < size_limit) {
- unsigned size_range = (cparam->managed.start_block_size / 8); /* Object size range */
+ unsigned size_range = (tmp_cparam.managed.start_block_size / 8); /* Object size range */
/* Determine the size of the range for this object */
/* (50% of the objects inserted will use the initial size range,
* 25% of the objects will be twice as large, 12.5% will be
* four times larger, etc.)
*/
- while(HDrandom() < (RAND_MAX / 2) && size_range < cparam->max_man_size)
+ while(HDrandom() < (RAND_MAX / 2) && size_range < tmp_cparam.max_man_size)
size_range *= 2;
- if(size_range > (cparam->max_man_size + 255))
- size_range = cparam->max_man_size + 255;
+ if(size_range > (tmp_cparam.max_man_size + 255))
+ size_range = tmp_cparam.max_man_size + 255;
/* Choose a random size of object (from 1 up to stand alone block size) */
obj_size = (HDrandom() % (size_range - 1)) + 1;
- obj_loc = (cparam->max_man_size + 255) - obj_size;
+ obj_loc = (tmp_cparam.max_man_size + 255) - obj_size;
/* Insert object */
if(add_obj(fh, dxpl, obj_loc, obj_size, NULL, &keep_ids))
@@ -14598,6 +14951,7 @@ HDfprintf(stderr, "keep_ids.num_ids = %Zu, total_obj_added = %Hu, size_limit = %
if((file_size = h5_get_file_size(filename)) < 0)
TEST_ERROR
#ifdef QAK
+HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size);
HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size);
#endif /* QAK */
@@ -14606,6 +14960,10 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size);
TEST_ERROR
/* Free resources */
+ if(tparam->comp == FHEAP_TEST_COMPRESS)
+ H5O_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */
+
+ /* Free resources */
H5MM_xfree(keep_ids.ids);
H5MM_xfree(keep_ids.lens);
H5MM_xfree(keep_ids.offs);
@@ -14688,8 +15046,8 @@ main(void)
for(curr_test = FHEAP_TEST_NORMAL; curr_test < FHEAP_TEST_NTESTS; curr_test++) {
#else /* QAK */
HDfprintf(stderr, "Uncomment test loop!\n");
-/* curr_test = FHEAP_TEST_NORMAL; */
-curr_test = FHEAP_TEST_REOPEN;
+curr_test = FHEAP_TEST_NORMAL;
+/* curr_test = FHEAP_TEST_REOPEN; */
#endif /* QAK */
/* Clear the testing parameters */
HDmemset(&tparam, 0, sizeof(fheap_test_param_t));
@@ -15002,10 +15360,28 @@ HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK2 */
/* Test I/O filter support */
-#ifdef NOT_YET
- /* This test isn't working properly yet */
- nerrors += test_filtered_man_one(fapl, &small_cparam, &tparam);
-#endif /* NOT_YET */
+
+ /* Try several different methods of deleting objects */
+ {
+ fheap_test_del_dir_t del_dir; /* Deletion direction */
+
+ for(del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) {
+ tparam.del_dir = del_dir;
+
+ /* Controlled tests */
+ nerrors += test_filtered_man_root_direct(fapl, &small_cparam, &tparam);
+/* XXX: Re-enable file size checks in this test, after the file has persistent free space tracking working */
+ nerrors += test_filtered_man_root_indirect(fapl, &small_cparam, &tparam);
+
+ /* Random tests, with compressed blocks */
+ tparam.comp = FHEAP_TEST_COMPRESS;
+ nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(50*1000*1000) : (hsize_t)(25*1000*1000)), fapl, &small_cparam, &tparam);
+ nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(50*1000*1000) : (hsize_t)(2*1000*1000)), fapl, &small_cparam, &tparam);
+
+ /* Reset block compression */
+ tparam.comp = FHEAP_TEST_NO_COMPRESS;
+ } /* end for */
+ } /* end block */
#ifndef QAK
/* Random object insertion & deletion */
@@ -15017,7 +15393,7 @@ HDfprintf(stderr, "Uncomment tests!\n");
puts("Using 'small' heap creation parameters");
/* (reduce size of tests when re-opening each time) */
-/* XXX: Try to speed things up enough that these tests don't have to be reduced */
+/* XXX: Try to speed things up enough that these tests don't have to be reduced when re-opening */
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &small_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(4*1000*1000)), fapl, &small_cparam, &tparam);
@@ -15029,12 +15405,13 @@ HDfprintf(stderr, "Uncomment tests!\n");
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
+#ifndef QAK
/* Random tests using "large" heap creation parameters */
puts("Using 'large' heap creation parameters");
tparam.actual_id_len = LARGE_HEAP_ID_LEN;
/* (reduce size of tests when re-opening each time) */
-/* XXX: Try to speed things up enough that these tests don't have to be reduced */
+/* XXX: Try to speed things up enough that these tests don't have to be reduced when re-opening */
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &large_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(4*1000*1000)), fapl, &large_cparam, &tparam);
@@ -15042,6 +15419,9 @@ HDfprintf(stderr, "Uncomment tests!\n");
tparam.del_dir = FHEAP_DEL_HEAP;
nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &large_cparam, &tparam);
nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(4*1000*1000)), fapl, &large_cparam, &tparam);
+#else /* QAK */
+HDfprintf(stderr, "Uncomment tests!\n");
+#endif /* QAK */
/* Reset the "normal" heap ID length */
tparam.actual_id_len = SMALL_HEAP_ID_LEN;