summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5HF.c9
-rw-r--r--src/H5HFcache.c112
-rw-r--r--src/H5HFdbg.c48
-rw-r--r--src/H5HFflist.c195
-rw-r--r--src/H5HFint.c474
-rw-r--r--src/H5HFpkg.h80
-rw-r--r--src/H5private.h19
-rw-r--r--test/fheap.c646
8 files changed, 1191 insertions, 392 deletions
diff --git a/src/H5HF.c b/src/H5HF.c
index ac5990b..feb88be 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -99,6 +99,7 @@ herr_t
H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, haddr_t *addr_p)
{
H5HF_t *fh = NULL; /* The new fractal heap header information */
+ H5HF_shared_t *shared = NULL; /* Shared fractal heap information */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_create, FAIL)
@@ -119,12 +120,16 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, haddr_t *addr_p)
/* Reset the metadata cache info for the heap header */
HDmemset(&fh->cache_info, 0, sizeof(H5AC_info_t));
+ /* Allocate & basic initialization for the shared info struct */
+ if(NULL == (shared = H5HF_shared_alloc(f)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for shared heap info")
+
/* Allocate space for the header on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(f))))
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(shared))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap header")
/* Initialize shared fractal heap info */
- if(H5HF_shared_create(f, fh, *addr_p, cparam) < 0)
+ if(H5HF_shared_init(shared, fh, *addr_p, cparam) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared fractal heap info")
/* Cache the new fractal heap header */
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index fbeecc8..1fd3b51 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -283,7 +283,7 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
shared->heap_addr = addr;
/* Compute the size of the fractal heap header on disk */
- size = H5HF_HEADER_SIZE(f);
+ size = H5HF_HEADER_SIZE(shared);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
@@ -399,7 +399,7 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H
HDassert(shared->dirty);
/* Compute the size of the heap header on disk */
- size = H5HF_HEADER_SIZE(f);
+ size = H5HF_HEADER_SIZE(shared);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
@@ -554,16 +554,23 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t UNUSED *fh, size_t *size_ptr)
+H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *fh, size_t *size_ptr)
{
+ H5HF_shared_t *shared; /* Shared fractal heap information */
+
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_size)
/* check arguments */
HDassert(f);
+ HDassert(fh);
HDassert(size_ptr);
+ /* Get the pointer to the shared heap info */
+ shared = H5RC_GET_OBJ(fh->shared);
+ HDassert(shared);
+
/* Set size value */
- *size_ptr = H5HF_HEADER_SIZE(f);
+ *size_ptr = H5HF_HEADER_SIZE(shared);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5HF_cache_hdr_size() */
@@ -994,14 +1001,10 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
/* Set block's internal information */
iblock->nrows = *nrows;
- if(iblock->nrows > shared->man_dtable.max_direct_rows) {
- iblock->ndir_rows = shared->man_dtable.max_direct_rows;
- iblock->nindir_rows = iblock->nrows - iblock->ndir_rows;
- } /* end if */
- else {
- iblock->ndir_rows = iblock->nrows;
- iblock->nindir_rows = 0;
- } /* end else */
+ if(!iblock->parent)
+ iblock->max_rows = shared->man_dtable.max_root_rows;
+ else
+ iblock->max_rows = *nrows;
/* Compute size of indirect block */
iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock);
@@ -1037,7 +1040,7 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
if(metadata_chksum != 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap direct block")
- /* Address of heap that owns this block (skip) */
+ /* Address of heap that owns this block */
H5F_addr_decode(f, &p, &heap_addr);
if(H5F_addr_ne(heap_addr, shared->heap_addr))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block")
@@ -1045,47 +1048,28 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
/* Offset of heap within the heap's address space */
UINT64DECODE_VAR(p, iblock->block_off, shared->heap_off_size);
+ /* Offset of next entry to allocate within this block */
+ UINT32DECODE(p, iblock->next_entry);
+
+ /* Compute next block column, row & size */
+ iblock->next_col = iblock->next_entry % shared->man_dtable.cparam.width;
+ iblock->next_row = iblock->next_entry / shared->man_dtable.cparam.width;
+ iblock->next_size = shared->man_dtable.row_block_size[iblock->next_row];
+
/* Allocate & decode indirect block entry tables */
- HDassert(iblock->ndir_rows > 0);
- if(NULL == (iblock->dblock_ents = H5FL_SEQ_MALLOC(H5HF_indirect_dblock_ent_t, (iblock->ndir_rows * shared->man_dtable.cparam.width))))
+ HDassert(iblock->nrows > 0);
+ if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * shared->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries")
- iblock->dir_full = TRUE;
- for(u = 0; u < (iblock->ndir_rows * shared->man_dtable.cparam.width); u++) {
- H5F_addr_decode(f, &p, &(iblock->dblock_ents[u].addr));
- UINT32DECODE_VAR(p, iblock->dblock_ents[u].free_space, shared->man_dtable.max_dir_blk_off_size);
-
- /* Check for direct block being undefined and use that for the next one to allocate from this indirect block */
- if(iblock->dir_full) {
- if(!H5F_addr_defined(iblock->dblock_ents[u].addr)) {
- iblock->next_dir_col = u % shared->man_dtable.cparam.width;
- iblock->next_dir_row = u / shared->man_dtable.cparam.width;
- iblock->next_dir_entry = u;
- if(iblock->next_dir_row == 0)
- iblock->next_dir_size = shared->man_dtable.cparam.start_block_size;
- else
- iblock->next_dir_size = shared->man_dtable.cparam.start_block_size * (1 << (iblock->next_dir_row - 1));
- if(iblock->block_off == 0)
- iblock->max_direct_rows = shared->man_dtable.max_direct_rows;
- else
- HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "computing max direct rows for non-root indirect block not supported yet")
-
- /* Set the flag to indicate the direct blocks aren't full */
- iblock->dir_full = FALSE;
- } /* end if */
- } /* end if */
+ for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) {
+ /* Decode block address */
+ H5F_addr_decode(f, &p, &(iblock->ents[u].addr));
+
+ /* Decode direct & indirect blocks differently */
+ if(u < (shared->man_dtable.max_direct_rows * shared->man_dtable.cparam.width))
+ UINT32DECODE_VAR(p, iblock->ents[u].free_space, shared->man_dtable.max_dir_blk_off_size)
+ else
+ UINT64DECODE_VAR(p, iblock->ents[u].free_space, shared->heap_off_size)
} /* end for */
- if(iblock->nindir_rows > 0) {
- if(NULL == (iblock->iblock_ents = H5FL_SEQ_MALLOC(H5HF_indirect_iblock_ent_t, (iblock->nindir_rows * shared->man_dtable.cparam.width))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for indirect entries")
-
- /* Decode indirect block-specific fields */
- for(u = 0; u < (iblock->nindir_rows * shared->man_dtable.cparam.width); u++) {
- H5F_addr_decode(f, &p, &(iblock->iblock_ents[u].addr));
- UINT64DECODE_VAR(p, iblock->iblock_ents[u].free_space, shared->heap_off_size);
- } /* end for */
- } /* end if */
- else
- iblock->iblock_ents = NULL;
/* Sanity check */
HDassert((size_t)(p - buf) == iblock->size);
@@ -1150,8 +1134,6 @@ HDfprintf(stderr, "%s: Flushing indirect block\n", FUNC);
/* XXX: Use free list factories? */
#ifdef QAK
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
-HDfprintf(stderr, "%s: iblock->ndir_rows = %u\n", FUNC, iblock->ndir_rows);
-HDfprintf(stderr, "%s: iblock->nindir_rows = %u\n", FUNC, iblock->nindir_rows);
HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size);
HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->man_dtable.cparam.width);
@@ -1182,21 +1164,21 @@ HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->ma
/* Offset of block in heap */
UINT64ENCODE_VAR(p, iblock->block_off, shared->heap_off_size);
-/* XXX: Fix this when we start writing recursive indirect blocks */
-if(iblock->block_off != 0)
- HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "fix computing max direct rows for non-root indirect block for loading")
+
+ /* Next block entry to allocate from */
+ UINT32ENCODE(p, iblock->next_entry);
/* Encode indirect block-specific fields */
- HDassert(iblock->ndir_rows > 0);
- for(u = 0; u < (iblock->ndir_rows * shared->man_dtable.cparam.width); u++) {
- H5F_addr_encode(f, &p, iblock->dblock_ents[u].addr);
- UINT32ENCODE_VAR(p, iblock->dblock_ents[u].free_space, shared->man_dtable.max_dir_blk_off_size);
+ for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) {
+ /* Encode block address */
+ H5F_addr_encode(f, &p, iblock->ents[u].addr);
+
+ /* Encode direct & indirect blocks differently */
+ if(u < (shared->man_dtable.max_direct_rows * shared->man_dtable.cparam.width))
+ UINT32ENCODE_VAR(p, iblock->ents[u].free_space, shared->man_dtable.max_dir_blk_off_size)
+ else
+ UINT64ENCODE_VAR(p, iblock->ents[u].free_space, shared->heap_off_size)
} /* end for */
- if(iblock->nindir_rows > 0)
- for(u = 0; u < (iblock->nindir_rows * shared->man_dtable.cparam.width); u++) {
- H5F_addr_encode(f, &p, iblock->iblock_ents[u].addr);
- UINT64ENCODE_VAR(p, iblock->iblock_ents[u].free_space, shared->heap_off_size);
- } /* end for */
/* Sanity check */
HDassert((size_t)(p - buf) == iblock->size);
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index 5dddac7..43a6064 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -133,7 +133,7 @@ H5HF_dtable_debug(H5HF_dtable_t *dtable, FILE *stream, int indent, int fwidth)
/* Computed values */
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Max. # of rows in root indirect block:",
- dtable->max_root_indirect_rows);
+ dtable->max_root_rows);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Max. # of direct rows in any indirect block:",
dtable->max_direct_rows);
@@ -476,35 +476,28 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
"Size of indirect block:",
iblock->size);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Total # of rows:",
+ "Current # of rows:",
iblock->nrows);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "# of direct rows:",
- iblock->ndir_rows);
- HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "# of indirect rows:",
- iblock->nindir_rows);
- HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Direct blocks full:",
- (iblock->dir_full ? "TRUE" : "FALSE"));
+ "Max. # of rows:",
+ iblock->max_rows);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Max direct block rows:",
- iblock->max_direct_rows);
+ shared->man_dtable.max_direct_rows);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Next direct block column:",
- iblock->next_dir_col);
+ "Next block column:",
+ iblock->next_col);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Next direct block row:",
- iblock->next_dir_row);
- HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Next direct block size:",
- iblock->next_dir_size);
+ "Next block row:",
+ iblock->next_row);
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Next block size:",
+ iblock->next_size);
/* Print the entry tables */
- dblock_size = shared->man_dtable.cparam.start_block_size;
HDfprintf(stream, "%*sDirect Block Entries (address, free space):\n", indent, "");
- for(u = 0; u < iblock->ndir_rows; u++) {
- sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)dblock_size);
+ for(u = 0; u < shared->man_dtable.max_direct_rows && u < iblock->nrows; u++) {
+ sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)shared->man_dtable.row_block_size[u]);
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
for(v = 0; v < shared->man_dtable.cparam.width; v++) {
@@ -513,14 +506,14 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
sprintf(temp_str, "Col #%u:", (unsigned)v);
HDfprintf(stream, "%*s%-*s %8a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6),
temp_str,
- iblock->dblock_ents[off].addr,
- iblock->dblock_ents[off].free_space);
+ iblock->ents[off].addr,
+ iblock->ents[off].free_space);
} /* end for */
dblock_size *= 2;
} /* end for */
HDfprintf(stream, "%*sIndirect Block Entries:\n", indent, "");
- if(iblock->nindir_rows > 0) {
- for(u = 0; u < iblock->nindir_rows; u++) {
+ if(iblock->nrows > shared->man_dtable.max_direct_rows) {
+ for(u = shared->man_dtable.max_direct_rows; u < iblock->nrows; u++) {
sprintf(temp_str, "Row #%u:", (unsigned)u);
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
@@ -528,9 +521,10 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
size_t off = (u * shared->man_dtable.cparam.width) + v;
sprintf(temp_str, "Col #%u:", (unsigned)v);
- HDfprintf(stream, "%*s%-*s %8a\n", indent + 6, "", MAX(0, fwidth - 6),
+ HDfprintf(stream, "%*s%-*s %8a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6),
temp_str,
- iblock->iblock_ents[off].addr);
+ iblock->ents[off].addr,
+ iblock->ents[off].free_space);
} /* end for */
} /* end for */
} /* end if */
diff --git a/src/H5HFflist.c b/src/H5HFflist.c
index 361bb37..97e30e9 100644
--- a/src/H5HFflist.c
+++ b/src/H5HFflist.c
@@ -44,6 +44,13 @@
/* Local Typedefs */
/******************/
+/* Structure for storing single free list section */
+typedef struct H5HF_flist_single_t {
+ void *node; /* Pointer to section's node */
+ size_t *size_key; /* Pointer to size key for section */
+ haddr_t *addr_key; /* Pointer to address key for section */
+} H5HF_flist_single_t;
+
/* Free list node for free list sections of the same size */
typedef struct H5HF_flist_node_t {
size_t sec_size; /* Size of all sections on list */
@@ -58,6 +65,8 @@ typedef struct H5HF_flist_node_t {
/* Main free list info */
struct H5HF_freelist_t {
hsize_t tot_space; /* Total amount of space in free list */
+ size_t sec_count; /* # of sections on free list */
+ H5HF_flist_single_t single; /* Section information when free list has only one free section */
unsigned nbins; /* Number of bins */
H5SL_operator_t node_free_op; /* Callback for freeing nodes when free list is destroyed */
H5SL_t **bins; /* Pointer to array of lists of free nodes */
@@ -128,12 +137,13 @@ H5HF_flist_create(size_t max_block_size, H5SL_operator_t node_free_op)
/* Set free list parameters */
flist->tot_space = 0;
+ flist->sec_count = 0;
+ flist->single.node = NULL;
+ flist->single.size_key = NULL;
+ flist->single.addr_key = NULL;
flist->nbins = H5V_log2_of2(max_block_size);
flist->node_free_op = node_free_op;
-
- /* Allocate the bins for free space sizes */
- if(NULL == (flist->bins = H5FL_SEQ_CALLOC(H5SL_ptr_t, flist->nbins)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free list bins")
+ flist->bins = NULL;
/* Set return value */
ret_value = flist;
@@ -144,27 +154,28 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_flist_add
+ * Function: H5HF_flist_add_bin_node
*
* Purpose: Add a section of free space in a direct block to the free list
+ * bins
*
* Return: Success: non-negative
*
* Failure: negative
*
* Programmer: Quincey Koziol
- * Tuesday, March 7, 2006
+ * Monday, March 20, 2006
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5HF_flist_add(H5HF_freelist_t *flist, void *node, size_t *size_key, haddr_t *addr_key)
+static herr_t
+H5HF_flist_add_bin_node(H5HF_freelist_t *flist, void *node, size_t *size_key, haddr_t *addr_key)
{
H5HF_flist_node_t *flist_node = NULL; /* Pointer to free list node of the correct size */
unsigned bin; /* Bin to put the free space section in */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_flist_add)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_flist_add_bin_node)
#ifdef QAK
HDfprintf(stderr, "%s: *size_key = %Zu, *addr_key = %a\n", FUNC, *size_key, *addr_key);
#endif /* QAK */
@@ -208,13 +219,83 @@ HDfprintf(stderr, "%s: *size_key = %Zu, *addr_key = %a\n", FUNC, *size_key, *add
done:
FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_flist_add_bin_node() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_flist_add
+ *
+ * Purpose: Add a section of free space in a direct block to the free list
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 7, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_flist_add(H5HF_freelist_t *flist, void *node, size_t *size_key, haddr_t *addr_key)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_flist_add)
+#ifdef QAK
+HDfprintf(stderr, "%s: *size_key = %Zu, *addr_key = %a\n", FUNC, *size_key, *addr_key);
+#endif /* QAK */
+
+ /* Check arguments. */
+ HDassert(flist);
+ HDassert(node);
+ HDassert(size_key);
+ HDassert(addr_key);
+
+ /* Check for special cases of # of sections on free list */
+ if(flist->sec_count == 0) {
+ HDassert(flist->single.node == NULL);
+
+ /* Capture single section's information */
+ flist->single.node = node;
+ flist->single.size_key = size_key;
+ flist->single.addr_key = addr_key;
+ } /* end if */
+ else {
+ /* Have a single section, put it into the bins */
+ if(flist->sec_count == 1) {
+ HDassert(flist->single.node);
+
+ /* Check if we should allocate the bins */
+ if(flist->bins == NULL)
+ /* Allocate the bins for free space sizes */
+ if(NULL == (flist->bins = H5FL_SEQ_CALLOC(H5SL_ptr_t, flist->nbins)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for free list bins")
+
+ /* Insert the current single section into the bins */
+ if(H5HF_flist_add_bin_node(flist, flist->single.node, flist->single.size_key, flist->single.addr_key) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't insert free list node into skip list")
+ flist->single.node = NULL;
+ } /* end if */
+ HDassert(flist->single.node == NULL);
+
+ /* Put new section into bins */
+ if(H5HF_flist_add_bin_node(flist, node, size_key, addr_key) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't insert free list node into skip list")
+ } /* end else */
+
+ /* Increment # of sections on free list */
+ flist->sec_count++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5HF_flist_add() */
/*-------------------------------------------------------------------------
- * Function: H5HF_flist_find
+ * Function: H5HF_flist_find_bin_node
*
- * Purpose: Locate a section of free space (in existing free list) that
+ * Purpose: Locate a section of free space (in existing free list bins) that
* is large enough to fulfill request.
*
* Return: Success: non-negative
@@ -222,18 +303,18 @@ done:
* Failure: negative
*
* Programmer: Quincey Koziol
- * Tuesday, March 7, 2006
+ * Monday, March 20, 2006
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5HF_flist_find(H5HF_freelist_t *flist, size_t request, void **node)
+static htri_t
+H5HF_flist_find_bin_node(H5HF_freelist_t *flist, size_t request, void **node)
{
H5HF_flist_node_t *flist_node; /* Free list size node */
unsigned bin; /* Bin to put the free space section in */
- herr_t ret_value = FALSE; /* Return value */
+ htri_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_flist_find)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_flist_find_bin_node)
/* Check arguments. */
HDassert(flist);
@@ -289,6 +370,64 @@ HDfprintf(stderr, "%s: bin = %u\n", FUNC, bin);
done:
FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_flist_find_bin_node() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_flist_find
+ *
+ * Purpose: Locate a section of free space (in existing free list) that
+ * is large enough to fulfill request.
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 7, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5HF_flist_find(H5HF_freelist_t *flist, size_t request, void **node)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_flist_find)
+
+ /* Check arguments. */
+ HDassert(flist);
+ HDassert(request > 0);
+ HDassert(node);
+
+ /* Check for any sections on free list */
+ if(flist->sec_count > 0) {
+ /* Check for single section */
+ if(flist->sec_count == 1) {
+ HDassert(flist->single.node);
+
+ /* See if single section is large enough */
+ if(*(flist->single.size_key) >= request) {
+ *node = flist->single.node;
+ flist->single.node = NULL;
+ ret_value = TRUE;
+ } /* end if */
+ } /* end if */
+ else {
+ HDassert(flist->single.node == NULL);
+
+ /* Look for node in bins */
+ if((ret_value = H5HF_flist_find_bin_node(flist, request, node)) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "can't remove section from bins")
+ } /* end else */
+
+ /* Decrement # of sections on free list */
+ flist->sec_count--;
+/* XXX: Should check for only one section in bins & convert to single section */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5HF_flist_find() */
@@ -349,15 +488,25 @@ H5HF_flist_free(H5HF_freelist_t *flist)
/* Check arguments. */
HDassert(flist);
- /* Clear out lists of nodes */
- for(u = 0; u < flist->nbins; u++)
- if(flist->bins[u]) {
- H5SL_destroy(flist->bins[u], H5HF_flist_node_free_cb, (void *)flist->node_free_op);
- flist->bins[u] = NULL;
- } /* end if */
+ /* Check for single section to free */
+ if(flist->sec_count == 1) {
+ HDassert(flist->single.node != NULL);
+ flist->node_free_op(flist->single.node, flist->single.addr_key, NULL);
+ flist->single.node = NULL;
+ } /* end if */
+ HDassert(flist->single.node == NULL);
/* Release bins for skip lists */
- H5FL_SEQ_FREE(H5SL_ptr_t, flist->bins);
+ if(flist->bins) {
+ /* Clear out lists of nodes */
+ for(u = 0; u < flist->nbins; u++)
+ if(flist->bins[u]) {
+ H5SL_destroy(flist->bins[u], H5HF_flist_node_free_cb, (void *)flist->node_free_op);
+ flist->bins[u] = NULL;
+ } /* end if */
+
+ H5FL_SEQ_FREE(H5SL_ptr_t, flist->bins);
+ } /* end if */
/* Free fractal heap free list info */
H5FL_FREE(H5HF_freelist_t, flist);
diff --git a/src/H5HFint.c b/src/H5HFint.c
index bbae6a2..e25ad64 100644
--- a/src/H5HFint.c
+++ b/src/H5HFint.c
@@ -98,7 +98,7 @@ static H5HF_indirect_t * H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t d
size_t min_dblock_size, haddr_t *addr_p, size_t *entry_p,
size_t *dblock_size);
static herr_t H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id,
- hsize_t block_off, unsigned nrows, unsigned max_dir_rows, haddr_t *addr_p);
+ hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p);
/*********************/
/* Package Variables */
@@ -119,11 +119,8 @@ H5FL_DEFINE(H5HF_section_free_node_t);
/* Declare a free list to manage the H5HF_indirect_t struct */
H5FL_DEFINE(H5HF_indirect_t);
-/* Declare a free list to manage the H5HF_indirect_dblock_ent_t sequence information */
-H5FL_SEQ_DEFINE(H5HF_indirect_dblock_ent_t);
-
-/* Declare a free list to manage the H5HF_indirect_iblock_ent_t sequence information */
-H5FL_SEQ_DEFINE(H5HF_indirect_iblock_ent_t);
+/* Declare a free list to manage the H5HF_indirect_ent_t sequence information */
+H5FL_SEQ_DEFINE(H5HF_indirect_ent_t);
/*****************************/
@@ -171,18 +168,18 @@ H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable)
/* Compute/cache some values */
dtable->first_row_bits = H5V_log2_of2(dtable->cparam.start_block_size) +
H5V_log2_of2(dtable->cparam.width);
- dtable->max_root_indirect_rows = (dtable->cparam.max_index - dtable->first_row_bits) + 1;
+ dtable->max_root_rows = (dtable->cparam.max_index - dtable->first_row_bits) + 1;
dtable->max_direct_rows = (H5V_log2_of2(dtable->cparam.max_direct_size) -
H5V_log2_of2(dtable->cparam.start_block_size)) + 2;
dtable->num_id_first_row = dtable->cparam.start_block_size * dtable->cparam.width;
dtable->max_dir_blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dtable->cparam.max_direct_size);
/* Build table of block sizes for each row */
- if(NULL == (dtable->row_block_size = H5MM_malloc(dtable->max_root_indirect_rows * sizeof(hsize_t))))
+ if(NULL == (dtable->row_block_size = H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table block size table")
tmp_block_size = dtable->cparam.start_block_size;
dtable->row_block_size[0] = dtable->cparam.start_block_size;
- for(u = 1; u < dtable->max_root_indirect_rows; u++) {
+ for(u = 1; u < dtable->max_root_rows; u++) {
dtable->row_block_size[u] = tmp_block_size;
tmp_block_size *= 2;
} /* end for */
@@ -266,6 +263,8 @@ H5HF_shared_alloc(H5F_t *f)
/* Set the internal parameters for the heap */
shared->f = f;
+ shared->sizeof_size = H5F_SIZEOF_SIZE(f);
+ shared->sizeof_addr = H5F_SIZEOF_ADDR(f);
/* Set the return value */
ret_value = shared;
@@ -338,17 +337,16 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_shared_create(H5F_t *f, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam)
+H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam)
{
- H5HF_shared_t *shared = NULL; /* Shared fractal heap information */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_create)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_init)
/*
* Check arguments.
*/
- HDassert(f);
+ HDassert(shared);
HDassert(fh);
HDassert(cparam);
@@ -363,14 +361,10 @@ H5HF_shared_create(H5F_t *f, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam)
HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two")
if(cparam->managed.max_direct_size < cparam->standalone_size)
HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not large enough to hold all managed blocks")
- if(cparam->managed.max_index > (8 * H5F_SIZEOF_SIZE(f)) || cparam->managed.max_index == 0)
+ if(cparam->managed.max_index > (8 * shared->sizeof_size) || cparam->managed.max_index == 0)
HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two")
#endif /* NDEBUG */
- /* Allocate & basic initialization for the shared info struct */
- if(NULL == (shared = H5HF_shared_alloc(f)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for shared heap info")
-
/* Set the creation parameters for the heap */
shared->heap_addr = fh_addr;
shared->addrmap = cparam->addrmap;
@@ -394,7 +388,7 @@ done:
H5HF_shared_free(shared);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_shared_create() */
+} /* end H5HF_shared_init() */
/*-------------------------------------------------------------------------
@@ -451,8 +445,9 @@ static herr_t
H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock)
{
H5HF_shared_t *shared; /* Pointer to shared heap info */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iblock_inc_loc)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_inc_loc)
/*
* Check arguments.
@@ -463,33 +458,44 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock)
shared = H5RC_GET_OBJ(iblock->shared);
HDassert(shared);
+ /* Increment block entry */
+ iblock->next_entry++;
+
/* Increment column */
- iblock->next_dir_col++;
+ iblock->next_col++;
/* Check for walking off end of column */
- if(iblock->next_dir_col == shared->man_dtable.cparam.width) {
+ if(iblock->next_col == shared->man_dtable.cparam.width) {
/* Reset column */
- iblock->next_dir_col = 0;
+ iblock->next_col = 0;
- /* Increment row & direct block size */
- iblock->next_dir_row++;
- iblock->next_dir_size *= 2;
+ /* Increment row & block size */
+ iblock->next_row++;
+ iblock->next_size *= 2;
- /* Check for filling up all direct block entries in indirect block */
- if(iblock->next_dir_row == iblock->max_direct_rows)
- iblock->dir_full = TRUE;
+ /* Check for filling up indirect block */
+ if(iblock->next_row == iblock->max_rows) {
+ /* Check for "full" heap */
+ if(iblock->parent == NULL)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location")
+
+ /* Increment location for parent indirect block */
+ iblock = H5RC_GET_OBJ(iblock->parent);
+ if(H5HF_man_iblock_inc_loc(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location")
+ } /* end if */
} /* end if */
#ifdef QAK
-HDfprintf(stderr, "%s: iblock->next_dir_row = %u\n", "H5HF_man_iblock_inc_loc", iblock->next_dir_row);
-HDfprintf(stderr, "%s: iblock->next_dir_col = %u\n", "H5HF_man_iblock_inc_loc", iblock->next_dir_col);
-HDfprintf(stderr, "%s: iblock->next_dir_size = %Zu\n", "H5HF_man_iblock_inc_loc", iblock->next_dir_size);
-HDfprintf(stderr, "%s: iblock->dir_full = %u\n", "H5HF_man_iblock_inc_loc", (unsigned)iblock->dir_full);
+HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row);
+HDfprintf(stderr, "%s: iblock->next_col = %u\n", FUNC, iblock->next_col);
+HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size);
#endif /* QAK */
/* Mark heap header as modified */
shared->dirty = TRUE;
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_iblock_inc_loc() */
@@ -851,7 +857,7 @@ HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt);
#ifdef QAK
HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_free", iblock->child_free_space);
#endif /* QAK */
- iblock->dblock_ents[dblock->parent_entry].free_space += amt;
+ iblock->ents[dblock->parent_entry].free_space += amt;
iblock->child_free_space += amt;
/* Mark indirect block as dirty */
@@ -867,7 +873,7 @@ HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_f
HDassert(iblock);
/* Adjust this indirect block's child free space */
- iblock->iblock_ents[parent_entry].free_space += amt;
+ iblock->ents[parent_entry].free_space += amt;
iblock->child_free_space += amt;
/* Mark indirect block as dirty */
@@ -988,14 +994,10 @@ HDfprintf(stderr, "%s: dblock_size = %Zu\n", FUNC, dblock_size);
#ifdef QAK
HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
-HDfprintf(stderr, "%s: shared->man_dtable.next_dir_block = %Hu\n", FUNC, shared->man_dtable.next_dir_block);
#endif /* QAK */
/* Point indirect block at new direct block */
- iblock->dblock_ents[dblock_entry].addr = dblock_addr;
-
- /* Increment size of next block from this indirect block */
- H5HF_man_iblock_inc_loc(iblock);
+ iblock->ents[dblock_entry].addr = dblock_addr;
/* Mark indirect block as modified */
iblock->dirty = TRUE;
@@ -1287,8 +1289,14 @@ done:
herr_t
H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj)
{
+ H5HF_parent_shared_t par_shared; /* Parent shared information */
H5HF_shared_t *shared; /* Pointer to shared heap info */
- unsigned row, col; /* Row & column for object's block */
+ H5HF_direct_t *dblock; /* Pointer to direct block to query */
+ size_t blk_off; /* Offset of object in block */
+ uint8_t *p; /* Temporary pointer to obj info in block */
+ size_t obj_size; /* Size of object */
+ haddr_t dblock_addr; /* Direct block address */
+ size_t dblock_size; /* Direct block size */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_read)
@@ -1306,52 +1314,125 @@ H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj)
/* Check for root direct block */
if(shared->man_dtable.curr_root_rows == 0) {
- H5HF_parent_shared_t par_shared; /* Parent shared information */
- H5HF_direct_t *dblock; /* Pointer to direct block to query */
- size_t blk_off; /* Offset of object in block */
- uint8_t *p; /* Temporary pointer to obj info in block */
- size_t obj_size; /* Size of object */
+ /* Set direct block info */
+ par_shared.shared = fh_shared;
+ par_shared.parent = NULL;
+ par_shared.parent_entry = 0;
+ par_shared.parent_free_space = shared->total_man_free;
+
+ dblock_addr = shared->man_dtable.table_addr;
+ dblock_size = shared->man_dtable.cparam.start_block_size;
+
+ /* Lock direct block */
+ if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block")
+ } /* end if */
+ else {
+ haddr_t iblock_addr; /* Indirect block's address */
+ H5HF_indirect_t *iblock; /* Pointer to indirect block */
+ unsigned row, col; /* Row & column for object's block */
+ size_t entry; /* Entry of block */
-#ifdef QAK
/* Look up row & column for object */
if(H5HF_dtable_lookup(&shared->man_dtable, obj_off, &row, &col) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
+#ifdef QAK
HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
#endif /* QAK */
- /* Lock first (root) direct block */
+ /* Set initial indirect block info */
+ iblock_addr = shared->man_dtable.table_addr;
+
+ /* Lock indirect block */
par_shared.shared = fh_shared;
par_shared.parent = NULL;
par_shared.parent_entry = 0;
par_shared.parent_free_space = shared->total_man_free;
- if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.cparam.start_block_size, &par_shared, H5AC_READ)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block")
+ if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
- /* Compute offset of object within block */
- HDassert((obj_off - dblock->block_off) < (hsize_t)shared->man_dtable.cparam.start_block_size);
- blk_off = (size_t)(obj_off - dblock->block_off);
+ /* Check for indirect block row */
+ while(row >= shared->man_dtable.max_direct_rows) {
+ haddr_t new_iblock_addr; /* New indirect block's address */
+ H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */
+ unsigned nrows; /* Number of rows in new indirect block */
- /* Point to location for object */
- p = dblock->blk + blk_off;
+ /* Compute # of rows in child indirect block */
+ nrows = (H5V_log2_gen(shared->man_dtable.row_block_size[row]) - shared->man_dtable.first_row_bits) + 1;
- /* Decode the length */
- UINT64DECODE_VAR(p, obj_size, dblock->blk_off_size);
+ /* Compute indirect block's entry */
+ entry = (row * shared->man_dtable.cparam.width) + col;
- /* Skip over the free fragment size & ref count */
- p += 1 + (shared->ref_count_obj ? shared->ref_count_size : 0);
+ /* Locate child indirect block */
+ new_iblock_addr = iblock->ents[entry].addr;
- /* Copy the object's data into the heap */
- HDmemcpy(obj, p, obj_size);
+ /* Lock new indirect block */
+ par_shared.shared = fh_shared;
+ par_shared.parent = iblock->self;
+ par_shared.parent_entry = entry;
+ par_shared.parent_free_space = iblock->ents[entry].free_space;
+ if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
+
+ /* Release the current indirect block (possibly marked as dirty) */
+ if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
+
+ /* Switch variables to use new indirect block */
+ iblock = new_iblock;
+ iblock_addr = new_iblock_addr;
+
+ /* Look up row & column in new indirect block for object */
+ if(H5HF_dtable_lookup(&shared->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
+ } /* end while */
- /* Unlock first (root) direct block */
- if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap direct block")
- dblock = NULL;
- } /* end if */
- else {
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "root indirect blocks not supported yet")
+ /* Compute direct block's entry */
+ entry = (row * shared->man_dtable.cparam.width) + col;
+#ifdef QAK
+HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->dblock_ents[entry].addr);
+#endif /* QAK */
+
+ /* Set direct block info */
+ par_shared.shared = fh_shared;
+ par_shared.parent = iblock->self;
+ par_shared.parent_entry = entry;
+ par_shared.parent_free_space = iblock->ents[entry].free_space;
+
+ dblock_addr = iblock->ents[entry].addr;
+ dblock_size = shared->man_dtable.row_block_size[row];
+
+ /* Lock direct block */
+ if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block")
+
+ /* Unlock indirect block */
+ if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
+ iblock = NULL;
} /* end else */
+ /* Compute offset of object within block */
+ HDassert((obj_off - dblock->block_off) < (hsize_t)dblock_size);
+ blk_off = (size_t)(obj_off - dblock->block_off);
+
+ /* Point to location for object */
+ p = dblock->blk + blk_off;
+
+ /* Decode the length */
+ UINT64DECODE_VAR(p, obj_size, dblock->blk_off_size);
+
+ /* Skip over the free fragment size & ref count */
+ p += 1 + (shared->ref_count_obj ? shared->ref_count_size : 0);
+
+ /* Copy the object's data into the heap */
+ HDmemcpy(obj, p, obj_size);
+
+ /* Unlock direct block */
+ if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
+ dblock = NULL;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_read() */
@@ -1390,10 +1471,8 @@ HDfprintf(stderr, "%s: Freeing indirect block\n", "H5HF_iblock_free");
H5RC_DEC(iblock->parent);
/* Release entry tables */
- if(iblock->dblock_ents)
- H5FL_SEQ_FREE(H5HF_indirect_dblock_ent_t, iblock->dblock_ents);
- if(iblock->iblock_ents)
- H5FL_SEQ_FREE(H5HF_indirect_iblock_ent_t, iblock->iblock_ents);
+ if(iblock->ents)
+ H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents);
/* Free fractal heap indirect block info */
H5FL_FREE(H5HF_indirect_t, iblock);
@@ -1425,6 +1504,7 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id,
H5HF_parent_shared_t par_shared; /* Parent shared information */
H5HF_shared_t *shared; /* Pointer to shared heap info */
H5HF_indirect_t *iblock; /* Pointer to indirect block */
+ haddr_t iblock_addr; /* Indirect block's address */
H5HF_indirect_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_place_dblock)
@@ -1445,26 +1525,20 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id,
H5HF_direct_t *dblock; /* Pointer to direct block to query */
unsigned nrows; /* Number of rows for root indirect block */
- /* Check for skipping over blocks */
- if(min_dblock_size != shared->man_dtable.cparam.start_block_size) {
-HDfprintf(stderr, "%s: Skipping direct block sizes not supported\n", FUNC);
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "skipping direct block sizes not supported yet")
- } /* end if */
-
#ifdef QAK
HDfprintf(stderr, "%s: creating first indirect block\n", FUNC);
#endif /* QAK */
/* Check for allocating entire root indirect block initially */
if(shared->man_dtable.cparam.start_root_rows == 0)
- nrows = shared->man_dtable.max_root_indirect_rows;
+ nrows = shared->man_dtable.max_root_rows;
else
nrows = shared->man_dtable.cparam.start_root_rows;
/* Allocate root indirect block */
- if(H5HF_man_iblock_create(fh_shared, dxpl_id, (hsize_t)0, nrows, shared->man_dtable.max_direct_rows, addr_p) < 0)
+ if(H5HF_man_iblock_create(fh_shared, dxpl_id, (hsize_t)0, nrows, shared->man_dtable.max_root_rows, &iblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block")
#ifdef QAK
-HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p);
+HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
#endif /* QAK */
/* Move current direct block (used as root) into new indirect block */
@@ -1474,7 +1548,7 @@ HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p);
par_shared.parent = NULL;
par_shared.parent_entry = 0;
par_shared.parent_free_space = 0;
- if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, &nrows, &par_shared, H5AC_WRITE)))
+ if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &nrows, &par_shared, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
/* Lock first (root) direct block */
@@ -1483,8 +1557,8 @@ HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p);
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block")
/* Point indirect block at direct block to add */
- iblock->dblock_ents[0].addr = shared->man_dtable.table_addr;
- iblock->dblock_ents[0].free_space = dblock->blk_free_space;
+ iblock->ents[0].addr = shared->man_dtable.table_addr;
+ iblock->ents[0].free_space = dblock->blk_free_space;
iblock->child_free_space += dblock->blk_free_space;
/* Make direct block share parent indirect block */
@@ -1499,23 +1573,18 @@ HDfprintf(stderr, "%s: *addr_p = %a\n", FUNC, *addr_p);
/* Increment size of next block from this indirect block */
/* (account for the already existing direct block */
- H5HF_man_iblock_inc_loc(iblock);
+ if(H5HF_man_iblock_inc_loc(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location")
/* Mark indirect block as modified */
iblock->dirty = TRUE;
/* Point heap header at new indirect block */
shared->man_dtable.curr_root_rows = nrows;
- shared->man_dtable.table_addr = *addr_p;
+ shared->man_dtable.table_addr = iblock_addr;
/* Mark heap header as modified */
shared->dirty = TRUE;
-
- /* Set entry for direct block */
- *entry_p = 1;
-
- /* Set size of direct block to create */
- *dblock_size = iblock->next_dir_size;
} /* end if */
else {
#ifdef QAK
@@ -1527,62 +1596,44 @@ HDfprintf(stderr, "%s: searching root indirect block\n", FUNC);
par_shared.parent = NULL;
par_shared.parent_entry = 0;
par_shared.parent_free_space = shared->total_man_free;
- if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE)))
+ iblock_addr = shared->man_dtable.table_addr;
+ if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
#ifdef QAK
-HDfprintf(stderr, "%s: iblock->next_dir_row = %u\n", FUNC, iblock->next_dir_row);
-HDfprintf(stderr, "%s: iblock->next_dir_col = %u\n", FUNC, iblock->next_dir_col);
-HDfprintf(stderr, "%s: iblock->next_dir_size = %Zu\n", FUNC, iblock->next_dir_size);
-HDfprintf(stderr, "%s: iblock->dir_full = %u\n", FUNC, (unsigned)iblock->dir_full);
+HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
#endif /* QAK */
- /* Check for full direct block entries in root */
- if(iblock->dir_full) {
-HDfprintf(stderr, "%s: Adding nested indirect block to heap not supported\n", FUNC);
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "Adding nested indirect block not supported yet")
- } /* end if */
-
- /* Check for skipping over blocks */
- if(min_dblock_size > iblock->next_dir_size) {
-HDfprintf(stderr, "%s: Skipping direct block sizes not supported\n", FUNC);
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "skipping direct block sizes not supported yet")
- } /* end if */
-
- /* Check if we need a direct block past current allocation */
- if(iblock->next_dir_row == iblock->ndir_rows) {
- haddr_t old_addr; /* Old address of indirect block */
+ /* Check if we need a block past current allocation */
+ if(iblock->next_row == iblock->nrows) {
haddr_t new_addr; /* New address of indirect block */
unsigned new_nrows; /* New # of direct rows */
size_t u; /* Local index variable */
/* Check for special case of second row, which has blocks the same size as first row */
- if(iblock->next_dir_row == 1)
- iblock->next_dir_size = shared->man_dtable.cparam.start_block_size;
+ if(iblock->next_row == 1)
+ iblock->next_size = shared->man_dtable.cparam.start_block_size;
/* Compute new # of rows in indirect block */
- new_nrows = 2 * iblock->ndir_rows;
- if(new_nrows > iblock->max_direct_rows)
- new_nrows = iblock->max_direct_rows;
+ new_nrows = MIN(2 * iblock->nrows, iblock->max_rows);
#ifdef QAK
HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows);
#endif /* QAK */
/* Currently, the old chunk data is "thrown away" after the space is reallocated,
- * so avoid data copy in H5MF_realloc() call by just free'ing the space and
- * allocating new space.
- *
- * This should keep the file smaller also, by freeing the space and then
- * allocating new space, instead of vice versa (in H5MF_realloc).
- *
- * QAK - 3/14/2006
- */
+* so avoid data copy in H5MF_realloc() call by just free'ing the space and
+* allocating new space.
+*
+* This should keep the file smaller also, by freeing the space and then
+* allocating new space, instead of vice versa (in H5MF_realloc).
+*
+* QAK - 3/14/2006
+*/
/* Free previous indirect block disk space */
- old_addr = shared->man_dtable.table_addr;
- if(H5MF_xfree(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, old_addr, (hsize_t)iblock->size)<0)
+ if(H5MF_xfree(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock_addr, (hsize_t)iblock->size)<0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, NULL, "unable to free fractal heap indirect block")
/* Compute size of buffer needed for new indirect block */
- iblock->ndir_rows = new_nrows;
+ iblock->nrows = new_nrows;
iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock);
/* Allocate space for the new indirect block on disk */
@@ -1590,31 +1641,31 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows);
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, NULL, "file allocation failed for fractal heap indirect block")
/* Re-allocate direct block entry table */
- if(NULL == (iblock->dblock_ents = H5FL_SEQ_REALLOC(H5HF_indirect_dblock_ent_t, iblock->dblock_ents, (iblock->ndir_rows * shared->man_dtable.cparam.width))))
+ if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * shared->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries")
/* Initialize new direct block entries */
- for(u = (iblock->next_dir_row * shared->man_dtable.cparam.width);
- u < (iblock->ndir_rows * shared->man_dtable.cparam.width);
+ for(u = (iblock->next_row * shared->man_dtable.cparam.width);
+ u < (iblock->nrows * shared->man_dtable.cparam.width);
u++) {
- iblock->dblock_ents[u].addr = HADDR_UNDEF;
- iblock->dblock_ents[u].free_space = 0;
+ iblock->ents[u].addr = HADDR_UNDEF;
+ iblock->ents[u].free_space = 0;
} /* end for */
/* Mark indirect block as dirty */
iblock->dirty = TRUE;
/* Release the indirect block (marked as dirty) */
- if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, old_addr, iblock, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block")
/* Move object in cache */
- if(H5AC_rename(shared->f, H5AC_FHEAP_IBLOCK, old_addr, new_addr) < 0)
+ if(H5AC_rename(shared->f, H5AC_FHEAP_IBLOCK, iblock_addr, new_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, NULL, "unable to move fractal heap root indirect block")
/* Update other shared header info */
shared->man_dtable.curr_root_rows = new_nrows;
- shared->man_dtable.table_addr = new_addr;
+ shared->man_dtable.table_addr = iblock_addr = new_addr;
/* Mark heap header as modified */
shared->dirty = TRUE;
@@ -1624,20 +1675,113 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows);
par_shared.parent = NULL;
par_shared.parent_entry = 0;
par_shared.parent_free_space = shared->total_man_free;
- if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE)))
+ if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
} /* end if */
- /* Set address of indirect block */
- *addr_p = shared->man_dtable.table_addr;
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row);
+HDfprintf(stderr, "%s: iblock->next_col = %u\n", FUNC, iblock->next_col);
+HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size);
+HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry);
+#endif /* QAK */
+ /* Check for full direct block entries in current indirect block */
+ while(iblock->next_row >= shared->man_dtable.max_direct_rows) {
+ haddr_t new_iblock_addr; /* New indirect block's address */
+ H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */
+ unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for header */
+ unsigned nrows; /* Number of rows in new indirect block */
+
+ /* Compute # of rows in child indirect block */
+ nrows = (H5V_log2_gen(iblock->next_size) - shared->man_dtable.first_row_bits) + 1;
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->next_size, nrows);
+#endif /* QAK */
+
+ /* Check for allocating new indirect block */
+ if(!H5F_addr_defined(iblock->ents[iblock->next_entry].addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Allocating new indirect block\n", FUNC);
+#endif /* QAK */
+ /* Allocate new indirect block */
+ if(H5HF_man_iblock_create(fh_shared, dxpl_id, shared->man_dtable.next_dir_block, nrows, nrows, &new_iblock_addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block")
+
+ /* Lock new indirect block */
+ par_shared.shared = fh_shared;
+ par_shared.parent = iblock->self;
+ par_shared.parent_entry = iblock->next_entry;
+ par_shared.parent_free_space = 0;
+ if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
+#ifdef QAK
+HDfprintf(stderr, "%s: new_iblock->next_row = %u\n", FUNC, new_iblock->next_row);
+HDfprintf(stderr, "%s: new_iblock->next_col = %u\n", FUNC, new_iblock->next_col);
+HDfprintf(stderr, "%s: new_iblock->next_size = %Zu\n", FUNC, new_iblock->next_size);
+HDfprintf(stderr, "%s: new_iblock->next_entry = %u\n", FUNC, new_iblock->next_entry);
+#endif /* QAK */
+
+ /* Point current indirect block at new indirect block */
+ iblock->ents[iblock->next_entry].addr = new_iblock_addr;
- /* Set entry for direct block */
- *entry_p = iblock->next_dir_entry;
+ /* Increment location of next block from current indirect block */
+ if(H5HF_man_iblock_inc_loc(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location")
- /* Set size of direct block to create */
- *dblock_size = iblock->next_dir_size;
+ /* Mark current indirect block as modified */
+ iblock->dirty = TRUE;
+
+ /* Release the current indirect block (marked as dirty) */
+ hdr_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+ else {
+#ifdef QAK
+HDfprintf(stderr, "%s: Descending existing indirect block\n", FUNC);
+#endif /* QAK */
+ /* Locate child indirect block */
+ new_iblock_addr = iblock->ents[iblock->next_entry].addr;
+
+ /* Lock new indirect block */
+ par_shared.shared = fh_shared;
+ par_shared.parent = iblock->self;
+ par_shared.parent_entry = iblock->next_entry;
+ par_shared.parent_free_space = iblock->ents[iblock->next_entry].free_space;
+ if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
+ } /* end else */
+
+ /* Release the current indirect block (possibly marked as dirty) */
+ if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, hdr_flags) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block")
+
+ /* Switch variables to use new indirect block */
+ iblock = new_iblock;
+ iblock_addr = new_iblock_addr;
+#ifdef QAK
+HDfprintf(stderr, "%s: new_iblock_addr = %a\n", FUNC, new_iblock_addr);
+#endif /* QAK */
+ } /* end while */
} /* end else */
+ /* Check for skipping over blocks */
+ if(min_dblock_size > iblock->next_size) {
+HDfprintf(stderr, "%s: Skipping direct block sizes not supported\n", FUNC);
+HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "skipping direct block sizes not supported yet")
+ } /* end if */
+
+ /* Set address of indirect block that's the immediate parent of new direct block */
+ *addr_p = iblock_addr;
+
+ /* Set entry for new direct block to use */
+ *entry_p = iblock->next_entry;
+
+ /* Set size of direct block to create */
+ *dblock_size = iblock->next_size;
+
+ /* Increment location of next block from this indirect block */
+ if(H5HF_man_iblock_inc_loc(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location")
+
/* Set return value */
ret_value = iblock;
@@ -1661,7 +1805,7 @@ done:
*/
static herr_t
H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id,
- hsize_t block_off, unsigned nrows, unsigned max_dir_rows, haddr_t *addr_p)
+ hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p)
{
H5HF_shared_t *shared; /* Pointer to shared heap info */
H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */
@@ -1699,7 +1843,7 @@ H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for indirect fractal heap block")
#ifdef QAK
-HDfprintf(stderr, "%s: nrows = %u\n", FUNC, nrows);
+HDfprintf(stderr, "%s: nrows = %u, max_nrows = %u\n", FUNC, nrows, max_nrows);
#endif /* QAK */
/* Set info for direct block */
iblock->parent = NULL; /* Temporary, except for root indirect block */
@@ -1707,41 +1851,24 @@ HDfprintf(stderr, "%s: nrows = %u\n", FUNC, nrows);
iblock->block_off = block_off;
iblock->child_free_space = 0;
iblock->nrows = nrows;
- iblock->dir_full = FALSE;
- iblock->next_dir_col = 0;
- iblock->next_dir_row = 0;
- iblock->next_dir_entry = 0;
- iblock->next_dir_size = shared->man_dtable.cparam.start_block_size;
- iblock->max_direct_rows = max_dir_rows;
- if(iblock->nrows > shared->man_dtable.max_direct_rows) {
- iblock->ndir_rows = shared->man_dtable.max_direct_rows;
- iblock->nindir_rows = iblock->nrows - iblock->ndir_rows;
- } /* end if */
- else {
- iblock->ndir_rows = iblock->nrows;
- iblock->nindir_rows = 0;
- } /* end else */
+ iblock->max_rows = max_rows;
+ iblock->next_col = 0;
+ iblock->next_row = 0;
+ iblock->next_entry = 0;
+ iblock->next_size = shared->man_dtable.cparam.start_block_size;
/* Compute size of buffer needed for indirect block */
iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock);
/* Allocate indirect block entry tables */
- if(NULL == (iblock->dblock_ents = H5FL_SEQ_MALLOC(H5HF_indirect_dblock_ent_t, (iblock->ndir_rows * shared->man_dtable.cparam.width))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct entries")
- if(iblock->nindir_rows > 0) {
- if(NULL == (iblock->iblock_ents = H5FL_SEQ_MALLOC(H5HF_indirect_iblock_ent_t, (iblock->nindir_rows * shared->man_dtable.cparam.width))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for indirect entries")
- } /* end if */
- else
- iblock->iblock_ents = NULL;
+ if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * shared->man_dtable.cparam.width))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries")
/* Initialize indirect block entry tables */
- for(u = 0; u < (iblock->ndir_rows * shared->man_dtable.cparam.width); u++) {
- iblock->dblock_ents[u].addr = HADDR_UNDEF;
- iblock->dblock_ents[u].free_space = 0;
+ for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) {
+ iblock->ents[u].addr = HADDR_UNDEF;
+ iblock->ents[u].free_space = 0;
} /* end for */
- for(u = 0; u < (iblock->nindir_rows * shared->man_dtable.cparam.width); u++)
- iblock->iblock_ents[u].addr = HADDR_UNDEF;
/* Allocate space for the indirect block on disk */
if(HADDR_UNDEF == (*addr_p = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
@@ -1751,7 +1878,6 @@ HDfprintf(stderr, "%s: nrows = %u\n", FUNC, nrows);
#ifdef LATER
/* Update shared heap info */
shared->total_man_free += dblock->blk_free_space;
- shared->man_dtable.next_dir_block += dblock->size;
shared->total_size += dblock->size;
shared->man_size += dblock->size;
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 33a9d37..175b521 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -57,19 +57,19 @@
)
/* Size of doubling-table information */
-#define H5HF_DTABLE_INFO_SIZE(f) ( \
+#define H5HF_DTABLE_INFO_SIZE(s) ( \
2 /* Width of table (i.e. # of columns) */ \
- + H5F_SIZEOF_SIZE(f) /* Starting block size */ \
- + H5F_SIZEOF_SIZE(f) /* Maximum direct block size */ \
+ + (s)->sizeof_size /* Starting block size */ \
+ + (s)->sizeof_size /* Maximum direct block size */ \
+ 2 /* Max. size of heap (log2 of actual value - i.e. the # of bits) */ \
+ 2 /* Starting # of rows in root indirect block */ \
- + H5F_SIZEOF_ADDR(f) /* File address of table managed */ \
+ + (s)->sizeof_addr /* File address of table managed */ \
+ 2 /* Current # of rows in root indirect block */ \
- + H5F_SIZEOF_SIZE(f) /* Next direct block's heap offset */ \
+ + (s)->sizeof_size /* Next direct block's heap offset */ \
)
/* Size of the fractal heap header on disk */
-#define H5HF_HEADER_SIZE(f) ( \
+#define H5HF_HEADER_SIZE(s) ( \
/* General metadata fields */ \
H5HF_METADATA_PREFIX_SIZE \
\
@@ -77,13 +77,13 @@
+ 1 /* Address mapping */ \
+ 4 /* Min. size of standalone object */ \
+ 1 /* Size of ref. count for objects */ \
- + H5F_SIZEOF_SIZE(f) /* Total man. free space */ \
- + H5F_SIZEOF_SIZE(f) /* Total std. free entries */ \
- + H5F_SIZEOF_SIZE(f) /* Total size of heap */ \
- + H5F_SIZEOF_SIZE(f) /* Size of man. space in heap */ \
- + H5F_SIZEOF_SIZE(f) /* Size of std. space in heap */ \
- + H5F_SIZEOF_SIZE(f) /* Number of objects in heap */ \
- + H5HF_DTABLE_INFO_SIZE(f) /* Size of managed obj. doubling-table info */ \
+ + (s)->sizeof_size /* Total man. free space */ \
+ + (s)->sizeof_size /* Total std. free entries */ \
+ + (s)->sizeof_size /* Total size of heap */ \
+ + (s)->sizeof_size /* Size of man. space in heap */ \
+ + (s)->sizeof_size /* Size of std. space in heap */ \
+ + (s)->sizeof_size /* Number of objects in heap */ \
+ + H5HF_DTABLE_INFO_SIZE(s) /* Size of managed obj. doubling-table info */ \
)
/* Size of free space description in an absolute managed direct block */
@@ -107,7 +107,7 @@
H5HF_METADATA_PREFIX_SIZE \
\
/* Fractal heap managed, absolutely mapped direct block specific fields */ \
- + H5F_SIZEOF_ADDR((s)->f) /* File address of heap owning the block */ \
+ + (s)->sizeof_addr /* File address of heap owning the block */ \
+ (s)->heap_off_size /* Offset of the block in the heap */ \
+ H5HF_SIZEOF_OFFSET_LEN(o) /* Total free space in a block */ \
+ H5HF_SIZEOF_OFFSET_LEN(o) /* Offset of first descriptor in free list */ \
@@ -117,7 +117,7 @@
H5HF_METADATA_PREFIX_SIZE \
\
/* Fractal heap managed, absolutely mapped direct block specific fields */ \
- + H5F_SIZEOF_ADDR((s)->f) /* File address of heap owning the block */ \
+ + (s)->sizeof_addr /* File address of heap owning the block */ \
+ (s)->heap_off_size /* Offset of the block in the heap */ \
+ (d)->blk_off_size /* Offset of first descriptor in free list */ \
)
@@ -128,10 +128,11 @@
H5HF_METADATA_PREFIX_SIZE \
\
/* Fractal heap managed, absolutely mapped indirect block specific fields */ \
- + H5F_SIZEOF_ADDR((s)->f) /* File address of heap owning the block */ \
+ + (s)->sizeof_addr /* File address of heap owning the block */ \
+ (s)->heap_off_size /* Offset of the block in the heap */ \
- + ((i)->ndir_rows * (s)->man_dtable.cparam.width * (H5F_SIZEOF_ADDR((s)->f) + (s)->man_dtable.max_dir_blk_off_size)) /* Size of entries for direct blocks */ \
- + ((i)->nindir_rows * (s)->man_dtable.cparam.width * (H5F_SIZEOF_ADDR((s)->f) + (s)->heap_off_size)) /* Size of entries for indirect blocks */ \
+ + 4 /* Next block entry to allocate from */ \
+ + (MIN((i)->nrows, (s)->man_dtable.max_direct_rows) * (s)->man_dtable.cparam.width * ((s)->sizeof_addr + (s)->man_dtable.max_dir_blk_off_size)) /* Size of entries for direct blocks */ \
+ + ((((i)->nrows > (s)->man_dtable.max_direct_rows) ? ((i)->nrows - (s)->man_dtable.max_direct_rows) : 0) * (s)->man_dtable.cparam.width * ((s)->sizeof_addr + (s)->heap_off_size)) /* Size of entries for indirect blocks */ \
)
@@ -160,7 +161,7 @@ typedef struct H5HF_dtable_t {
hsize_t next_dir_block; /* Offset of next direct managed block */
/* Computed information (not stored) */
- unsigned max_root_indirect_rows; /* Maximum # of rows in root indirect block */
+ unsigned max_root_rows; /* Maximum # of rows in root indirect block */
unsigned max_direct_rows; /* Maximum # of direct rows in any indirect block */
unsigned max_dir_blk_off_size; /* Max. size of offsets in direct blocks */
unsigned first_row_bits; /* # of bits in address of first row */
@@ -192,6 +193,8 @@ typedef struct H5HF_shared_t {
hbool_t dirty; /* Shared info is modified */
haddr_t heap_addr; /* Address of heap header in the file */
H5F_t *f; /* Pointer to file for heap */
+ size_t sizeof_size; /* Size of file sizes */
+ size_t sizeof_addr; /* Size of file addresses */
H5HF_freelist_t *flist; /* Free list for objects in heap */
/* Doubling table information */
@@ -256,18 +259,12 @@ typedef struct H5HF_direct_t {
size_t free_list_head; /* Offset of head of free list in block */
} H5HF_direct_t;
-/* Indirect block direct block entry */
-typedef struct H5HF_indirect_dblock_ent_t {
+/* Indirect block entry */
+typedef struct H5HF_indirect_ent_t {
haddr_t addr; /* Direct block's address */
- size_t free_space; /* Amount of free space in direct block */
+ hsize_t free_space; /* Amount of free space in block pointed to */
/* XXX: Will need space for block size, for blocks with I/O filters */
-} H5HF_indirect_dblock_ent_t;
-
-/* Indirect block indirect block entry */
-typedef struct H5HF_indirect_iblock_ent_t {
- haddr_t addr; /* Indirect block's address */
- hsize_t free_space; /* Amount of free space in indirect block child */
-} H5HF_indirect_iblock_ent_t;
+} H5HF_indirect_ent_t;
/* Fractal heap indirect block */
typedef struct H5HF_indirect_t {
@@ -281,17 +278,13 @@ typedef struct H5HF_indirect_t {
size_t parent_entry; /* Entry in parent's table */
H5RC_t *self; /* Ref-counted shared 'self' block info */
unsigned nrows; /* Total # of rows in indirect block */
- unsigned ndir_rows; /* # of direct rows in indirect block */
- unsigned nindir_rows; /* # of indirect rows in indirect block */
+ unsigned max_rows; /* Max. # of rows in indirect block */
size_t size; /* Size of indirect block on disk */
- hbool_t dir_full; /* Flag to indicate that all direct blocks are allocated */
- unsigned next_dir_col; /* "Column" of next managed direct block (in doubling table) */
- unsigned next_dir_row; /* "Row" of next managed direct block (in doubling table) */
- unsigned next_dir_entry; /* Entry of next managed direct block */
- size_t next_dir_size; /* Size of next managed direct block */
- unsigned max_direct_rows; /* Maximum # of direct rows in indirect block */
- H5HF_indirect_dblock_ent_t *dblock_ents; /* Pointer to direct block entry table */
- H5HF_indirect_iblock_ent_t *iblock_ents; /* Pointer to indirect block entry table */
+ unsigned next_col; /* "Column" of next managed block (in doubling table) */
+ unsigned next_row; /* "Row" of next managed block (in doubling table) */
+ unsigned next_entry; /* Entry of next managed block */
+ hsize_t next_size; /* Size of next managed block */
+ H5HF_indirect_ent_t *ents; /* Pointer to block entry table */
/* Stored values */
hsize_t block_off; /* Offset of the block within the heap's address space */
@@ -347,11 +340,8 @@ H5FL_BLK_EXTERN(direct_block);
/* Declare a free list to manage the H5HF_indirect_t struct */
H5FL_EXTERN(H5HF_indirect_t);
-/* Declare a free list to manage the H5HF_indirect_dblock_ent_t sequence information */
-H5FL_SEQ_EXTERN(H5HF_indirect_dblock_ent_t);
-
-/* Declare a free list to manage the H5HF_indirect_iblock_ent_t sequence information */
-H5FL_SEQ_EXTERN(H5HF_indirect_iblock_ent_t);
+/* Declare a free list to manage the H5HF_indirect_ent_t sequence information */
+H5FL_SEQ_EXTERN(H5HF_indirect_ent_t);
/******************************/
@@ -360,7 +350,7 @@ H5FL_SEQ_EXTERN(H5HF_indirect_iblock_ent_t);
/* Routines for managing shared fractal heap info */
H5_DLL H5HF_shared_t * H5HF_shared_alloc(H5F_t *f);
-H5_DLL herr_t H5HF_shared_create(H5F_t *f, H5HF_t *fh, haddr_t heap_addr, H5HF_create_t *cparam);
+H5_DLL herr_t H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t heap_addr, H5HF_create_t *cparam);
H5_DLL herr_t H5HF_shared_own(H5HF_t *fh, H5HF_shared_t *shared);
/* Indirect block routines */
diff --git a/src/H5private.h b/src/H5private.h
index a67a6aa..8a10783 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -1192,12 +1192,23 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
#endif /* H5_INTERFACE_INIT_FUNC */
+#ifndef NDEBUG
#define FUNC_ENTER_COMMON_NOFUNC(func_name,asrt) \
- /* Check API status */ \
- assert(asrt); \
+ static hbool_t func_check = FALSE; \
+ \
+ if(!func_check) { \
+ /* Check API status */ \
+ HDassert(asrt); \
+ \
+ /* Check function name */ \
+ H5_CHECK_FUNCNAME(func_name); \
\
- /* Check function name */ \
- H5_CHECK_FUNCNAME(func_name);
+ /* Don't check again */ \
+ func_check = TRUE; \
+ } /* end if */
+#else /* NDEBUG */
+#define FUNC_ENTER_COMMON_NOFUNC(func_name,asrt)
+#endif /* NDEBUG */
#define FUNC_ENTER_COMMON(func_name,asrt) \
static const char FUNC[]=#func_name; \
diff --git a/test/fheap.c b/test/fheap.c
index 00dca95..6ae7830 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -27,6 +27,7 @@
/* Other private headers that this test requires */
#include "H5Iprivate.h"
+#include "H5MMprivate.h" /* Memory management */
/* "Standard" creation table parameters */
#define STD_ADDRMAP H5HF_ABSOLUTE /* Heap address mapping */
@@ -106,7 +107,6 @@ check_stats(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t total_size,
H5HF_stat_t heap_stats; /* Statistics about the heap */
/* Get statistics for heap and verify they are correct */
- HDmemset(&heap_stats, 0, sizeof(H5HF_stat_t));
if(H5HF_stat_info(f, dxpl, fh_addr, &heap_stats) < 0)
FAIL_STACK_ERROR
if(heap_stats.total_size != total_size) {
@@ -155,13 +155,33 @@ error:
*/
static int
fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size,
- unsigned start_nobjs, unsigned *nobjs_ptr)
+ size_t block_size, unsigned start_nobjs, unsigned *nobjs_ptr)
{
H5HF_stat_t heap_stats; /* Statistics about the heap */
hsize_t heap_id; /* Heap ID for object inserted */
- unsigned char obj[10]; /* Buffer for first object to insert */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
unsigned nobjs = 0; /* Number of objects inserted */
- unsigned u; /* Local index variable */
+ unsigned alloc_ids = 0; /* # of heap IDs allocated in array */
+ hsize_t *ids = NULL; /* Array of heap IDs */
+ size_t data_size; /* Size of data portion of heap block */
+ size_t obj_overhead; /* Size of overhead for each object */
+ size_t free_overhead; /* Size of free space overhead for each object */
+ unsigned free_frag_size; /* Size of free space fragment */
+ size_t last_obj_len; /* Size of last object inserted into heap */
+ unsigned u, v; /* Local index variable */
+
+ /* Initialize variables */
+ if(block_size <= (64 * 1024)) {
+ data_size = block_size - 28; /* '28' is the size of the direct block's overhead */
+ obj_overhead = 3;
+ free_overhead = 4;
+ } /* end if */
+ else {
+ data_size = block_size - 29; /* '29' is the size of the direct block's overhead */
+ obj_overhead = 4; /* Will handle blocks up to 2^24 */
+ free_overhead = 6;
+ } /* end else */
/* Initialize object buffer */
for(u = 0; u < sizeof(obj); u++)
@@ -175,17 +195,24 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size,
/* Increment object count */
nobjs++;
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)(996 - (nobjs * (sizeof(obj) + 3))), (hsize_t)(start_nobjs + nobjs)))
+ /* Check for needing to increase size of heap ID array */
+ if(nobjs > alloc_ids) {
+ alloc_ids = MAX(1024, (alloc_ids * 2));
+ if(NULL == (ids = H5MM_realloc(ids, sizeof(hsize_t) * alloc_ids)))
+ FAIL_STACK_ERROR
+ } /* end if */
+ ids[nobjs - 1] = heap_id;
+
+ if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)(data_size - (nobjs * (sizeof(obj) + obj_overhead))), (hsize_t)(start_nobjs + nobjs)))
FAIL_STACK_ERROR
/* Get statistics for heap */
- HDmemset(&heap_stats, 0, sizeof(H5HF_stat_t));
if(H5HF_stat_info(f, dxpl, fh_addr, &heap_stats) < 0)
FAIL_STACK_ERROR
/* Loop over inserting objects into the root direct block, until there's no more space */
- /* (The "+ 2" in the equation below allows for the length of the object) */
- while(heap_stats.man_free_space > (sizeof(obj) + 2)) {
+ free_frag_size = 0;
+ while(heap_stats.man_free_space > (sizeof(obj) + obj_overhead)) {
/* Initialize object buffer */
for(u = 0; u < sizeof(obj); u++)
obj[u] = u + nobjs;
@@ -197,39 +224,79 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size,
/* Increment object count */
nobjs++;
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)(996 - (nobjs * (sizeof(obj) + 3))), (hsize_t)(start_nobjs + nobjs)))
+ /* Check for needing to increase size of heap ID array */
+ if(nobjs > alloc_ids) {
+ alloc_ids = MAX(1024, (alloc_ids * 2));
+ if(NULL == (ids = H5MM_realloc(ids, sizeof(hsize_t) * alloc_ids)))
+ FAIL_STACK_ERROR
+ } /* end if */
+ ids[nobjs - 1] = heap_id;
+
+ /* Check stats for heap */
+ if((heap_stats.man_free_space - (sizeof(obj) + obj_overhead)) < free_overhead)
+ free_frag_size = heap_stats.man_free_space - (sizeof(obj) + obj_overhead);
+ if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)(data_size - ((nobjs * (sizeof(obj) + obj_overhead)) + free_frag_size)), (hsize_t)(start_nobjs + nobjs)))
FAIL_STACK_ERROR
/* Get statistics for heap */
- HDmemset(&heap_stats, 0, sizeof(H5HF_stat_t));
if(H5HF_stat_info(f, dxpl, fh_addr, &heap_stats) < 0)
FAIL_STACK_ERROR
} /* end while */
- /* Initialize object buffer */
- for(u = 0; u < sizeof(obj); u++)
- obj[u] = u + nobjs;
+ /* Check for adding smaller last object to heap block */
+ if(heap_stats.man_free_space > 0) {
+ last_obj_len = (size_t)(heap_stats.man_free_space - obj_overhead);
- /* Insert last object into the heap, using the remaining free space */
- heap_id = 0;
- if(H5HF_insert(f, dxpl, fh_addr, (size_t)(heap_stats.man_free_space - 3), obj, &heap_id) < 0)
- FAIL_STACK_ERROR
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + nobjs;
- /* Increment object count */
- nobjs++;
+ /* Insert last object into the heap, using the remaining free space */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, last_obj_len, obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
- /* Verify that the heap is full */
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)0, (hsize_t)(start_nobjs + nobjs)))
- FAIL_STACK_ERROR
+ /* Increment object count */
+ nobjs++;
+
+ /* Check for needing to increase size of heap ID array */
+ if(nobjs > alloc_ids) {
+ alloc_ids = MAX(1024, (alloc_ids * 2));
+ if(NULL == (ids = H5MM_realloc(ids, sizeof(hsize_t) * alloc_ids)))
+ FAIL_STACK_ERROR
+ } /* end if */
+ ids[nobjs - 1] = heap_id;
+
+ /* Verify that the heap is full */
+ if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)0, (hsize_t)(start_nobjs + nobjs)))
+ FAIL_STACK_ERROR
+ } /* end if */
+ else
+ last_obj_len = sizeof(obj); /* Normal sized last object */
+
+ /* Verify reading the objects written out */
+ for(v = 0; v < nobjs; v++) {
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + v;
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &ids[v], robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, (v == (nobjs - 1) ? last_obj_len : sizeof(obj))))
+ FAIL_STACK_ERROR
+ } /* end for */
/* Set the number of objects, if requested */
if(nobjs_ptr)
*nobjs_ptr = nobjs;
/* Operations succeeded */
+ H5MM_xfree(ids);
return(0);
error:
+ H5MM_xfree(ids);
return(1);
} /* fill_heap() */
@@ -352,7 +419,7 @@ test_abs_insert_first(hid_t fapl)
H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for object to insert */
- unsigned char obj2[10]; /* Buffer for object to read */
+ unsigned char robj[10]; /* Buffer for object to read */
hsize_t heap_id; /* Heap ID for object inserted */
unsigned u; /* Local index variable */
@@ -391,9 +458,9 @@ test_abs_insert_first(hid_t fapl)
FAIL_STACK_ERROR
/* Check reading back in the object */
- if(H5HF_read(f, dxpl, fh_addr, &heap_id, obj2) < 0)
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
FAIL_STACK_ERROR
- if(HDmemcmp(obj, obj2, sizeof(obj)))
+ if(HDmemcmp(obj, robj, sizeof(obj)))
FAIL_STACK_ERROR
PASSED()
@@ -437,7 +504,9 @@ test_abs_insert_second(hid_t fapl)
H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for first object to insert */
+ unsigned char robj[10]; /* Buffer for reading first object */
unsigned char obj2[20]; /* Buffer for second object to insert */
+ unsigned char robj2[20]; /* Buffer for reading second object */
hsize_t heap_id; /* Heap ID for object inserted */
unsigned u; /* Local index variable */
@@ -475,11 +544,24 @@ test_abs_insert_second(hid_t fapl)
if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)983, (hsize_t)1))
FAIL_STACK_ERROR
+ /* Check reading back in the first object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
heap_id = 0;
if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj2), obj2, &heap_id) < 0)
FAIL_STACK_ERROR
if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)960, (hsize_t)2))
FAIL_STACK_ERROR
+
+ /* Check reading back in the second object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj2) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj2, robj2, sizeof(obj2)))
+ FAIL_STACK_ERROR
+
PASSED()
/* Close the file */
@@ -546,7 +628,7 @@ test_abs_insert_root_mult(hid_t fapl)
TESTING("inserting objects to fill absolute heap's root direct block");
/* Fill the heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, 0, NULL))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, 0, NULL))
FAIL_STACK_ERROR
PASSED()
@@ -617,10 +699,10 @@ test_abs_insert_force_indirect(hid_t fapl)
/*
* Test forcing creation of indirect root block & second direct block
*/
- TESTING("inserting enough objects to create root indirect block");
+ TESTING("inserting objects to create root indirect block");
/* Fill the heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, 0, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, 0, &nobjs))
FAIL_STACK_ERROR
/* Insert one more object, to force root indirect block creation */
@@ -706,15 +788,15 @@ test_abs_insert_fill_second(hid_t fapl)
/*
* Test inserting mult. (small) objects to fill second direct block
*/
- TESTING("inserting enough objects to fill second direct block");
+ TESTING("inserting objects to fill second direct block");
/* Fill the first direct block heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
/* Fill the second direct block heap up (also creates initial root indirect block) */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
PASSED()
@@ -761,6 +843,7 @@ test_abs_insert_third_direct(hid_t fapl)
H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for first object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
hsize_t heap_id; /* Heap ID for object inserted */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
@@ -787,15 +870,15 @@ test_abs_insert_third_direct(hid_t fapl)
/*
* Test inserting mult. (small) objects to create third direct block
*/
- TESTING("inserting enough objects to create third direct block");
+ TESTING("inserting objects to create third direct block");
/* Fill the first direct block heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
/* Fill the second direct block heap up (also creates initial root indirect block) */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
@@ -816,6 +899,12 @@ test_abs_insert_third_direct(hid_t fapl)
if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)3072, (hsize_t)3072, (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs))
FAIL_STACK_ERROR
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
PASSED()
/* Close the file */
@@ -883,12 +972,12 @@ test_abs_fill_first_row(hid_t fapl)
/*
* Test inserting mult. (small) objects to fill first row in root indirect block
*/
- TESTING("inserting enough objects to fill first row of root indirect block");
+ TESTING("inserting objects to fill first row of root indirect block");
/* Loop over filling direct blocks, until first root indirect row is full */
for(u = 0; u < STD_MAN_WIDTH; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -935,7 +1024,8 @@ test_abs_start_second_row(hid_t fapl)
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
- unsigned char obj[10]; /* Buffer for first object to insert */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
hsize_t heap_id; /* Heap ID for object inserted */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
@@ -958,24 +1048,21 @@ test_abs_start_second_row(hid_t fapl)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
-#ifdef QAK
-HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
-#endif /* QAK */
/*
* Test inserting mult. (small) objects to start second row in root indirect block
*/
- TESTING("inserting enough objects to start second row of root indirect block");
+ TESTING("inserting objects to start second row of root indirect block");
/* Loop over filling direct blocks, until first root indirect row is full */
for(u = 0; u < STD_MAN_WIDTH; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
- /* Insert one more object, to force root indirect block creation */
+ /* Insert one more object, to force expanding root indirect block to two rows */
/* Initialize object buffer */
for(u = 0; u < sizeof(obj); u++)
@@ -992,6 +1079,12 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)((STD_MAN_WIDTH + 1) * STD_MAN_START_BLOCK_SIZE), (hsize_t)((STD_MAN_WIDTH + 1) * STD_MAN_START_BLOCK_SIZE), (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs))
FAIL_STACK_ERROR
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
PASSED()
/* Close the file */
@@ -1055,19 +1148,16 @@ test_abs_fill_second_row(hid_t fapl)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
-#ifndef QAK
-HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
-#endif /* QAK */
/*
* Test inserting mult. (small) objects to start second row in root indirect block
*/
- TESTING("inserting enough objects to fill second row of root indirect block");
+ TESTING("inserting objects to fill second row of root indirect block");
/* Loop over filling direct blocks, until first root indirect row is full */
for(u = 0; u < STD_MAN_WIDTH; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1075,7 +1165,7 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
/* Loop over filling direct blocks, until second root indirect row is full */
for(u = 0; u < STD_MAN_WIDTH; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)((STD_MAN_WIDTH * STD_MAN_START_BLOCK_SIZE) + (u + 1) * STD_MAN_START_BLOCK_SIZE), tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)((STD_MAN_WIDTH * STD_MAN_START_BLOCK_SIZE) + (u + 1) * STD_MAN_START_BLOCK_SIZE), STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1098,6 +1188,455 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_abs_start_third_row
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill first row of root indirect
+ * block, fill the second row also, then add another object to
+ * start the third row.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 20, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_start_third_row(hid_t fapl)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ H5HF_create_t cparam; /* Creation parameters for heap */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ init_std_cparam(&cparam);
+ if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to start third row in root indirect block
+ */
+ TESTING("inserting objects to start third row of root indirect block");
+
+ /* Loop over filling direct blocks, until first root indirect row is full */
+ for(u = 0; u < STD_MAN_WIDTH; u++) {
+ /* Fill a direct heap block up */
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Loop over filling direct blocks, until second root indirect row is full */
+ for(u = 0; u < STD_MAN_WIDTH; u++) {
+ /* Fill a direct heap block up */
+ if(fill_heap(f, dxpl, fh_addr, (hsize_t)((STD_MAN_WIDTH * STD_MAN_START_BLOCK_SIZE) + (u + 1) * STD_MAN_START_BLOCK_SIZE), STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Insert one more object, to force expanding root indirect block to three rows */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size = (2 * STD_MAN_WIDTH) * STD_MAN_START_BLOCK_SIZE +
+ (2 * STD_MAN_START_BLOCK_SIZE);
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)2007, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_start_third_row() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_fourth_row
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill first four rows of root indirect
+ * block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 20, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_fourth_row(hid_t fapl)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ H5HF_create_t cparam; /* Creation parameters for heap */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned u, v; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ init_std_cparam(&cparam);
+ if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to fill four rows in root indirect block
+ */
+ TESTING("inserting objects to fill four rows of root indirect block");
+
+ /* Loop over rows */
+ block_size = STD_MAN_START_BLOCK_SIZE;
+ heap_size = 0;
+ for(v = 0; v < 4; v++) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < STD_MAN_WIDTH; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(v > 0)
+ block_size *= 2;
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_fourth_row() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_all_root_direct
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 20, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_all_root_direct(hid_t fapl)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ H5HF_create_t cparam; /* Creation parameters for heap */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ init_std_cparam(&cparam);
+ if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct rows in root indirect block
+ */
+ TESTING("inserting objects to fill all direct rows of root indirect block");
+
+ /* Loop over rows */
+ block_size = STD_MAN_START_BLOCK_SIZE;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= STD_MAN_MAX_DIRECT_SIZE) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < STD_MAN_WIDTH; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_all_root_direct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_first_recursive_indirec5
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block and create first recursive indirect block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 20, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_first_recursive_indirect(hid_t fapl)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ H5HF_create_t cparam; /* Creation parameters for heap */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ init_std_cparam(&cparam);
+ if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to force creation of first recursive indirect block
+ */
+ TESTING("inserting objects to create first recursive indirect block");
+
+ /* Loop over rows */
+ block_size = STD_MAN_START_BLOCK_SIZE;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= STD_MAN_MAX_DIRECT_SIZE) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < STD_MAN_WIDTH; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Insert one more object, to force creation of first recursive indirect block */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size += STD_MAN_START_BLOCK_SIZE;
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_first_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test the fractal heap code
@@ -1133,13 +1672,16 @@ main(void)
nerrors += test_abs_insert_fill_second(fapl);
nerrors += test_abs_insert_third_direct(fapl);
nerrors += test_abs_fill_first_row(fapl);
- nerrors += test_abs_fill_first_row(fapl);
nerrors += test_abs_start_second_row(fapl);
+ nerrors += test_abs_fill_second_row(fapl);
+ nerrors += test_abs_start_third_row(fapl);
+ nerrors += test_abs_fill_fourth_row(fapl);
+ nerrors += test_abs_fill_all_root_direct(fapl);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
+ nerrors += test_abs_first_recursive_indirect(fapl);
#ifdef QAK
- nerrors += test_abs_fill_second_row(fapl);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
@@ -1147,7 +1689,7 @@ HDfprintf(stderr, "Uncomment tests!\n");
if(nerrors)
goto error;
puts("All fractal heap tests passed.");
-#ifndef QAK
+#ifdef QAK
h5_cleanup(FILENAME, fapl);
#else /* QAK */
HDfprintf(stderr, "Uncomment cleanup!\n");