[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
This commit is contained in:
Quincey Koziol 2006-10-28 21:17:07 -05:00
parent c6c63ab6c6
commit 02bba16ee0
10 changed files with 921 additions and 157 deletions

View File

@ -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 */

View File

@ -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 {

View File

@ -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 */
HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC);
HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "I/O filters not supported yet")
/* Use the compressed number of bytes as the size to write */
write_size = nbytes;
/* 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")

View File

@ -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, "");

View File

@ -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)

View File

@ -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 {

View File

@ -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 */

View File

@ -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,

View File

@ -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;
@ -528,6 +527,70 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_sect_single_new() */
/*-------------------------------------------------------------------------
* 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
@ -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,37 +623,14 @@ 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 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_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
/* Set the information for the section */
sect->u.single.parent = sec_iblock;
sect->u.single.par_entry = sec_entry;
/* 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];
/* 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;
/* 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 */
/* Section is "live" now */
@ -602,6 +640,91 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_sect_single_revive() */
/*-------------------------------------------------------------------------
* 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 */
FUNC_ENTER_NOAPI(H5HF_sect_single_dblock_info, FAIL)
/*
* 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);
/* 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_dblock_info() */
/*-------------------------------------------------------------------------
* Function: H5HF_sect_single_reduce
@ -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 */

View File

@ -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))
@ -14415,6 +14742,10 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size);
if(file_size != empty_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);
@ -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 */
@ -14605,6 +14959,10 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size);
if(file_size != empty_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);
@ -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;