summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--src/H5AC.c1
-rw-r--r--src/H5ACprivate.h1
-rw-r--r--src/H5Cpkg.h2
-rw-r--r--src/H5EA.c22
-rw-r--r--src/H5EAcache.c326
-rw-r--r--src/H5EAdbg.c84
-rw-r--r--src/H5EAdblock.c16
-rw-r--r--src/H5EAhdr.c8
-rw-r--r--src/H5EAiblock.c8
-rw-r--r--src/H5EApkg.h58
-rw-r--r--src/H5EAsblock.c397
-rw-r--r--src/H5FDpublic.h8
-rw-r--r--src/H5Fprivate.h1
-rwxr-xr-xsrc/Makefile.am2
-rw-r--r--src/Makefile.in5
-rw-r--r--test/earray.c11
-rw-r--r--tools/misc/h5debug.c17
18 files changed, 935 insertions, 33 deletions
diff --git a/MANIFEST b/MANIFEST
index cde6ed3..a7da515 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -507,6 +507,7 @@
./src/H5EAint.c
./src/H5EApkg.h
./src/H5EAprivate.h
+./src/H5EAsblock.c
./src/H5EAstat.c
./src/H5EAtest.c
./src/H5F.c
diff --git a/src/H5AC.c b/src/H5AC.c
index b8c4705..751f877 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -493,6 +493,7 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] =
"shared OH message index",
"extensible array headers",
"extensible array index blocks",
+ "extensible array super blocks",
"extensible array data blocks",
"test entry" /* for testing only -- not used for actual files */
};
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index ea97e17..fc30a78 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -64,6 +64,7 @@ typedef enum {
H5AC_SOHM_LIST_ID, /*shared message index stored as a list */
H5AC_EARRAY_HDR_ID, /*extensible array header */
H5AC_EARRAY_IBLOCK_ID, /*extensible array index block */
+ H5AC_EARRAY_SBLOCK_ID, /*extensible array super block */
H5AC_EARRAY_DBLOCK_ID, /*extensible array index block */
H5AC_TEST_ID, /*test entry -- not used for actual files */
H5AC_NTYPES /* Number of types, must be last */
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index 46181ea..ced02d2 100644
--- a/src/H5Cpkg.h
+++ b/src/H5Cpkg.h
@@ -802,7 +802,7 @@
****************************************************************************/
#define H5C__H5C_T_MAGIC 0x005CAC0E
-#define H5C__MAX_NUM_TYPE_IDS 19
+#define H5C__MAX_NUM_TYPE_IDS 20
#define H5C__PREFIX_LEN 32
struct H5C_t
diff --git a/src/H5EA.c b/src/H5EA.c
index 6f28238..00e1917 100644
--- a/src/H5EA.c
+++ b/src/H5EA.c
@@ -409,7 +409,7 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i
haddr_t dblk_addr; /* Address of data block created */
/* Create data block */
- dblk_addr = H5EA__dblock_create(iblock, dxpl_id, hdr->sblk_info[sblk_idx].dblk_nelmts);
+ dblk_addr = H5EA__dblock_create(hdr, dxpl_id, hdr->sblk_info[sblk_idx].dblk_nelmts);
if(!H5F_addr_defined(dblk_addr))
H5E_THROW(H5E_CANTCREATE, "unable to create extensible array data block")
@@ -435,7 +435,25 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i
dblock_cache_flags |= H5AC__DIRTIED_FLAG;
} /* end if */
else {
-HDfprintf(stderr, "%s: Super block index %Hu not supported yet!\n", FUNC, sblk_idx);
+ /* Check if the super block has been allocated on disk yet */
+ if(!H5F_addr_defined(iblock->sblk_addrs[sblk_idx - iblock->nsblks])) {
+ haddr_t sblk_addr; /* Address of data block created */
+
+ /* Create super block */
+ sblk_addr = H5EA__sblock_create(hdr, dxpl_id, sblk_idx);
+ if(!H5F_addr_defined(sblk_addr))
+ H5E_THROW(H5E_CANTCREATE, "unable to create extensible array super block")
+
+ /* Set super block address in index block */
+ iblock->sblk_addrs[sblk_idx - iblock->nsblks] = sblk_addr;
+ iblock_cache_flags |= H5AC__DIRTIED_FLAG;
+
+ /* Increment count of actual super blocks created */
+ hdr->stats.nsuper_blks++;
+ hdr_dirty = TRUE;
+ } /* end if */
+
+HDfprintf(stderr, "%s: Super block index %u not supported yet!\n", FUNC, sblk_idx);
HDassert(0 && "Super block index location not supported!");
} /* end else */
} /* end else */
diff --git a/src/H5EAcache.c b/src/H5EAcache.c
index d484653..35a6916 100644
--- a/src/H5EAcache.c
+++ b/src/H5EAcache.c
@@ -54,11 +54,13 @@
/* Fractal heap format version #'s */
#define H5EA_HDR_VERSION 0 /* Header */
#define H5EA_IBLOCK_VERSION 0 /* Index block */
+#define H5EA_SBLOCK_VERSION 0 /* Super block */
#define H5EA_DBLOCK_VERSION 0 /* Data block */
/* Size of stack buffer for serialization buffers */
#define H5EA_HDR_BUF_SIZE 512
#define H5EA_IBLOCK_BUF_SIZE 512
+#define H5EA_SBLOCK_BUF_SIZE 512
#define H5EA_DBLOCK_BUF_SIZE 512
@@ -87,6 +89,11 @@ static herr_t H5EA__cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy,
static herr_t H5EA__cache_iblock_clear(H5F_t *f, H5EA_iblock_t *iblock, hbool_t destroy);
static herr_t H5EA__cache_iblock_size(const H5F_t *f, const H5EA_iblock_t *iblock, size_t *size_ptr);
static herr_t H5EA__cache_iblock_dest(H5F_t *f, H5EA_iblock_t *iblock);
+static H5EA_sblock_t *H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+static herr_t H5EA__cache_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_sblock_t *sblock, unsigned * flags_ptr);
+static herr_t H5EA__cache_sblock_clear(H5F_t *f, H5EA_sblock_t *sblock, hbool_t destroy);
+static herr_t H5EA__cache_sblock_size(const H5F_t *f, const H5EA_sblock_t *sblock, size_t *size_ptr);
+static herr_t H5EA__cache_sblock_dest(H5F_t *f, H5EA_sblock_t *sblock);
static H5EA_dblock_t *H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
static herr_t H5EA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_dblock_t *dblock, unsigned * flags_ptr);
static herr_t H5EA__cache_dblock_clear(H5F_t *f, H5EA_dblock_t *dblock, hbool_t destroy);
@@ -118,6 +125,16 @@ const H5AC_class_t H5AC_EARRAY_IBLOCK[1] = {{
(H5AC_size_func_t)H5EA__cache_iblock_size,
}};
+/* H5EA super block inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_EARRAY_SBLOCK[1] = {{
+ H5AC_EARRAY_SBLOCK_ID,
+ (H5AC_load_func_t)H5EA__cache_sblock_load,
+ (H5AC_flush_func_t)H5EA__cache_sblock_flush,
+ (H5AC_dest_func_t)H5EA__cache_sblock_dest,
+ (H5AC_clear_func_t)H5EA__cache_sblock_clear,
+ (H5AC_size_func_t)H5EA__cache_sblock_size,
+}};
+
/* H5EA data block inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_EARRAY_DBLOCK[1] = {{
H5AC_EARRAY_DBLOCK_ID,
@@ -798,6 +815,315 @@ END_FUNC(STATIC) /* end H5EA__cache_iblock_dest() */
/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_load
+ *
+ * Purpose: Loads an extensible array super block from the disk.
+ *
+ * Return: Success: Pointer to a new extensible array super block
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+H5EA_sblock_t *, NULL, NULL,
+H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ const void *_sblk_idx, void *_hdr))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */
+ const unsigned *sblk_idx = (const unsigned *)_sblk_idx; /* Index of this super block */
+ H5EA_sblock_t *sblock = NULL; /* Super block info */
+ size_t size; /* Super block size */
+ H5WB_t *wb = NULL; /* Wrapped buffer for super block data */
+ uint8_t sblock_buf[H5EA_IBLOCK_BUF_SIZE]; /* Buffer for super block */
+ uint8_t *buf; /* Pointer to super block buffer */
+ const uint8_t *p; /* Pointer into raw data buffer */
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(sblk_idx && *sblk_idx > 0);
+ HDassert(hdr);
+
+ /* Allocate the extensible array super block */
+ if(NULL == (sblock = H5EA__sblock_alloc(hdr, *sblk_idx)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block")
+
+ /* Set the extensible array super block's address */
+ sblock->addr = addr;
+
+ /* Wrap the local buffer for serialized info */
+ if(NULL == (wb = H5WB_wrap(sblock_buf, sizeof(sblock_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* Compute the size of the extensible array super block on disk */
+ size = H5EA_SBLOCK_SIZE(sblock);
+
+ /* Get a pointer to a buffer that's large enough for serialized info */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Read super block from disk */
+ if(H5F_block_read(f, H5FD_MEM_EARRAY_SBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read extensible array super block")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array super block signature")
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5EA_SBLOCK_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong extensible array super block version")
+
+ /* Extensible array type */
+ if(*p++ != (uint8_t)hdr->cparam.cls->id)
+ H5E_THROW(H5E_BADTYPE, "incorrect extensible array class")
+
+ /* Internal information */
+
+ /* Decode data block addresses */
+ if(sblock->ndblks > 0) {
+ size_t u; /* Local index variable */
+
+ /* Decode addresses of data blocks in super block */
+ for(u = 0; u < sblock->ndblks; u++)
+ H5F_addr_decode(f, &p, &sblock->dblk_addrs[u]);
+ } /* end if */
+
+ /* Sanity check */
+ /* (allow for checksum not decoded yet) */
+ HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM));
+
+ /* Save the super block's size */
+ sblock->size = size;
+
+ /* Compute checksum on super block */
+ computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32DECODE(p, stored_chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(p - buf) == sblock->size);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array super block")
+
+ /* Set return value */
+ ret_value = sblock;
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+ if(!ret_value)
+ if(sblock && H5EA__cache_sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_flush
+ *
+ * Purpose: Flushes a dirty extensible array super block to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
+ H5EA_sblock_t *sblock, unsigned UNUSED * flags_ptr))
+
+ /* Local variables */
+ H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */
+ uint8_t ser_buf[H5EA_SBLOCK_BUF_SIZE]; /* Serialization buffer */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(sblock);
+ HDassert(sblock->hdr);
+
+ if(sblock->cache_info.is_dirty) {
+ uint8_t *buf; /* Temporary raw data buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t size; /* Index block size on disk */
+ uint32_t metadata_chksum; /* Computed metadata checksum value */
+
+ /* Wrap the local buffer for serialized info */
+ if(NULL == (wb = H5WB_wrap(ser_buf, sizeof(ser_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* Compute the size of the super block on disk */
+ size = sblock->size;
+
+ /* Get a pointer to a buffer that's large enough for serialized info */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ H5E_THROW(H5E_CANTGET, "can't get actual buffer")
+
+ /* Get temporary pointer to serialized info */
+ p = buf;
+
+ /* Magic number */
+ HDmemcpy(p, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5EA_SBLOCK_VERSION;
+
+ /* Extensible array type */
+ *p++ = sblock->hdr->cparam.cls->id;
+
+ /* Internal information */
+
+ /* Encode data block addresses */
+ if(sblock->ndblks > 0) {
+ size_t u; /* Local index variable */
+
+ /* Encode addresses of data blocks in super block */
+ for(u = 0; u < sblock->ndblks; u++)
+ H5F_addr_encode(f, &p, sblock->dblk_addrs[u]);
+ } /* end if */
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Write the super block */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_EARRAY_SBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save extensible array super block to disk")
+
+ sblock->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5EA__cache_sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_clear
+ *
+ * Purpose: Mark a extensible array super block in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sept 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_sblock_clear(H5F_t *f, H5EA_sblock_t *sblock, hbool_t destroy))
+
+ /* Sanity check */
+ HDassert(sblock);
+
+ /* Reset the dirty flag */
+ sblock->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5EA__cache_sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_size
+ *
+ * Purpose: Compute the size in bytes of a extensible array super block
+ * on disk, and return it in *size_ptr. On failure,
+ * the value of *size_ptr is undefined.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sept 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__cache_sblock_size(const H5F_t UNUSED *f, const H5EA_sblock_t *sblock,
+ size_t *size_ptr))
+
+ /* Sanity check */
+ HDassert(sblock);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = sblock->size;
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_sblock_dest
+ *
+ * Purpose: Destroys an extensible array super block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_sblock_dest(H5F_t *f, H5EA_sblock_t *sblock))
+
+ /* Sanity check */
+ HDassert(sblock);
+
+ /* Release the super block */
+ if(H5EA__sblock_dest(f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "can't free extensible array super block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_sblock_dest() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5EA__cache_dblock_load
*
* Purpose: Loads an extensible array data block from the disk.
diff --git a/src/H5EAdbg.c b/src/H5EAdbg.c
index 9fb30c7..7b2d839 100644
--- a/src/H5EAdbg.c
+++ b/src/H5EAdbg.c
@@ -279,6 +279,88 @@ END_FUNC(PKG) /* end H5EA__iblock_debug() */
/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_debug
+ *
+ * Purpose: Prints debugging info about a extensible array super block.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
+ int fwidth, const H5EA_class_t *cls, haddr_t hdr_addr, unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
+ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(cls);
+ HDassert(H5F_addr_defined(hdr_addr));
+
+ /* Load the extensible array header */
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, cls, NULL, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
+
+ /* Sanity check */
+ HDassert(H5F_addr_eq(hdr->idx_blk_addr, addr));
+
+ /* Protect super block */
+ if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, addr, sblk_idx, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long_long)addr)
+
+ /* Print opening message */
+ HDfprintf(stream, "%*sExtensible Array Super Block...\n", indent, "");
+
+ /* Print the values */
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Array class ID:",
+ (hdr->cparam.cls->id == H5EA_CLS_TEST_ID ? "H5EA_CLS_TEST_ID" :
+ "Unknown!"));
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "Super Block size:",
+ sblock->size);
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
+ "# of data block addresses in super block:",
+ sblock->ndblks);
+
+ /* Check if there are any data block addresses in super block */
+ if(sblock->ndblks > 0) {
+ char temp_str[128]; /* Temporary string, for formatting */
+ unsigned u; /* Local index variable */
+
+ /* Print the data block addresses in the super block */
+ HDfprintf(stream, "%*sData Block Addresses in Super Block:\n", indent, "");
+ for(u = 0; u < sblock->ndblks; u++) {
+ /* Print address */
+ sprintf(temp_str, "Address #%u:", u);
+ HDfprintf(stream, "%*s%-*s %a\n", (indent + 3), "", MAX(0, (fwidth - 3)),
+ temp_str,
+ sblock->dblk_addrs[u]);
+ } /* end for */
+ } /* end if */
+
+CATCH
+ if(sblock && H5EA__sblock_unprotect(sblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array super block")
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_EARRAY_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+
+END_FUNC(PKG) /* end H5EA__sblock_debug() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5EA__dblock_debug
*
* Purpose: Prints debugging info about a extensible array data block.
@@ -316,7 +398,7 @@ H5EA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int inde
H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
/* Protect data block */
- if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, addr, (size_t)dblk_nelmts, H5AC_READ)))
+ if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, addr, dblk_nelmts, H5AC_READ)))
H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)addr)
/* Print opening message */
diff --git a/src/H5EAdblock.c b/src/H5EAdblock.c
index 15a38c5..0c29741 100644
--- a/src/H5EAdblock.c
+++ b/src/H5EAdblock.c
@@ -152,7 +152,7 @@ END_FUNC(PKG) /* end H5EA__dblock_alloc() */
*/
BEGIN_FUNC(PKG, ERR,
haddr_t, HADDR_UNDEF, HADDR_UNDEF,
-H5EA__dblock_create(H5EA_iblock_t *iblock, hid_t dxpl_id, size_t nelmts))
+H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, size_t nelmts))
/* Local variables */
H5EA_dblock_t *dblock = NULL; /* Extensible array data block */
@@ -162,11 +162,11 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
#endif /* QAK */
/* Sanity check */
- HDassert(iblock);
+ HDassert(hdr);
HDassert(nelmts > 0);
/* Allocate the data block */
- if(NULL == (dblock = H5EA__dblock_alloc(iblock->hdr, nelmts)))
+ if(NULL == (dblock = H5EA__dblock_alloc(hdr, nelmts)))
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block")
/* Set size of data block on disk */
@@ -176,15 +176,15 @@ HDfprintf(stderr, "%s: dblock->size = %Zu\n", FUNC, dblock->size);
#endif /* QAK */
/* Allocate space for the data block on disk */
- if(HADDR_UNDEF == (dblock->addr = H5MF_alloc(iblock->hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
+ if(HADDR_UNDEF == (dblock->addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array data block")
/* Clear any elements in index block to fill value */
- if((iblock->hdr->cparam.cls->fill)(dblock->elmts, (size_t)dblock->nelmts) < 0)
+ if((hdr->cparam.cls->fill)(dblock->elmts, (size_t)dblock->nelmts) < 0)
H5E_THROW(H5E_CANTSET, "can't set extensible array data block elements to class's fill value")
/* Cache the new extensible array data block */
- if(H5AC_set(iblock->hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblock->addr, dblock, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_DBLOCK, dblock->addr, dblock, H5AC__NO_FLAGS_SET) < 0)
H5E_THROW(H5E_CANTINSERT, "can't add extensible array index block to cache")
/* Set address of index block to return */
@@ -194,11 +194,11 @@ CATCH
if(!H5F_addr_defined(ret_value))
if(dblock) {
/* Release data block's disk space */
- if(H5F_addr_defined(dblock->addr) && H5MF_xfree(iblock->hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, dblock->addr, (hsize_t)dblock->size) < 0)
+ if(H5F_addr_defined(dblock->addr) && H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_DBLOCK, dxpl_id, dblock->addr, (hsize_t)dblock->size) < 0)
H5E_THROW(H5E_CANTFREE, "unable to release extensible array data block")
/* Destroy data block */
- if(H5EA__dblock_dest(iblock->hdr->f, dblock) < 0)
+ if(H5EA__dblock_dest(hdr->f, dblock) < 0)
H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block")
} /* end if */
diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c
index 3dc5d50..f11fc70 100644
--- a/src/H5EAhdr.c
+++ b/src/H5EAhdr.c
@@ -209,17 +209,17 @@ HDfprintf(stderr, "%s: hdr->nsblks = %Zu\n", FUNC, hdr->nsblks);
start_idx = 0;
start_dblk = 0;
for(u = 0; u < hdr->nsblks; u++) {
- hdr->sblk_info[u].ndblks = (hsize_t)H5_EXP2(u / 2);
+ hdr->sblk_info[u].ndblks = (size_t)H5_EXP2(u / 2);
hdr->sblk_info[u].dblk_nelmts = (size_t)H5_EXP2((u + 1) / 2) * hdr->cparam.data_blk_min_elmts;
hdr->sblk_info[u].start_idx = start_idx;
hdr->sblk_info[u].start_dblk = start_dblk;
#ifdef QAK
-HDfprintf(stderr, "%s: hdr->sblk_info[%Zu] = {%Hu, %Zu, %Hu, %Hu}\n", FUNC, u, hdr->sblk_info[u].ndblks, hdr->sblk_info[u].dblk_nelmts, hdr->sblk_info[u].start_idx, hdr->sblk_info[u].start_dblk);
+HDfprintf(stderr, "%s: hdr->sblk_info[%Zu] = {%Zu, %Zu, %Hu, %Hu}\n", FUNC, u, hdr->sblk_info[u].ndblks, hdr->sblk_info[u].dblk_nelmts, hdr->sblk_info[u].start_idx, hdr->sblk_info[u].start_dblk);
#endif /* QAK */
/* Advance starting indices for next super block */
- start_idx += hdr->sblk_info[u].ndblks * hdr->sblk_info[u].dblk_nelmts;
- start_dblk += hdr->sblk_info[u].ndblks;
+ start_idx += (hsize_t)hdr->sblk_info[u].ndblks * (hsize_t)hdr->sblk_info[u].dblk_nelmts;
+ start_dblk += (hsize_t)hdr->sblk_info[u].ndblks;
} /* end for */
/* Set size of header on disk */
diff --git a/src/H5EAiblock.c b/src/H5EAiblock.c
index 75c2c85..78db20e 100644
--- a/src/H5EAiblock.c
+++ b/src/H5EAiblock.c
@@ -387,8 +387,12 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
for(u = 0; u < iblock->nsblk_addrs; u++) {
/* Check for data block existing */
if(H5F_addr_defined(iblock->sblk_addrs[u])) {
-HDfprintf(stderr, "%s: Deleting super blocks not supported yet!\n", FUNC);
-HDassert(0 && "Deleting super blocks not supported!");
+ /* Delete super block */
+ if(H5EA__sblock_delete(hdr, dxpl_id, iblock->sblk_addrs[u], (unsigned)(u + iblock->nsblks)) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array super block")
+ iblock->sblk_addrs[u] = HADDR_UNDEF;
+HDfprintf(stderr, "%s: Deleting super blocks not tested yet!\n", FUNC);
+HDassert(0 && "Deleting super blocks not tested!");
} /* end if */
} /* end for */
} /* end if */
diff --git a/src/H5EApkg.h b/src/H5EApkg.h
index ca920ec..2c0930c 100644
--- a/src/H5EApkg.h
+++ b/src/H5EApkg.h
@@ -302,12 +302,12 @@ func_init_failed: \
* BEGIN_FUNC() and an END_FUNC() within a function body. The argument is
* the return value.
* The return value is assigned to a variable `ret_value' and control branches
- * to the `catch' label, if we're not already past it.
+ * to the `catch_except' label, if we're not already past it.
*/
#define H5_LEAVE(v) { \
ret_value = v; \
if(!past_catch) \
- goto catch; \
+ goto catch_except; \
}
/*
@@ -315,7 +315,7 @@ func_init_failed: \
* FUNC_ENTER() and a FUNC_LEAVE() within a function body. The arguments are
* the minor error number, and an error string.
* The return value is assigned to a variable `ret_value' and control branches
- * to the `catch' label, if we're not already past it.
+ * to the `catch_except' label, if we're not already past it.
*/
#define H5E_THROW(...) { \
H5E_PRINTF(__VA_ARGS__); \
@@ -325,7 +325,7 @@ func_init_failed: \
/* Macro for "catching" flow of control when an error occurs. Note that the
* H5_LEAVE macro won't jump back here once it's past this point.
*/
-#define CATCH past_catch = TRUE; catch:;
+#define CATCH past_catch = TRUE; catch_except:;
/**************************/
@@ -391,6 +391,15 @@ func_init_failed: \
+ ((i)->nsblk_addrs * (i)->hdr->sizeof_addr) /* Super block addresses in index block */ \
)
+/* Size of the extensible array super block on disk */
+#define H5EA_SBLOCK_SIZE(s) ( \
+ /* General metadata fields */ \
+ H5EA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* Extensible Array Super Block specific fields */ \
+ + ((s)->ndblks * (s)->hdr->sizeof_addr) /* Data block addresses in super block */ \
+ )
+
/* Size of the extensible array data block on disk */
#define H5EA_DBLOCK_SIZE(d) ( \
/* General metadata fields */ \
@@ -407,7 +416,7 @@ func_init_failed: \
/* Information for each super block in extensible array */
typedef struct H5EA_sblk_info_t {
- hsize_t ndblks; /* Number of data blocks for a super block */
+ size_t ndblks; /* Number of data blocks for a super block */
size_t dblk_nelmts; /* Number of elements in each data block for super block */
hsize_t start_idx; /* Index of first element in super block */
hsize_t start_dblk; /* Index of first data block in super block */
@@ -473,6 +482,26 @@ typedef struct H5EA_iblock_t {
size_t nsblk_addrs; /* Number of pointers to super blocks in index block */
} H5EA_iblock_t;
+/* The extensible array super block information */
+typedef struct H5EA_sblock_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Extensible array information (stored) */
+ haddr_t *dblk_addrs; /* Buffer for addresses of data blocks in super block */
+
+ /* Internal array information (not stored) */
+ size_t rc; /* Reference count of objects using this block */
+ H5EA_hdr_t *hdr; /* Shared array header info */
+ haddr_t addr; /* Address of this index block on disk */
+ size_t size; /* Size of index block on disk */
+
+ /* Computed/cached values (not stored) */
+ unsigned idx; /* Super block index within the extensible array */
+ size_t ndblks; /* # of data block addresses that are in super block */
+ size_t dblk_nelmts; /* # of elements for data blocks reachable through this super block */
+} H5EA_sblock_t;
+
/* The extensible array data block information */
typedef struct H5EA_dblock_t {
/* Information for H5AC cache functions, _must_ be first field in structure */
@@ -507,6 +536,9 @@ H5_DLLVAR const H5AC_class_t H5AC_EARRAY_HDR[1];
/* H5EA index block inherits cache-like properties from H5AC */
H5_DLLVAR const H5AC_class_t H5AC_EARRAY_IBLOCK[1];
+/* H5EA index block inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_EARRAY_SBLOCK[1];
+
/* H5EA data block inherits cache-like properties from H5AC */
H5_DLLVAR const H5AC_class_t H5AC_EARRAY_DBLOCK[1];
@@ -544,9 +576,20 @@ H5_DLL herr_t H5EA__iblock_unprotect(H5EA_iblock_t *iblock, hid_t dxpl_id,
H5_DLL herr_t H5EA__iblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id);
H5_DLL herr_t H5EA__iblock_dest(H5F_t *f, H5EA_iblock_t *iblock);
+/* Super block routines */
+H5_DLL H5EA_sblock_t *H5EA__sblock_alloc(H5EA_hdr_t *hdr, unsigned sblk_idx);
+H5_DLL haddr_t H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, unsigned sblk_idx);
+H5_DLL H5EA_sblock_t *H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t sblk_addr, unsigned sblk_idx, H5AC_protect_t rw);
+H5_DLL herr_t H5EA__sblock_unprotect(H5EA_sblock_t *sblock, hid_t dxpl_id,
+ unsigned cache_flags);
+H5_DLL herr_t H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t sblk_addr, unsigned sblk_idx);
+H5_DLL herr_t H5EA__sblock_dest(H5F_t *f, H5EA_sblock_t *sblock);
+
/* Data block routines */
H5_DLL H5EA_dblock_t *H5EA__dblock_alloc(H5EA_hdr_t *hdr, size_t nelmts);
-H5_DLL haddr_t H5EA__dblock_create(H5EA_iblock_t *iblock, hid_t dxpl_id,
+H5_DLL haddr_t H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id,
size_t nelmts);
H5_DLL unsigned H5EA__dblock_sblk_idx(const H5EA_hdr_t *hdr, hsize_t idx);
H5_DLL H5EA_dblock_t *H5EA__dblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
@@ -563,6 +606,9 @@ H5_DLL herr_t H5EA__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
H5_DLL herr_t H5EA__iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth, const H5EA_class_t *cls,
haddr_t hdr_addr);
+H5_DLL herr_t H5EA__sblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ FILE *stream, int indent, int fwidth, const H5EA_class_t *cls,
+ haddr_t hdr_addr, unsigned sblk_idx);
H5_DLL herr_t H5EA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth, const H5EA_class_t *cls,
haddr_t hdr_addr, size_t dblk_nelmts);
diff --git a/src/H5EAsblock.c b/src/H5EAsblock.c
new file mode 100644
index 0000000..89f4d4a
--- /dev/null
+++ b/src/H5EAsblock.c
@@ -0,0 +1,397 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5EAsblock.c
+ * Sep 30 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Super block routines for extensible arrays.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5EA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5EApkg.h" /* Extensible Arrays */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5EA_iblock_t struct */
+H5FL_DEFINE_STATIC(H5EA_sblock_t);
+
+/* Declare a free list to manage the haddr_t sequence information */
+H5FL_SEQ_DEFINE_STATIC(haddr_t);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_alloc
+ *
+ * Purpose: Allocate extensible array super block
+ *
+ * Return: Non-NULL pointer to super block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_sblock_t *, NULL, NULL,
+H5EA__sblock_alloc(H5EA_hdr_t *hdr, unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
+
+ /* Check arguments */
+ HDassert(hdr);
+
+ /* Allocate memory for the index block */
+ if(NULL == (sblock = H5FL_CALLOC(H5EA_sblock_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block")
+
+ /* Set non-zero internal fields */
+ sblock->addr = HADDR_UNDEF;
+
+ /* Compute/cache information */
+ sblock->idx = sblk_idx;
+ sblock->ndblks = hdr->sblk_info[sblk_idx].ndblks;
+ sblock->dblk_nelmts = hdr->sblk_info[sblk_idx].dblk_nelmts;
+#ifdef QAK
+HDfprintf(stderr, "%s: sblock->ndblks = %Zu\n", FUNC, sblock->ndblks);
+#endif /* QAK */
+
+ /* Allocate buffer for data block addresses in super block */
+ if(sblock->ndblks > 0)
+ if(NULL == (sblock->dblk_addrs = H5FL_SEQ_MALLOC(haddr_t, sblock->ndblks)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for super block data block addresses")
+
+ /* Share common array information */
+ sblock->hdr = hdr;
+ if(H5EA__hdr_incr(hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header")
+
+ /* Set the return value */
+ ret_value = sblock;
+
+CATCH
+ if(!ret_value)
+ if(sblock && H5EA__sblock_dest(hdr->f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+
+END_FUNC(PKG) /* end H5EA__sblock_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_create
+ *
+ * Purpose: Creates a new extensible array super block in the file
+ *
+ * Return: Valid file address on success/HADDR_UNDEF on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+haddr_t, HADDR_UNDEF, HADDR_UNDEF,
+H5EA__sblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_sblock_t *sblock = NULL; /* Extensible array super block */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Allocate the super block */
+ if(NULL == (sblock = H5EA__sblock_alloc(hdr, sblk_idx)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block")
+
+ /* Set size of super block on disk */
+ sblock->size = H5EA_SBLOCK_SIZE(sblock);
+#ifdef QAK
+HDfprintf(stderr, "%s: sblock->size = %Zu\n", FUNC, sblock->size);
+#endif /* QAK */
+
+ /* Allocate space for the super block on disk */
+ if(HADDR_UNDEF == (sblock->addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, (hsize_t)sblock->size)))
+ H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array super block")
+
+ /* Reset data block addresses */
+ if(sblock->ndblks > 0) {
+ haddr_t tmp_addr = HADDR_UNDEF; /* Address value to fill data block addresses with */
+
+ /* Set all the data block addresses to "undefined" address value */
+ H5V_array_fill(sblock->dblk_addrs, &tmp_addr, sizeof(haddr_t), sblock->ndblks);
+ } /* end if */
+
+ /* Cache the new extensible array super block */
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblock->addr, sblock, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTINSERT, "can't add extensible array super block to cache")
+
+ /* Set address of super block to return */
+ ret_value = sblock->addr;
+
+CATCH
+ if(!H5F_addr_defined(ret_value))
+ if(sblock) {
+ /* Release super block's disk space */
+ if(H5F_addr_defined(sblock->addr) && H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, sblock->addr, (hsize_t)sblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to release extensible array super block")
+
+ /* Destroy super block */
+ if(H5EA__sblock_dest(hdr->f, sblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array super block")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5EA__sblock_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_protect
+ *
+ * Purpose: Convenience wrapper around protecting extensible array super block
+ *
+ * Return: Non-NULL pointer to data block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_sblock_t *, NULL, NULL,
+H5EA__sblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t sblk_addr,
+ unsigned sblk_idx, H5AC_protect_t rw))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(sblk_addr));
+
+ /* Protect the super block */
+ if(NULL == (ret_value = (H5EA_sblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblk_addr, &sblk_idx, hdr, rw)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long_long)sblk_addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__sblock_protect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_unprotect
+ *
+ * Purpose: Convenience wrapper around unprotecting extensible array super block
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_unprotect(H5EA_sblock_t *sblock, hid_t dxpl_id, unsigned cache_flags))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(sblock);
+
+ /* Unprotect the super block */
+ if(H5AC_unprotect(sblock->hdr->f, dxpl_id, H5AC_EARRAY_SBLOCK, sblock->addr, sblock, cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect extensible array super block, address = %llu", (unsigned long_long)sblock->addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__sblock_unprotect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_delete
+ *
+ * Purpose: Delete a super block
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t sblk_addr,
+ unsigned sblk_idx))
+
+ /* Local variables */
+ H5EA_sblock_t *sblock = NULL; /* Pointer to super block */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(sblk_addr));
+
+ /* Protect super block */
+ if(NULL == (sblock = H5EA__sblock_protect(hdr, dxpl_id, sblk_addr, sblk_idx, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array super block, address = %llu", (unsigned long_long)sblk_addr)
+
+ /* Check for super block having data block pointers */
+ if(sblock->ndblks > 0) {
+ size_t u; /* Local index variable */
+
+ /* Iterate over data blocks */
+ for(u = 0; u < sblock->ndblks; u++) {
+ /* Check for data block existing */
+ if(H5F_addr_defined(sblock->dblk_addrs[u])) {
+ /* Delete data block */
+ if(H5EA__dblock_delete(hdr, dxpl_id, sblock->dblk_addrs[u], sblock->dblk_nelmts) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array data block")
+ sblock->dblk_addrs[u] = HADDR_UNDEF;
+ } /* end if */
+ } /* end for */
+ } /* end if */
+
+ /* Release super block's disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_SBLOCK, dxpl_id, sblk_addr, (hsize_t)sblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free extensible array super block")
+
+CATCH
+ /* Finished deleting super block in metadata cache */
+ if(sblock && H5EA__sblock_unprotect(sblock, dxpl_id, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array super block")
+
+END_FUNC(PKG) /* end H5EA__sblock_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__sblock_dest
+ *
+ * Purpose: Destroys an extensible array super block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 30 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__sblock_dest(H5F_t *f, H5EA_sblock_t *sblock))
+
+ /* Sanity check */
+ HDassert(sblock);
+ HDassert(sblock->rc == 0);
+
+ /* Set the shared array header's file context for this operation */
+ sblock->hdr->f = f;
+
+ /* Check if we've got data block addresses in the super block */
+ if(sblock->ndblks > 0) {
+ /* Free buffer for super block data block addresses */
+ HDassert(sblock->dblk_addrs);
+ (void)H5FL_SEQ_FREE(haddr_t, sblock->dblk_addrs);
+ } /* end if */
+
+ /* Decrement reference count on shared info */
+ if(H5EA__hdr_decr(sblock->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+
+ /* Free the super block itself */
+ (void)H5FL_FREE(H5EA_sblock_t, sblock);
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__sblock_dest() */
+
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index 1d5e3ae..ef48edd 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -96,14 +96,18 @@ typedef enum H5FD_mem_t {
* Map "extensible array" index blocks to 'ohdr' type file memory, since they
* are similar to extensible array header blocks.
*
- * Map "extensible array" data blocks to 'lheap' type file memory, since they
+ * Map "extensible array" super blocks to 'btree' type file memory, since they
* are similar enough to B-tree nodes.
*
+ * Map "extensible array" data blocks to 'lheap' type file memory, since they
+ * are similar enough to local heap info.
+ *
* -QAK
*/
#define H5FD_MEM_EARRAY_HDR H5FD_MEM_OHDR
#define H5FD_MEM_EARRAY_IBLOCK H5FD_MEM_OHDR
-#define H5FD_MEM_EARRAY_DBLOCK H5FD_MEM_BTREE
+#define H5FD_MEM_EARRAY_SBLOCK H5FD_MEM_BTREE
+#define H5FD_MEM_EARRAY_DBLOCK H5FD_MEM_LHEAP
/*
* A free-list map which maps all types of allocation requests to a single
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index f4d2b6c..cb716fc 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -425,6 +425,7 @@ typedef struct H5F_t H5F_t;
/* Extensible array signatures */
#define H5EA_HDR_MAGIC "EAHD" /* Header */
#define H5EA_IBLOCK_MAGIC "EAIB" /* Index block */
+#define H5EA_SBLOCK_MAGIC "EASB" /* Super block */
#define H5EA_DBLOCK_MAGIC "EADB" /* Data block */
/* Free space signatures */
diff --git a/src/Makefile.am b/src/Makefile.am
index cd8f6ac..9a9673b 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,7 +52,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Distore.c H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
H5E.c H5Edeprec.c H5Eint.c \
H5EA.c H5EAcache.c H5EAdbg.c H5EAdblock.c H5EAhdr.c H5EAiblock.c \
- H5EAint.c H5EAstat.c H5EAtest.c \
+ H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \
H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.c \
H5FD.c H5FDcore.c \
H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 74ca61f..aff05cd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -87,7 +87,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Dint.lo H5Dio.lo H5Distore.lo H5Dmpio.lo H5Doh.lo \
H5Dscatgath.lo H5Dselect.lo H5Dtest.lo H5E.lo H5Edeprec.lo \
H5Eint.lo H5EA.lo H5EAcache.lo H5EAdbg.lo H5EAdblock.lo \
- H5EAhdr.lo H5EAiblock.lo H5EAint.lo H5EAstat.lo H5EAtest.lo \
+ H5EAhdr.lo H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo \
H5F.lo H5Fdbg.lo H5Ffake.lo H5Fmount.lo H5Fsfile.lo \
H5Fsuper.lo H5Ftest.lo H5FD.lo H5FDcore.lo H5FDdirect.lo \
H5FDfamily.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \
@@ -432,7 +432,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Distore.c H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
H5E.c H5Edeprec.c H5Eint.c \
H5EA.c H5EAcache.c H5EAdbg.c H5EAdblock.c H5EAhdr.c H5EAiblock.c \
- H5EAint.c H5EAstat.c H5EAtest.c \
+ H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \
H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.c \
H5FD.c H5FDcore.c \
H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
@@ -649,6 +649,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAhdr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAiblock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAsblock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAstat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Edeprec.Plo@am__quote@
diff --git a/test/earray.c b/test/earray.c
index 3c257e3..5f75596 100644
--- a/test/earray.c
+++ b/test/earray.c
@@ -171,14 +171,14 @@ init_tparam(earray_test_param_t *tparam, const H5EA_create_t *cparam)
start_idx = 0;
start_dblk = 0;
for(u = 0; u < tparam->nsblks; u++) {
- tparam->sblk_info[u].ndblks = (hsize_t)H5_EXP2(u / 2);
+ tparam->sblk_info[u].ndblks = (size_t)H5_EXP2(u / 2);
tparam->sblk_info[u].dblk_nelmts = (size_t)H5_EXP2((u + 1) / 2) * cparam->data_blk_min_elmts;
tparam->sblk_info[u].start_idx = start_idx;
tparam->sblk_info[u].start_dblk = start_dblk;
/* Advance starting indices for next super block */
- start_idx += tparam->sblk_info[u].ndblks * tparam->sblk_info[u].dblk_nelmts;
- start_dblk += tparam->sblk_info[u].ndblks;
+ start_idx += (hsize_t)tparam->sblk_info[u].ndblks * (hsize_t)tparam->sblk_info[u].dblk_nelmts;
+ start_dblk += (hsize_t)tparam->sblk_info[u].ndblks;
} /* end for */
return(0);
@@ -1046,7 +1046,7 @@ test_set_elmts(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam,
/* (same eqn. as in H5EA__dblock_sblk_idx()) */
sblk_idx = H5V_log2_gen((uint64_t)(((idx - cparam->idx_blk_elmts) / cparam->data_blk_min_elmts) + 1));
#ifdef QAK
-HDfprintf(stderr, "idx = %Hu, tparam->sblk_info[%u] = {%Hu, %Zu, %Hu, %Hu}\n", idx, sblk_idx, tparam->sblk_info[sblk_idx].ndblks, tparam->sblk_info[sblk_idx].dblk_nelmts, tparam->sblk_info[sblk_idx].start_idx, tparam->sblk_info[sblk_idx].start_dblk);
+HDfprintf(stderr, "idx = %Hu, tparam->sblk_info[%u] = {%Zu, %Zu, %Hu, %Hu}\n", idx, sblk_idx, tparam->sblk_info[sblk_idx].ndblks, tparam->sblk_info[sblk_idx].dblk_nelmts, tparam->sblk_info[sblk_idx].start_idx, tparam->sblk_info[sblk_idx].start_dblk);
#endif /* QAK */
state.nelmts = (hsize_t)(cparam->idx_blk_elmts +
@@ -1200,6 +1200,9 @@ main(void)
nerrors += test_set_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (11 * cparam.data_blk_min_elmts)), "setting all elements of array's fifth data block");
nerrors += test_set_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (11 * cparam.data_blk_min_elmts) + 1), "setting first element of array's sixth data block");
nerrors += test_set_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (15 * cparam.data_blk_min_elmts)), "setting all elements of array's sixth data block");
+#ifdef NOT_YET
+ nerrors += test_set_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (15 * cparam.data_blk_min_elmts) + 1), "setting first element of array's seventh data block");
+#endif /* NOT_YET */
/* Close down testing parameters */
finish_tparam(&tparam);
diff --git a/tools/misc/h5debug.c b/tools/misc/h5debug.c
index 3b2d38c..e11d3bf 100644
--- a/tools/misc/h5debug.c
+++ b/tools/misc/h5debug.c
@@ -460,6 +460,23 @@ main(int argc, char *argv[])
status = H5EA__iblock_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra);
+ } else if(!HDmemcmp(sig, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible aray super block.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if(extra == 0 || extra2 == 0) {
+ fprintf(stderr, "ERROR: Need extensible array header address and super block index in order to dump super block\n");
+ fprintf(stderr, "Extensible array super block usage:\n");
+ fprintf(stderr, "\th5debug <filename> <super block address> <array header address> <super block index>\n");
+ HDexit(4);
+ } /* end if */
+
+ status = H5EA__sblock_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2);
+
} else if(!HDmemcmp(sig, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
/*
* Debug an extensible aray data block.