diff options
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | src/H5AC.c | 1 | ||||
-rw-r--r-- | src/H5ACprivate.h | 1 | ||||
-rw-r--r-- | src/H5Cpkg.h | 2 | ||||
-rw-r--r-- | src/H5EA.c | 22 | ||||
-rw-r--r-- | src/H5EAcache.c | 326 | ||||
-rw-r--r-- | src/H5EAdbg.c | 84 | ||||
-rw-r--r-- | src/H5EAdblock.c | 16 | ||||
-rw-r--r-- | src/H5EAhdr.c | 8 | ||||
-rw-r--r-- | src/H5EAiblock.c | 8 | ||||
-rw-r--r-- | src/H5EApkg.h | 58 | ||||
-rw-r--r-- | src/H5EAsblock.c | 397 | ||||
-rw-r--r-- | src/H5FDpublic.h | 8 | ||||
-rw-r--r-- | src/H5Fprivate.h | 1 | ||||
-rwxr-xr-x | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 5 | ||||
-rw-r--r-- | test/earray.c | 11 | ||||
-rw-r--r-- | tools/misc/h5debug.c | 17 |
18 files changed, 935 insertions, 33 deletions
@@ -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 @@ -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 @@ -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. |