summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST2
-rw-r--r--src/H5AC.c1
-rw-r--r--src/H5ACprivate.h1
-rw-r--r--src/H5Cpkg.h2
-rw-r--r--src/H5EA.c218
-rw-r--r--src/H5EAcache.c360
-rw-r--r--src/H5EAhdr.c108
-rw-r--r--src/H5EAiblock.c325
-rw-r--r--src/H5EApkg.h71
-rw-r--r--src/H5EAprivate.h13
-rw-r--r--src/H5EAstat.c116
-rw-r--r--src/H5EAtest.c85
-rw-r--r--src/H5FDpublic.h4
-rwxr-xr-xsrc/Makefile.am3
-rw-r--r--src/Makefile.in8
-rw-r--r--test/earray.c80
16 files changed, 1238 insertions, 159 deletions
diff --git a/MANIFEST b/MANIFEST
index af9e64e..d36607e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -501,9 +501,11 @@
./src/H5EA.c
./src/H5EAcache.c
./src/H5EAhdr.c
+./src/H5EAiblock.c
./src/H5EAint.c
./src/H5EApkg.h
./src/H5EAprivate.h
+./src/H5EAstat.c
./src/H5EAtest.c
./src/H5F.c
./src/H5Fdbg.c
diff --git a/src/H5AC.c b/src/H5AC.c
index 83ab0a4..406dad3 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -492,6 +492,7 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] =
"shared OH message master table",
"shared OH message index",
"extensible array headers",
+ "extensible array index blocks",
"test entry" /* for testing only -- not used for actual files */
};
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index da18cd5..9568a79 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -63,6 +63,7 @@ typedef enum {
H5AC_SOHM_TABLE_ID, /*shared object header message master table */
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_TEST_ID, /*test entry -- not used for actual files */
H5AC_NTYPES /* Number of types, must be last */
} H5AC_type_t;
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index c82443b..a2dadf1 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 17
+#define H5C__MAX_NUM_TYPE_IDS 18
#define H5C__PREFIX_LEN 32
struct H5C_t
diff --git a/src/H5EA.c b/src/H5EA.c
index 06a11d2..fa8cd32 100644
--- a/src/H5EA.c
+++ b/src/H5EA.c
@@ -116,7 +116,7 @@ H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam))
haddr_t ea_addr; /* Array header address */
#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Called\n", __func__);
#endif /* QAK */
/*
@@ -134,7 +134,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array info")
/* Lock the array header into memory */
- if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE)))
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cparam->cls, NULL, H5AC_WRITE)))
H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header")
/* Point extensible array wrapper at header and bump it's ref count */
@@ -179,7 +179,7 @@ END_FUNC(PRIV) /* end H5EA_create() */
*/
BEGIN_FUNC(PRIV, ERR,
H5EA_t *, NULL, NULL,
-H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr))
+H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5EA_class_t *cls))
/* Local variables */
H5EA_t *ea = NULL; /* Pointer to new extensible array wrapper */
@@ -190,12 +190,13 @@ H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr))
*/
HDassert(f);
HDassert(H5F_addr_defined(ea_addr));
+ HDassert(cls);
/* Load the array header into memory */
#ifdef QAK
-HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr);
+HDfprintf(stderr, "%s: ea_addr = %a\n", __func__, ea_addr);
#endif /* QAK */
- if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, cls, NULL, H5AC_READ)))
H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header, address = %llu", (unsigned long_long)ea_addr)
/* Check for pending array deletion */
@@ -252,7 +253,7 @@ H5EA_get_nelmts(const H5EA_t *ea, hsize_t *nelmts))
/* Local variables */
#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Called\n", __func__);
#endif /* QAK */
/*
@@ -261,8 +262,8 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
HDassert(ea);
HDassert(nelmts);
- /* Placeholder value */
- *nelmts = 0;
+ /* Retrieve the max. index set */
+ *nelmts = ea->hdr->max_idx_set;
END_FUNC(PRIV) /* end H5EA_get_nelmts() */
@@ -287,7 +288,7 @@ H5EA_get_addr(const H5EA_t *ea, haddr_t *addr))
/* Local variables */
#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Called\n", __func__);
#endif /* QAK */
/*
@@ -304,93 +305,159 @@ END_FUNC(PRIV) /* end H5EA_get_addr() */
/*-------------------------------------------------------------------------
- * Function: H5EA_get_stats
+ * Function: H5EA_set
*
- * Purpose: Query the metadata stats of an array
+ * Purpose: Set an element of an extensible array
*
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
- * Aug 21 2008
+ * Sep 9 2008
*
*-------------------------------------------------------------------------
*/
-BEGIN_FUNC(PRIV, NOERR,
-herr_t, SUCCEED, -,
-H5EA_get_stats(const H5EA_t *ea, H5EA_stat_t *stats))
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt))
/* Local variables */
+ H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
+ H5EA_iblock_t *iblock = NULL; /* Pointer to index block for EA */
+ hbool_t hdr_dirty = FALSE; /* Whether header information changed */
#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Called\n", __func__);
+HDfprintf(stderr, "%s: Index %Hu\n", __func__, idx);
#endif /* QAK */
/*
* Check arguments.
*/
HDassert(ea);
- HDassert(stats);
+ HDassert(ea->hdr);
- /* Placeholder value */
- HDmemset(stats, 0, sizeof(*stats));
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
-END_FUNC(PRIV) /* end H5EA_get_stats() */
+ /* Check if we should create the index block */
+ if(!H5F_addr_defined(hdr->idx_blk_addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Index block address not defined!\n", __func__, idx);
+#endif /* QAK */
+ /* Create the index block */
+ hdr->idx_blk_addr = H5EA__iblock_create(hdr, dxpl_id);
+ if(!H5F_addr_defined(hdr->idx_blk_addr))
+ H5E_THROW(H5E_CANTCREATE, "unable to create index block")
+
+ /* Mark the header dirty */
+ hdr_dirty = TRUE;
+ } /* end if */
+#ifdef QAK
+HDfprintf(stderr, "%s: Index block address is: %a\n", __func__, hdr->idx_blk_addr);
+#endif /* QAK */
+
+ /* Protect index block */
+ if(NULL == (iblock = H5EA__iblock_protect(hdr, dxpl_id, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array index block, address = %llu", (unsigned long_long)hdr->idx_blk_addr)
+
+ /* Determine where the element to set falls */
+ if(idx < hdr->idx_blk_elmts) {
+ /* Set element in index block */
+ HDmemcpy(((uint8_t *)iblock->elmts) + (hdr->cls->nat_elmt_size * idx), elmt, hdr->cls->nat_elmt_size);
+ } /* end if */
+ else {
+HDfprintf(stderr, "%s: Index %Hu not supported yet!\n", __func__, idx);
+HDassert(0 && "Index location not supported!");
+ } /* end else */
+
+ /* Update max. element set in array, if appropriate */
+ if(idx >= hdr->max_idx_set) {
+ hdr->max_idx_set = idx + 1;
+ hdr_dirty = TRUE;
+ } /* end if */
+
+CATCH
+ /* Check for header modified */
+ if(hdr_dirty)
+ if(H5EA__hdr_modified(hdr) < 0)
+ H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark extensible array header as modified")
+
+ if(iblock && H5EA__iblock_unprotect(iblock, dxpl_id, H5AC__DIRTIED_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array index block")
+
+END_FUNC(PRIV) /* end H5EA_set() */
/*-------------------------------------------------------------------------
- * Function: H5EA_delete
+ * Function: H5EA_get
*
- * Purpose: Delete an extensible array
+ * Purpose: Get an element of an extensible array
*
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
- * Aug 28 2008
+ * Sep 11 2008
*
*-------------------------------------------------------------------------
*/
BEGIN_FUNC(PRIV, ERR,
herr_t, SUCCEED, FAIL,
-H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr))
+H5EA_get(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt))
/* Local variables */
- H5EA_hdr_t *hdr = NULL; /* The fractal heap header information */
+ H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
+ H5EA_iblock_t *iblock = NULL; /* Pointer to index block for EA */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", __func__);
+HDfprintf(stderr, "%s: Index %Hu\n", __func__, idx);
+#endif /* QAK */
/*
* Check arguments.
*/
- HDassert(f);
- HDassert(H5F_addr_defined(ea_addr));
+ HDassert(ea);
+ HDassert(ea->hdr);
- /* Lock the array header into memory */
+ /* Set the shared array header's file context for this operation */
+ hdr->f = ea->f;
+
+ /* Check for element beyond max. element in array */
+ if(idx >= hdr->max_idx_set) {
#ifdef QAK
-HDfprintf(stderr, "%s: ea_addr = %a\n", FUNC, ea_addr);
+HDfprintf(stderr, "%s: Element beyond max. index set\n", __func__, idx);
#endif /* QAK */
- if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE)))
- H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array header, address = %llu", (unsigned long_long)ea_addr)
-
- /* Check for files using shared array header */
- if(hdr->file_rc)
- hdr->pending_delete = TRUE;
+ /* Call the class's 'fill' callback */
+ if((hdr->cls->fill)(elmt, (size_t)1) < 0)
+ H5E_THROW(H5E_CANTSET, "can't set element to class's fill value")
+ } /* end if */
else {
- /* Set the shared array header's file context for this operation */
- hdr->f = f;
+#ifdef QAK
+HDfprintf(stderr, "%s: Index block address is: %a\n", __func__, hdr->idx_blk_addr);
+#endif /* QAK */
- /* Delete array now, starting with header (unprotects header) */
- if(H5EA__hdr_delete(hdr, dxpl_id) < 0)
- H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array")
- hdr = NULL;
- } /* end if */
+ /* Protect index block */
+ if(NULL == (iblock = H5EA__iblock_protect(hdr, dxpl_id, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array index block, address = %llu", (unsigned long_long)hdr->idx_blk_addr)
-CATCH
+ /* Determine where the element to set falls */
+ if(idx < hdr->idx_blk_elmts) {
+ /* Get element from index block */
+ HDmemcpy(elmt, ((uint8_t *)iblock->elmts) + (hdr->cls->nat_elmt_size * idx), hdr->cls->nat_elmt_size);
+ } /* end if */
+ else {
+HDfprintf(stderr, "%s: Index %Hu not supported yet!\n", __func__, idx);
+HDassert(0 && "Index location not supported!");
+ } /* end else */
+ } /* end else */
- /* Unprotect the header, if an error occurred */
- if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
- H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+CATCH
+ if(iblock && H5EA__iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array index block")
-END_FUNC(PRIV) /* end H5EA_delete() */
+END_FUNC(PRIV) /* end H5EA_set() */
/*-------------------------------------------------------------------------
@@ -415,7 +482,7 @@ H5EA_close(H5EA_t *ea, hid_t dxpl_id))
haddr_t ea_addr = HADDR_UNDEF; /* Address of array (for deletion) */
#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Called\n", __func__);
#endif /* QAK */
/*
@@ -470,3 +537,58 @@ CATCH
END_FUNC(PRIV) /* end H5EA_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_delete
+ *
+ * Purpose: Delete an extensible array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 28 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* The fractal heap header information */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(ea_addr));
+
+ /* Lock the array header into memory */
+#ifdef QAK
+HDfprintf(stderr, "%s: ea_addr = %a\n", __func__, ea_addr);
+#endif /* QAK */
+ if(NULL == (hdr = (H5EA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, NULL, NULL, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array header, address = %llu", (unsigned long_long)ea_addr)
+
+ /* Check for files using shared array header */
+ if(hdr->file_rc)
+ hdr->pending_delete = TRUE;
+ else {
+ /* Set the shared array header's file context for this operation */
+ hdr->f = f;
+
+ /* Delete array now, starting with header (unprotects header) */
+ if(H5EA__hdr_delete(hdr, dxpl_id) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array")
+ hdr = NULL;
+ } /* end if */
+
+CATCH
+
+ /* Unprotect the header, if an error occurred */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_EARRAY_HDR, ea_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header")
+
+END_FUNC(PRIV) /* end H5EA_delete() */
+
diff --git a/src/H5EAcache.c b/src/H5EAcache.c
index a6e8178..6e141e9 100644
--- a/src/H5EAcache.c
+++ b/src/H5EAcache.c
@@ -52,9 +52,11 @@
/* Fractal heap format version #'s */
#define H5EA_HDR_VERSION 0 /* Header */
+#define H5EA_IBLOCK_VERSION 0 /* Index block */
-/* Size of stack buffer for serialized headers */
+/* Size of stack buffer for serialization buffers */
#define H5EA_HDR_BUF_SIZE 512
+#define H5EA_IBLOCK_BUF_SIZE 512
/******************/
@@ -76,6 +78,10 @@ static H5EA_hdr_t *H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, c
static herr_t H5EA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_hdr_t *hdr, unsigned UNUSED * flags_ptr);
static herr_t H5EA__cache_hdr_clear(H5F_t *f, H5EA_hdr_t *hdr, hbool_t destroy);
static herr_t H5EA__cache_hdr_size(const H5F_t *f, const H5EA_hdr_t *hdr, size_t *size_ptr);
+static H5EA_iblock_t *H5EA__cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
+static herr_t H5EA__cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_iblock_t *iblock, unsigned UNUSED * flags_ptr);
+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);
/*********************/
@@ -92,6 +98,16 @@ const H5AC_class_t H5AC_EARRAY_HDR[1] = {{
(H5AC_size_func_t)H5EA__cache_hdr_size,
}};
+/* H5EA index block inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_EARRAY_IBLOCK[1] = {{
+ H5AC_EARRAY_IBLOCK_ID,
+ (H5AC_load_func_t)H5EA__cache_iblock_load,
+ (H5AC_flush_func_t)H5EA__cache_iblock_flush,
+ (H5AC_dest_func_t)H5EA__cache_iblock_dest,
+ (H5AC_clear_func_t)H5EA__cache_iblock_clear,
+ (H5AC_size_func_t)H5EA__cache_iblock_size,
+}};
+
/*****************************/
/* Library Private Variables */
@@ -105,7 +121,7 @@ const H5AC_class_t H5AC_EARRAY_HDR[1] = {{
/*-------------------------------------------------------------------------
- * Function: H5EA_cache_hdr_load
+ * Function: H5EA__cache_hdr_load
*
* Purpose: Loads an extensible array header from the disk.
*
@@ -120,9 +136,11 @@ const H5AC_class_t H5AC_EARRAY_HDR[1] = {{
*/
BEGIN_FUNC(STATIC, ERR,
H5EA_hdr_t *, NULL, NULL,
-H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2))
+H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, void UNUSED *udata2))
- H5EA_hdr_t *hdr = NULL; /* Fractal heap info */
+ /* Local variables */
+ const H5EA_class_t *cls = (const H5EA_class_t *)_cls; /* Extensible array class */
+ H5EA_hdr_t *hdr = NULL; /* Extensible array info */
size_t size; /* Header size */
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5EA_HDR_BUF_SIZE]; /* Buffer for header */
@@ -136,17 +154,17 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *u
HDassert(H5F_addr_defined(addr));
/* Allocate space for the extensible array data structure */
- if(NULL == (hdr = H5EA__hdr_alloc(f)))
+ if(NULL == (hdr = H5EA__hdr_alloc(f, cls)))
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header")
/* Set the extensible array header's address */
hdr->addr = addr;
- /* Wrap the local buffer for serialized header info */
+ /* Wrap the local buffer for serialized info */
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
- /* Compute the 'base' size of the fractal heap header on disk */
+ /* Compute the 'base' size of the extensible array header on disk */
size = H5EA_HEADER_SIZE(hdr);
/* Get a pointer to a buffer that's large enough for serialized header */
@@ -176,6 +194,10 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *u
hdr->data_blk_min_elmts = *p++; /* Min. # of elements per data block */
hdr->sup_blk_min_data_ptrs = *p++; /* Min. # of data block pointers for a super block */
+ /* Internal information */
+ H5F_addr_decode(f, &p, &hdr->idx_blk_addr); /* Address of index block */
+ H5F_DECODE_LENGTH(f, p, hdr->max_idx_set); /* Max. index set (+1) */
+
/* Sanity check */
/* (allow for checksum not decoded yet) */
HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM));
@@ -247,7 +269,7 @@ H5EA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
- /* Compute the size of the heap header on disk */
+ /* Compute the size of the array header on disk */
size = hdr->size;
/* Get a pointer to a buffer that's large enough for serialized header */
@@ -271,6 +293,10 @@ H5EA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5
*p++ = hdr->data_blk_min_elmts; /* Min. # of elements per data block */
*p++ = hdr->sup_blk_min_data_ptrs; /* Min. # of data block pointers for a super block */
+ /* Internal information */
+ H5F_addr_encode(f, &p, hdr->idx_blk_addr); /* Address of index block */
+ H5F_ENCODE_LENGTH(f, p, hdr->max_idx_set); /* Max. index set (+1) */
+
/* Compute metadata checksum */
metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
@@ -392,3 +418,321 @@ H5EA__cache_hdr_size(const H5F_t UNUSED *f, const H5EA_hdr_t *hdr, size_t *size_
END_FUNC(STATIC) /* end H5EA__cache_hdr_size() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_iblock_load
+ *
+ * Purpose: Loads an extensible array index block from the disk.
+ *
+ * Return: Success: Pointer to a new extensible array index block
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+H5EA_iblock_t *, NULL, NULL,
+H5EA__cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *_hdr))
+
+ /* Local variables */
+ H5EA_hdr_t *hdr = (H5EA_hdr_t *)_hdr; /* Shared extensible array information */
+ H5EA_iblock_t *iblock = NULL; /* Index block info */
+ size_t size; /* Index block size */
+ H5WB_t *wb = NULL; /* Wrapped buffer for index block data */
+ uint8_t iblock_buf[H5EA_IBLOCK_BUF_SIZE]; /* Buffer for index block */
+ uint8_t *buf; /* Pointer to index 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(hdr);
+
+ /* Allocate the extensible array index block */
+ if(NULL == (iblock = H5EA__iblock_alloc(hdr)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header")
+
+ /* Share common array information */
+ iblock->hdr = hdr;
+ if(H5EA__hdr_incr(hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header")
+
+ /* Set the extensible array index block's address */
+ iblock->addr = addr;
+
+ /* Wrap the local buffer for serialized info */
+ if(NULL == (wb = H5WB_wrap(iblock_buf, sizeof(iblock_buf))))
+ H5E_THROW(H5E_CANTINIT, "can't wrap buffer")
+
+ /* Compute the size of the extensible array index block on disk */
+ size = H5EA_IBLOCK_SIZE(hdr);
+
+ /* 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 index block from disk */
+ if(H5F_block_read(f, H5FD_MEM_EARRAY_IBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_READERROR, "can't read extensible array index block")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Magic number */
+ if(HDmemcmp(p, H5EA_IBLOCK_MAGIC, (size_t)H5EA_SIZEOF_MAGIC))
+ H5E_THROW(H5E_BADVALUE, "wrong extensible array index block signature")
+ p += H5EA_SIZEOF_MAGIC;
+
+ /* Version */
+ if(*p++ != H5EA_IBLOCK_VERSION)
+ H5E_THROW(H5E_VERSION, "wrong extensible array index block version")
+
+ /* Internal information */
+
+ /* Decode elements in index block */
+ if(hdr->idx_blk_elmts > 0) {
+ /* Convert from raw elements on disk into native elements in memory */
+ if((hdr->cls->decode)(p, iblock->elmts, (size_t)hdr->idx_blk_elmts) < 0)
+ H5E_THROW(H5E_CANTDECODE, "can't decode extensible array index elements")
+ p += (hdr->idx_blk_elmts * hdr->raw_elmt_size);
+ } /* end if */
+
+ /* Sanity check */
+ /* (allow for checksum not decoded yet) */
+ HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM));
+
+ /* Save the index block's size */
+ iblock->size = size;
+
+ /* Compute checksum on index 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) == iblock->size);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array index block")
+
+ /* Set return value */
+ ret_value = iblock;
+
+CATCH
+
+ /* Release resources */
+ if(wb && H5WB_unwrap(wb) < 0)
+ H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer")
+ if(!ret_value)
+ if(iblock && H5EA__cache_iblock_dest(f, iblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array index block")
+
+END_FUNC(STATIC) /* end H5EA__cache_iblock_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_iblock_flush
+ *
+ * Purpose: Flushes a dirty extensible array index block to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_iblock_t *iblock, unsigned UNUSED * flags_ptr))
+
+ /* Local variables */
+ H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */
+ uint8_t ser_buf[H5EA_HDR_BUF_SIZE]; /* Serialization buffer */
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(iblock);
+ HDassert(iblock->hdr);
+
+ if(iblock->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 index block on disk */
+ size = iblock->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_IBLOCK_MAGIC, (size_t)H5EA_SIZEOF_MAGIC);
+ p += H5EA_SIZEOF_MAGIC;
+
+ /* Version # */
+ *p++ = H5EA_IBLOCK_VERSION;
+
+ /* Internal information */
+
+ /* Encode elements in index block */
+ if(iblock->hdr->idx_blk_elmts > 0) {
+ /* Convert from native elements in memory into raw elements on disk */
+ if((iblock->hdr->cls->encode)(p, iblock->elmts, (size_t)iblock->hdr->idx_blk_elmts) < 0)
+ H5E_THROW(H5E_CANTENCODE, "can't encode extensible array index elements")
+ p += (iblock->hdr->idx_blk_elmts * iblock->hdr->raw_elmt_size);
+ } /* end if */
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Write the index block */
+ HDassert((size_t)(p - buf) == size);
+ if(H5F_block_write(f, H5FD_MEM_EARRAY_IBLOCK, addr, size, dxpl_id, buf) < 0)
+ H5E_THROW(H5E_WRITEERROR, "unable to save extensible array index block to disk")
+
+ iblock->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if(destroy)
+ if(H5EA__cache_iblock_dest(f, iblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array index 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_iblock_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_iblock_dest
+ *
+ * Purpose: Destroys a extensible array index block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_iblock_dest(H5F_t UNUSED *f, H5EA_iblock_t *iblock))
+
+ /* Sanity check */
+ HDassert(iblock);
+ HDassert(iblock->rc == 0);
+
+ /* Set the shared array header's file context for this operation */
+ iblock->hdr->f = f;
+
+ /* Check if we've got elements in the index block */
+ if(iblock->hdr->idx_blk_elmts > 0) {
+ /* Free buffer for index block elements */
+ HDassert(iblock->elmts);
+ (void)H5FL_BLK_FREE(elmt_buf, iblock->elmts);
+ } /* end if */
+
+ /* Decrement reference count on shared info */
+ if(H5EA__hdr_decr(iblock->hdr) < 0)
+ H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header")
+
+ /* Free the index block itself */
+ (void)H5FL_FREE(H5EA_iblock_t, iblock);
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__cache_iblock_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_iblock_clear
+ *
+ * Purpose: Mark a extensible array index block in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sept 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(STATIC, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__cache_iblock_clear(H5F_t *f, H5EA_iblock_t *iblock, hbool_t destroy))
+
+ /*
+ * Check arguments.
+ */
+ HDassert(iblock);
+
+ /* Reset the dirty flag */
+ iblock->cache_info.is_dirty = FALSE;
+
+ if(destroy)
+ if(H5EA__cache_iblock_dest(f, iblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array index block")
+
+CATCH
+
+END_FUNC(STATIC) /* end H5EA__cache_iblock_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__cache_iblock_size
+ *
+ * Purpose: Compute the size in bytes of a extensible array index 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 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+BEGIN_FUNC(STATIC, NOERR,
+herr_t, SUCCEED, -,
+H5EA__cache_iblock_size(const H5F_t UNUSED *f, const H5EA_iblock_t *iblock, size_t *size_ptr))
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(iblock);
+ HDassert(size_ptr);
+
+ /* Set size value */
+ *size_ptr = iblock->size;
+
+END_FUNC(STATIC) /* end H5EA__cache_iblock_size() */
+
diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c
index 5fbcaf9..9ccec62 100644
--- a/src/H5EAhdr.c
+++ b/src/H5EAhdr.c
@@ -52,6 +52,7 @@
/* Max. # of bits for max. nelmts index */
#define H5EA_MAX_NELMTS_IDX_MAX 64
+
/******************/
/* Local Typedefs */
/******************/
@@ -101,14 +102,14 @@ H5FL_DEFINE(H5EA_hdr_t);
*/
BEGIN_FUNC(PKG, ERR,
H5EA_hdr_t *, NULL, NULL,
-H5EA__hdr_alloc(H5F_t *f))
+H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls))
- H5EA_hdr_t *hdr = NULL; /* Shared fractal heap header */
+ /* Local variables */
+ H5EA_hdr_t *hdr = NULL; /* Shared extensible array header */
- /*
- * Check arguments.
- */
+ /* Check arguments */
HDassert(f);
+ HDassert(cls);
/* Allocate space for the shared information */
if(NULL == (hdr = H5FL_CALLOC(H5EA_hdr_t)))
@@ -116,6 +117,11 @@ H5EA__hdr_alloc(H5F_t *f))
/* Set the internal parameters for the array */
hdr->f = f;
+ hdr->sizeof_addr = H5F_SIZEOF_ADDR(f);
+ hdr->sizeof_size = H5F_SIZEOF_SIZE(f);
+
+ /* Set the class of the array */
+ hdr->cls = cls;
/* Set the return value */
ret_value = hdr;
@@ -129,7 +135,7 @@ END_FUNC(PKG) /* end H5EA__hdr_alloc() */
/*-------------------------------------------------------------------------
- * Function: H5EA_hdr_create
+ * Function: H5EA__hdr_create
*
* Purpose: Creates a new extensible array header in the file
*
@@ -145,15 +151,14 @@ BEGIN_FUNC(PKG, ERR,
haddr_t, HADDR_UNDEF, HADDR_UNDEF,
H5EA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam))
+ /* Local variables */
H5EA_hdr_t *hdr; /* Extensible array header */
#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
+HDfprintf(stderr, "%s: Called\n", __func__);
#endif /* QAK */
- /*
- * Check arguments.
- */
+ /* Check arguments */
HDassert(f);
HDassert(cparam);
@@ -172,10 +177,11 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
#endif /* NDEBUG */
/* Allocate space for the shared information */
- if(NULL == (hdr = H5EA__hdr_alloc(f)))
+ if(NULL == (hdr = H5EA__hdr_alloc(f, cparam->cls)))
H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array shared header")
/* Set the internal parameters for the array */
+ hdr->idx_blk_addr = HADDR_UNDEF;
/* Set the creation parameters for the array */
hdr->raw_elmt_size = cparam->raw_elmt_size;
@@ -198,14 +204,13 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
/* Set address of array header to return */
ret_value = hdr->addr;
-
CATCH
END_FUNC(PKG) /* end H5EA__hdr_create() */
/*-------------------------------------------------------------------------
- * Function: H5EA_hdr_incr
+ * Function: H5EA__hdr_incr
*
* Purpose: Increment component reference count on shared array header
*
@@ -238,7 +243,7 @@ END_FUNC(PKG) /* end H5EA__hdr_incr() */
/*-------------------------------------------------------------------------
- * Function: H5EA_hdr_decr
+ * Function: H5EA__hdr_decr
*
* Purpose: Decrement component reference count on shared array header
*
@@ -274,7 +279,7 @@ END_FUNC(PKG) /* end H5EA__hdr_decr() */
/*-------------------------------------------------------------------------
- * Function: H5EA_hdr_fuse_incr
+ * Function: H5EA__hdr_fuse_incr
*
* Purpose: Increment file reference count on shared array header
*
@@ -300,7 +305,7 @@ END_FUNC(PKG) /* end H5EA__hdr_fuse_incr() */
/*-------------------------------------------------------------------------
- * Function: H5EA_hdr_fuse_decr
+ * Function: H5EA__hdr_fuse_decr
*
* Purpose: Decrement file reference count on shared array header
*
@@ -330,6 +335,36 @@ END_FUNC(PKG) /* end H5EA__hdr_fuse_decr() */
/*-------------------------------------------------------------------------
+ * Function: H5EA__hdr_modified
+ *
+ * Purpose: Mark an extensible array as modified
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__hdr_modified(H5EA_hdr_t *hdr))
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->f);
+
+ /* Mark header as dirty in cache */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0)
+ H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark extensible array header as dirty")
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__hdr_modified() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5EA__hdr_delete
*
* Purpose: Delete an extensible array, starting with the header
@@ -346,9 +381,7 @@ BEGIN_FUNC(PKG, ERR,
herr_t, SUCCEED, FAIL,
H5EA__hdr_delete(H5EA_hdr_t *hdr, hid_t dxpl_id))
- /*
- * Check arguments.
- */
+ /* Sanity check */
HDassert(hdr);
HDassert(!hdr->file_rc);
@@ -366,40 +399,15 @@ H5EA__hdr_delete(H5EA_hdr_t *hdr, hid_t dxpl_id))
} /* end block */
#endif /* NDEBUG */
-#ifdef LATER
- /* Check for root direct/indirect block */
- if(H5F_addr_defined(hdr->man_dtable.table_addr)) {
+ /* Check for index block */
+ if(H5F_addr_defined(hdr->idx_blk_addr)) {
#ifdef QAK
-HDfprintf(stderr, "%s: hdr->man_dtable.table_addr = %a\n", FUNC, hdr->man_dtable.table_addr);
+HDfprintf(stderr, "%s: hdr->idx_blk_addr = %a\n", __func__, hdr->idx_blk_addr);
#endif /* QAK */
- if(hdr->man_dtable.curr_root_rows == 0) {
- hsize_t dblock_size; /* Size of direct block */
-
- /* Check for I/O filters on this heap */
- if(hdr->filter_len > 0) {
- dblock_size = (hsize_t)hdr->pline_root_direct_size;
-#ifdef QAK
-HDfprintf(stderr, "%s: hdr->pline_root_direct_size = %Zu\n", FUNC, hdr->pline_root_direct_size);
-#endif /* QAK */
-
- /* Reset the header's pipeline information */
- hdr->pline_root_direct_size = 0;
- hdr->pline_root_direct_filter_mask = 0;
- } /* end else */
- else
- dblock_size = (hsize_t)hdr->man_dtable.cparam.start_block_size;
-
- /* Delete root direct block */
- if(H5HF_man_dblock_delete(hdr->f, dxpl_id, hdr->man_dtable.table_addr, dblock_size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap root direct block")
- } /* end if */
- else {
- /* Delete root indirect block */
- if(H5HF_man_iblock_delete(hdr, dxpl_id, hdr->man_dtable.table_addr, hdr->man_dtable.curr_root_rows, NULL, 0) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap root indirect block")
- } /* end else */
+ /* Delete index block */
+ if(H5EA__iblock_delete(hdr, dxpl_id) < 0)
+ H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array index block")
} /* end if */
-#endif /* LATER */
/* Release header's disk space */
if(H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_HDR, dxpl_id, hdr->addr, (hsize_t)hdr->size) < 0)
diff --git a/src/H5EAiblock.c b/src/H5EAiblock.c
new file mode 100644
index 0000000..2e924a9
--- /dev/null
+++ b/src/H5EAiblock.c
@@ -0,0 +1,325 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAiblock.c
+ * Sep 9 2008
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Index 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 "H5MFprivate.h" /* File memory management */
+
+
+/****************/
+/* 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(H5EA_iblock_t);
+
+/* Declare a free list to manage the index block elements */
+H5FL_BLK_DEFINE(elmt_buf);
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_alloc
+ *
+ * Purpose: Allocate shared extensible array index block
+ *
+ * Return: Non-NULL pointer to index block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_iblock_t *, NULL, NULL,
+H5EA__iblock_alloc(H5EA_hdr_t *hdr))
+
+ /* Local variables */
+ H5EA_iblock_t *iblock = NULL; /* Extensible array index block */
+
+ /* Check arguments */
+ HDassert(hdr);
+
+ /* Allocate memory for the index block */
+ if(NULL == (iblock = H5FL_CALLOC(H5EA_iblock_t)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array index block")
+
+ /* Set non-zero internal fields */
+ iblock->addr = HADDR_UNDEF;
+
+ /* Allocate buffer for elements in index block */
+ if(hdr->idx_blk_elmts > 0)
+ if(NULL == (iblock->elmts = H5FL_BLK_MALLOC(elmt_buf, (size_t)(hdr->idx_blk_elmts * hdr->cls->nat_elmt_size))))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for index block data element buffer")
+
+ /* Set the return value */
+ ret_value = iblock;
+
+CATCH
+ if(!ret_value)
+ if(iblock && H5EA__cache_iblock_dest(hdr->f, iblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array index block")
+
+END_FUNC(PKG) /* end H5EA__iblock_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_create
+ *
+ * Purpose: Creates a new extensible array index block in the file
+ *
+ * Return: Valid file address on success/HADDR_UNDEF on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+haddr_t, HADDR_UNDEF, HADDR_UNDEF,
+H5EA__iblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id))
+
+ /* Local variables */
+ H5EA_iblock_t *iblock = NULL; /* Extensible array index block */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", __func__);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Allocate the index block */
+ if(NULL == (iblock = H5EA__iblock_alloc(hdr)))
+ H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array index block")
+
+ /* Set size of header on disk */
+ iblock->size = H5EA_IBLOCK_SIZE(hdr);
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->size = %Zu\n", __func__, iblock->size);
+#endif /* QAK */
+
+ /* Allocate space for the index block on disk */
+ if(HADDR_UNDEF == (iblock->addr = H5MF_alloc(hdr->f, H5FD_MEM_EARRAY_IBLOCK, dxpl_id, iblock->size)))
+ H5E_THROW(H5E_CANTALLOC, "file allocation failed for extensible array index block")
+
+ /* Share common array information */
+ iblock->hdr = hdr;
+ if(H5EA__hdr_incr(hdr) < 0)
+ H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header")
+
+ /* Clear any elements in index block to fill value */
+ if(hdr->idx_blk_elmts > 0) {
+ /* Call the class's 'fill' callback */
+ if((hdr->cls->fill)(iblock->elmts, (size_t)hdr->idx_blk_elmts) < 0)
+ H5E_THROW(H5E_CANTSET, "can't set extensible array index block elements to class's fill value")
+ } /* end if */
+
+ /* Cache the new extensible array index block */
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_IBLOCK, iblock->addr, iblock, 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 */
+ ret_value = iblock->addr;
+
+CATCH
+ if(!H5F_addr_defined(ret_value))
+ if(iblock) {
+ /* Release index block's disk space */
+ if(H5F_addr_defined(iblock->addr) && H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to release extensible array index block")
+
+ /* Destroy index block */
+ if(H5EA__cache_iblock_dest(hdr->f, iblock) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array index block")
+ } /* end if */
+
+END_FUNC(PKG) /* end H5EA__iblock_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_protect
+ *
+ * Purpose: Convenience wrapper around protecting extensible array index block
+ *
+ * Return: Non-NULL pointer to index block on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+H5EA_iblock_t *, NULL, NULL,
+H5EA__iblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, H5AC_protect_t rw))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", __func__);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Protect the index block */
+ if(NULL == (ret_value = (H5EA_iblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_IBLOCK, hdr->idx_blk_addr, NULL, hdr, rw)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array index block, address = %llu", (unsigned long_long)hdr->idx_blk_addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__iblock_protect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_unprotect
+ *
+ * Purpose: Convenience wrapper around unprotecting extensible array index block
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__iblock_unprotect(H5EA_iblock_t *iblock, hid_t dxpl_id, unsigned cache_flags))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", __func__);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(iblock);
+
+ /* Unprotect the index block */
+ if(H5AC_unprotect(iblock->hdr->f, dxpl_id, H5AC_EARRAY_IBLOCK, iblock->addr, iblock, cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect extensible array index block, address = %llu", (unsigned long_long)iblock->addr)
+
+CATCH
+
+END_FUNC(PKG) /* end H5EA__iblock_unprotect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA__iblock_delete
+ *
+ * Purpose: Delete index block
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Sep 9 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PKG, ERR,
+herr_t, SUCCEED, FAIL,
+H5EA__iblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id))
+
+ /* Local variables */
+ H5EA_iblock_t *iblock = NULL; /* Pointer to index block */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", __func__);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(H5F_addr_defined(hdr->idx_blk_addr));
+
+ /* Protect index block */
+ if(NULL == (iblock = H5EA__iblock_protect(hdr, dxpl_id, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array index block, address = %llu", (unsigned long_long)hdr->idx_blk_addr)
+
+ /* Iterate over data blocks & super blocks (not yet) */
+
+ /* Release index block's disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_EARRAY_IBLOCK, dxpl_id, hdr->idx_blk_addr, (hsize_t)iblock->size) < 0)
+ H5E_THROW(H5E_CANTFREE, "unable to free extensible array index block")
+
+CATCH
+ /* Finished deleting index block in metadata cache */
+ if(iblock && H5EA__iblock_unprotect(iblock, dxpl_id, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array index block")
+
+END_FUNC(PKG) /* end H5EA__iblock_delete() */
+
diff --git a/src/H5EApkg.h b/src/H5EApkg.h
index 33131bd..b0f351f 100644
--- a/src/H5EApkg.h
+++ b/src/H5EApkg.h
@@ -341,8 +341,14 @@ func_init_failed: \
/* Size of signature information (on disk) */
#define H5EA_SIZEOF_MAGIC 4
-/* Fractal heap signatures */
+/* Fill value for extensible array test class */
+#ifdef H5EA_TESTING
+#define H5EA_TEST_FILL ((uint64_t)ULLONG_MAX)
+#endif /* H5EA_TESTING */
+
+/* Extensible array signatures */
#define H5EA_HDR_MAGIC "EAHD" /* Header */
+#define H5EA_IBLOCK_MAGIC "EAIB" /* Index block */
/* Size of checksum information (on disk) */
#define H5EA_SIZEOF_CHKSUM 4
@@ -359,14 +365,25 @@ func_init_failed: \
/* General metadata fields */ \
H5EA_METADATA_PREFIX_SIZE(TRUE) \
\
- /* Extensible Array Header specific fields */ \
- \
/* General heap information */ \
+ 1 /* Element Size */ \
+ 1 /* Max. # of elements bits */ \
+ 1 /* # of elements to store in index block */ \
+ 1 /* Min. # elements per data block */ \
+ 1 /* Min. # of data block pointers for a super block */ \
+ \
+ /* Extensible Array Header specific fields */ \
+ + (h)->sizeof_addr /* File address of index block */ \
+ + (h)->sizeof_size /* Max. index set */ \
+ )
+
+/* Size of the extensible array index block on disk */
+#define H5EA_IBLOCK_SIZE(h) ( \
+ /* General metadata fields */ \
+ H5EA_METADATA_PREFIX_SIZE(TRUE) \
+ \
+ /* Extensible Array Index Block specific fields */ \
+ + (size_t)((h)->idx_blk_elmts * (h)->raw_elmt_size) /* Elements in index block */ \
)
@@ -389,6 +406,12 @@ typedef struct H5EA_hdr_t {
uint8_t data_blk_min_elmts; /* Min. # of elements per data block */
uint8_t sup_blk_min_data_ptrs; /* Min. # of data block pointers for a super block */
+ /* Index block information (stored in header) */
+ haddr_t idx_blk_addr; /* Address of index block in header */
+
+ /* Statistics for array (stored in header) */
+ hsize_t max_idx_set; /* Highest element index stored (+1 - i.e. if element 0 has been set, this value with be '1', if no elements have been stored, this value will be '0') */
+
/* Computed/cached values */
size_t rc; /* Reference count of heap's components using heap header */
haddr_t addr; /* Address of header in file */
@@ -396,8 +419,28 @@ typedef struct H5EA_hdr_t {
H5F_t *f; /* Pointer to file for extensible array */
size_t file_rc; /* Reference count of files using array header */
hbool_t pending_delete; /* Array is pending deletion */
+ size_t sizeof_addr; /* Size of file addresses */
+ size_t sizeof_size; /* Size of file sizes */
+
+ /* Memory data structures (not stored directly) */
+ const H5EA_class_t *cls; /* Pointer to class for array */
} H5EA_hdr_t;
+/* The extensible array index block information */
+typedef struct H5EA_iblock_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
+ /* Extensible array information (stored) */
+ void *elmts; /* Buffer for elements stored in index 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 */
+} H5EA_iblock_t;
+
/* Extensible array */
struct H5EA_t {
H5EA_hdr_t *hdr; /* Pointer to internal extensible array header info */
@@ -412,9 +455,18 @@ struct H5EA_t {
/* H5EA header inherits cache-like properties from H5AC */
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];
+
/* Declare a free list to manage the H5EA_hdr_t struct */
H5FL_EXTERN(H5EA_hdr_t);
+/* Declare a free list to manage the H5EA_iblock_t struct */
+H5FL_EXTERN(H5EA_iblock_t);
+
+/* Declare a free list to manage the index block elements */
+H5FL_BLK_EXTERN(elmt_buf);
+
/* Internal extensible array testing class */
#ifdef H5EA_TESTING
H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1];
@@ -426,16 +478,27 @@ H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1];
/******************************/
/* Header routines */
-H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f);
+H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f, const H5EA_class_t *cls);
H5_DLL haddr_t H5EA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam);
H5_DLL herr_t H5EA__hdr_incr(H5EA_hdr_t *hdr);
H5_DLL herr_t H5EA__hdr_decr(H5EA_hdr_t *hdr);
H5_DLL herr_t H5EA__hdr_fuse_incr(H5EA_hdr_t *hdr);
H5_DLL size_t H5EA__hdr_fuse_decr(H5EA_hdr_t *hdr);
+H5_DLL herr_t H5EA__hdr_modified(H5EA_hdr_t *hdr);
H5_DLL herr_t H5EA__hdr_delete(H5EA_hdr_t *hdr, hid_t dxpl_id);
+/* Index block routines */
+H5_DLL H5EA_iblock_t *H5EA__iblock_alloc(H5EA_hdr_t *hdr);
+H5_DLL haddr_t H5EA__iblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id);
+H5_DLL H5EA_iblock_t *H5EA__iblock_protect(H5EA_hdr_t *hdr, hid_t dxpl_id,
+ H5AC_protect_t rw);
+H5_DLL herr_t H5EA__iblock_unprotect(H5EA_iblock_t *iblock, hid_t dxpl_id,
+ unsigned cache_flags);
+H5_DLL herr_t H5EA__iblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id);
+
/* Metadata cache callbacks */
H5_DLL herr_t H5EA__cache_hdr_dest(H5F_t *f, H5EA_hdr_t *hdr);
+H5_DLL herr_t H5EA__cache_iblock_dest(H5F_t *f, H5EA_iblock_t *iblock);
/* Testing routines */
#ifdef H5EA_TESTING
diff --git a/src/H5EAprivate.h b/src/H5EAprivate.h
index e39cefe..5893ebb 100644
--- a/src/H5EAprivate.h
+++ b/src/H5EAprivate.h
@@ -62,9 +62,9 @@ typedef struct H5EA_class_t {
size_t nat_elmt_size; /* Size of native (memory) element */
/* Extensible array client callback methods */
- herr_t (*fill)(uint8_t *raw_blk, size_t nelmts); /* Fill array of elements with encoded form of "missing element" value */
- herr_t (*encode)(uint8_t *raw, const void *elmt); /* Encode element from native form to disk storage form */
- herr_t (*decode)(const uint8_t *raw, void *elmt); /* Decode element from disk storage form to native form */
+ herr_t (*fill)(void *nat_blk, size_t nelmts); /* Fill array of elements with encoded form of "missing element" value */
+ herr_t (*encode)(void *raw, const void *elmt, size_t nelmts); /* Encode elements from native form to disk storage form */
+ herr_t (*decode)(const void *raw, void *elmt, size_t nelmts); /* Decode elements from disk storage form to native form */
herr_t (*debug)(FILE *stream, int indent, int fwidth, const void *elmt); /* Print an element for debugging */
} H5EA_class_t;
@@ -99,11 +99,14 @@ typedef struct H5EA_t H5EA_t;
/* General routines */
H5_DLL H5EA_t *H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam);
-H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr);
+H5_DLL H5EA_t *H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr,
+ const H5EA_class_t *cls);
H5_DLL herr_t H5EA_get_nelmts(const H5EA_t *ea, hsize_t *nelmts);
H5_DLL herr_t H5EA_get_addr(const H5EA_t *ea, haddr_t *addr);
-H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr);
+H5_DLL herr_t H5EA_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt);
+herr_t H5EA_get(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt);
H5_DLL herr_t H5EA_close(H5EA_t *ea, hid_t dxpl_id);
+H5_DLL herr_t H5EA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr);
/* Statistics routines */
H5_DLL herr_t H5EA_get_stats(const H5EA_t *ea, H5EA_stat_t *stats);
diff --git a/src/H5EAstat.c b/src/H5EAstat.c
new file mode 100644
index 0000000..8b0460c
--- /dev/null
+++ b/src/H5EAstat.c
@@ -0,0 +1,116 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5EAstat.c
+ * Sep 11 2009
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Extensible array metadata statistics functions.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/**********************/
+/* Module Declaration */
+/**********************/
+
+#define H5EA_MODULE
+
+
+/***********************/
+/* Other Packages Used */
+/***********************/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5EApkg.h" /* Extensible Arrays */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EA_get_stats
+ *
+ * Purpose: Query the metadata stats of an array
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Aug 21 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+BEGIN_FUNC(PRIV, NOERR,
+herr_t, SUCCEED, -,
+H5EA_get_stats(const H5EA_t *ea, H5EA_stat_t *stats))
+
+ /* Local variables */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", __func__);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(ea);
+ HDassert(stats);
+
+ /* Placeholder value */
+ HDmemset(stats, 0, sizeof(*stats));
+
+END_FUNC(PRIV) /* end H5EA_get_stats() */
+
diff --git a/src/H5EAtest.c b/src/H5EAtest.c
index 0096d9c..8f2e038 100644
--- a/src/H5EAtest.c
+++ b/src/H5EAtest.c
@@ -39,6 +39,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5EApkg.h" /* Extensible Arrays */
+#include "H5Vprivate.h" /* Vector functions */
/****************/
@@ -61,10 +62,10 @@
/********************/
/* Extensible array class callbacks */
-static herr_t H5EA_test_fill(uint8_t *raw_blk, size_t nelmts);
-static herr_t H5EA_test_encode(uint8_t *raw, const void *elmt);
-static herr_t H5EA_test_decode(const uint8_t *raw, void *elmt);
-static herr_t H5EA_test_debug(FILE *stream, int indent, int fwidth, const void *elmt);
+static herr_t H5EA__test_fill(void *nat_blk, size_t nelmts);
+static herr_t H5EA__test_encode(void *raw, const void *elmt, size_t nelmts);
+static herr_t H5EA__test_decode(const void *raw, void *elmt, size_t nelmts);
+static herr_t H5EA__test_debug(FILE *stream, int indent, int fwidth, const void *elmt);
/*********************/
@@ -74,11 +75,11 @@ static herr_t H5EA_test_debug(FILE *stream, int indent, int fwidth, const void *
/* Extensible array testing class information */
const H5EA_class_t H5EA_CLS_TEST[1]={{
H5EA_CLS_TEST_ID, /* Type of Extensible array */
- sizeof(haddr_t), /* Size of native record */
- H5EA_test_fill, /* Fill block of missing elements callback */
- H5EA_test_encode, /* Element encoding callback */
- H5EA_test_decode, /* Element decoding callback */
- H5EA_test_debug /* Element debugging callback */
+ sizeof(uint64_t), /* Size of native element */
+ H5EA__test_fill, /* Fill block of missing elements callback */
+ H5EA__test_encode, /* Element encoding callback */
+ H5EA__test_decode, /* Element decoding callback */
+ H5EA__test_debug /* Element debugging callback */
}};
@@ -94,7 +95,7 @@ const H5EA_class_t H5EA_CLS_TEST[1]={{
/*-------------------------------------------------------------------------
- * Function: H5EA_test_fill
+ * Function: H5EA__test_fill
*
* Purpose: Fill "missing elements" in block of elements
*
@@ -108,17 +109,22 @@ const H5EA_class_t H5EA_CLS_TEST[1]={{
*/
BEGIN_FUNC(STATIC, NOERR,
herr_t, SUCCEED, -,
-H5EA_test_fill(uint8_t *raw_blk, size_t nelmts))
+H5EA__test_fill(void *nat_blk, size_t nelmts))
+
+ /* Local variables */
+ uint64_t fill_val = H5EA_TEST_FILL; /* Value to fill elements with */
/* Sanity checks */
- HDassert(raw_blk);
+ HDassert(nat_blk);
HDassert(nelmts);
-END_FUNC(STATIC) /* end H5EA_test_fill() */
+ H5V_array_fill(nat_blk, &fill_val, sizeof(uint64_t), nelmts);
+
+END_FUNC(STATIC) /* end H5EA__test_fill() */
/*-------------------------------------------------------------------------
- * Function: H5EA_test_encode
+ * Function: H5EA__test_encode
*
* Purpose: Encode an element from "native" to "raw" form
*
@@ -132,17 +138,34 @@ END_FUNC(STATIC) /* end H5EA_test_fill() */
*/
BEGIN_FUNC(STATIC, NOERR,
herr_t, SUCCEED, -,
-H5EA_test_encode(uint8_t *raw, const void *elmt))
+H5EA__test_encode(void *raw, const void *_elmt, size_t nelmts))
+
+ /* Local variables */
+ const uint64_t *elmt = (const uint64_t *)_elmt; /* Convenience pointer to native elements */
/* Sanity checks */
HDassert(raw);
HDassert(elmt);
+ HDassert(nelmts);
+
+ /* Encode native elements into raw elements */
+ while(nelmts) {
+ /* Encode element */
+ /* (advances 'raw' pointer */
+ UINT64ENCODE(raw, *elmt);
+
+ /* Advance native element pointer */
+ elmt++;
-END_FUNC(STATIC) /* end H5EA_test_encode() */
+ /* Decrement # of elements to encode */
+ nelmts--;
+ } /* end while */
+
+END_FUNC(STATIC) /* end H5EA__test_encode() */
/*-------------------------------------------------------------------------
- * Function: H5EA_test_decode
+ * Function: H5EA__test_decode
*
* Purpose: Decode an element from "raw" to "native" form
*
@@ -156,17 +179,35 @@ END_FUNC(STATIC) /* end H5EA_test_encode() */
*/
BEGIN_FUNC(STATIC, NOERR,
herr_t, SUCCEED, -,
-H5EA_test_decode(const uint8_t *raw, void *elmt))
+H5EA__test_decode(const void *_raw, void *_elmt, size_t nelmts))
+
+ /* Local variables */
+ uint64_t *elmt = (uint64_t *)_elmt; /* Convenience pointer to native elements */
+ const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */
/* Sanity checks */
HDassert(raw);
HDassert(elmt);
+ HDassert(nelmts);
+
+ /* Decode raw elements into native elements */
+ while(nelmts) {
+ /* Decode element */
+ /* (advances 'raw' pointer */
+ UINT64DECODE(raw, *elmt);
+
+ /* Advance native element pointer */
+ elmt++;
+
+ /* Decrement # of elements to decode */
+ nelmts--;
+ } /* end while */
-END_FUNC(STATIC) /* end H5EA_test_decode() */
+END_FUNC(STATIC) /* end H5EA__test_decode() */
/*-------------------------------------------------------------------------
- * Function: H5EA_test_debug
+ * Function: H5EA__test_debug
*
* Purpose: Display an element for debugging
*
@@ -180,13 +221,13 @@ END_FUNC(STATIC) /* end H5EA_test_decode() */
*/
BEGIN_FUNC(STATIC, NOERR,
herr_t, SUCCEED, -,
-H5EA_test_debug(FILE *stream, int indent, int fwidth, const void *elmt))
+H5EA__test_debug(FILE *stream, int indent, int fwidth, const void *elmt))
/* Sanity checks */
HDassert(stream);
HDassert(elmt);
-END_FUNC(STATIC) /* end H5EA_test_debug() */
+END_FUNC(STATIC) /* end H5EA__test_debug() */
/*-------------------------------------------------------------------------
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index 984edb6..f83d8fe 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -93,9 +93,13 @@ typedef enum H5FD_mem_t {
* a fair amount of work to add a new kind of file memory and they are similar
* enough to object headers and probably too minor to deserve their own type.
*
+ * Map "extensible array" index blocks to 'ohdr' type file memory, since they
+ * are similar to extensible array header blocks.
+ *
* -QAK
*/
#define H5FD_MEM_EARRAY_HDR H5FD_MEM_OHDR
+#define H5FD_MEM_EARRAY_IBLOCK H5FD_MEM_OHDR
/*
* A free-list map which maps all types of allocation requests to a single
diff --git a/src/Makefile.am b/src/Makefile.am
index 161af23..6111ed0 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,7 +51,8 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Dio.c \
H5Distore.c H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
H5E.c H5Edeprec.c H5Eint.c \
- H5EA.c H5EAcache.c H5EAhdr.c H5EAint.c H5EAtest.c \
+ H5EA.c H5EAcache.c H5EAhdr.c H5EAiblock.c H5EAint.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 786ffff..b4900dc 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -86,8 +86,8 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Dcontig.lo H5Ddbg.lo H5Ddeprec.lo H5Defl.lo H5Dfill.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 H5EAhdr.lo H5EAint.lo \
- H5EAtest.lo H5F.lo H5Fdbg.lo H5Ffake.lo H5Fmount.lo \
+ H5Eint.lo H5EA.lo H5EAcache.lo H5EAhdr.lo H5EAiblock.lo H5EAint.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 \
H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \
@@ -430,7 +430,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Dio.c \
H5Distore.c H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
H5E.c H5Edeprec.c H5Eint.c \
- H5EA.c H5EAcache.c H5EAhdr.c H5EAint.c H5EAtest.c \
+ H5EA.c H5EAcache.c H5EAhdr.c H5EAiblock.c H5EAint.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 \
@@ -643,7 +643,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EA.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAcache.Plo@am__quote@
@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)/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@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Eint.Plo@am__quote@
diff --git a/test/earray.c b/test/earray.c
index 32b58bb..868a7ba 100644
--- a/test/earray.c
+++ b/test/earray.c
@@ -36,7 +36,7 @@
#define EARRAY_FILENAME_LEN 1024
/* Extensible array creation values */
-#define ELMT_SIZE sizeof(haddr_t)
+#define ELMT_SIZE sizeof(uint64_t)
#define MAX_NELMTS_BITS 32
#define IDX_BLK_ELMTS 4
#define SUP_BLK_MIN_DATA_PTRS 4
@@ -215,7 +215,8 @@ error:
*/
static int
reopen_file(hid_t *file, H5F_t **f, hid_t fapl, hid_t dxpl,
- H5EA_t **ea, haddr_t ea_addr, const earray_test_param_t *tparam)
+ H5EA_t **ea, haddr_t ea_addr, const H5EA_class_t *ea_cls,
+ const earray_test_param_t *tparam)
{
/* Check for closing & re-opening the array */
/* (actually will close & re-open the file as well) */
@@ -243,7 +244,7 @@ reopen_file(hid_t *file, H5F_t **f, hid_t fapl, hid_t dxpl,
/* Re-open array, if given */
if(ea) {
- if(NULL == (*ea = H5EA_open(*f, dxpl, ea_addr)))
+ if(NULL == (*ea = H5EA_open(*f, dxpl, ea_addr, ea_cls)))
FAIL_STACK_ERROR
} /* end if */
} /* end if */
@@ -281,7 +282,7 @@ create_array(H5F_t *f, hid_t dxpl, const H5EA_create_t *cparam,
FAIL_STACK_ERROR
/* Check status of array */
- nelmts = 0;
+ nelmts = (hsize_t)ULLONG_MAX;
if(H5EA_get_nelmts(*ea, &nelmts) < 0)
FAIL_STACK_ERROR
if(nelmts > 0)
@@ -572,11 +573,11 @@ test_reopen(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
FAIL_STACK_ERROR
/* Check for closing & re-opening the file */
- if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, tparam) < 0)
+ if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, NULL, tparam) < 0)
TEST_ERROR
/* Re-open the array */
- if(NULL == (ea = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr)))
+ if(NULL == (ea = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr, cparam->cls)))
FAIL_STACK_ERROR
/* Verify the creation parameters */
@@ -641,7 +642,7 @@ test_open_twice(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
TEST_ERROR
/* Open the array again, through the first file handle */
- if(NULL == (ea2 = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr)))
+ if(NULL == (ea2 = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr, cparam->cls)))
FAIL_STACK_ERROR
/* Verify the creation parameters */
@@ -656,7 +657,7 @@ test_open_twice(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
ea2 = NULL;
/* Check for closing & re-opening the file */
- if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, &ea, ea_addr, tparam) < 0)
+ if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, &ea, ea_addr, cparam->cls, tparam) < 0)
TEST_ERROR
/* Re-open the file */
@@ -668,7 +669,7 @@ test_open_twice(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
FAIL_STACK_ERROR
/* Open the extensible array through the second file handle */
- if(NULL == (ea2 = H5EA_open(f2, H5P_DATASET_XFER_DEFAULT, ea_addr)))
+ if(NULL == (ea2 = H5EA_open(f2, H5P_DATASET_XFER_DEFAULT, ea_addr, cparam->cls)))
FAIL_STACK_ERROR
/* Verify the creation parameters */
@@ -747,7 +748,7 @@ test_delete_open(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
TEST_ERROR
/* Open the array again */
- if(NULL == (ea2 = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr)))
+ if(NULL == (ea2 = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr, cparam->cls)))
FAIL_STACK_ERROR
/* Request that the array be deleted */
@@ -767,7 +768,7 @@ test_delete_open(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
/* Try re-opening the array again (should fail, as array will be deleted) */
H5E_BEGIN_TRY {
- ea2 = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr);
+ ea2 = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr, cparam->cls);
} H5E_END_TRY;
if(ea2) {
/* Close opened array */
@@ -783,12 +784,12 @@ test_delete_open(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
ea = NULL;
/* Check for closing & re-opening the file */
- if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, tparam) < 0)
+ if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, NULL, tparam) < 0)
TEST_ERROR
/* Try re-opening the array again (should fail, as array is now deleted) */
H5E_BEGIN_TRY {
- ea = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr);
+ ea = H5EA_open(f, H5P_DATASET_XFER_DEFAULT, ea_addr, cparam->cls);
} H5E_END_TRY;
if(ea) {
/* Close opened array */
@@ -847,6 +848,10 @@ test_set_first(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
hid_t file = -1; /* File ID */
H5F_t *f = NULL; /* Internal file object pointer */
H5EA_t *ea = NULL; /* Extensible array wrapper */
+ earray_state_t state; /* State of extensible array */
+ uint64_t welmt; /* Element to write */
+ uint64_t relmt; /* Element to read */
+ hsize_t nelmts; /* Highest element written in array */
haddr_t ea_addr = HADDR_UNDEF; /* Array address in file */
/* Create file & retrieve pointer to internal file object */
@@ -867,14 +872,55 @@ test_set_first(hid_t fapl, H5EA_create_t *cparam, earray_test_param_t *tparam)
TEST_ERROR
/* Check for closing & re-opening the file */
- if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, &ea, ea_addr, tparam) < 0)
+ if(reopen_file(&file, &f, fapl, H5P_DATASET_XFER_DEFAULT, &ea, ea_addr, cparam->cls, tparam) < 0)
+ TEST_ERROR
+
+ /* Verify high-water # of elements written */
+ nelmts = (hsize_t)ULLONG_MAX;
+ if(H5EA_get_nelmts(ea, &nelmts) < 0)
+ FAIL_STACK_ERROR
+ if(nelmts != 0)
+ TEST_ERROR
+
+ /* Verify array state */
+ HDmemset(&state, 0, sizeof(state));
+ if(check_stats(ea, &state))
+ TEST_ERROR
+
+ /* Retrieve first element of array (not set yet) */
+ relmt = (uint64_t)0;
+ if(H5EA_get(ea, H5P_DATASET_XFER_DEFAULT, 0, &relmt) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify first element is fill value for array */
+ if(relmt != H5EA_TEST_FILL)
+ TEST_ERROR
+
+ /* Set first element of array */
+ welmt = (uint64_t)7;
+ if(H5EA_set(ea, H5P_DATASET_XFER_DEFAULT, 0, &welmt) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify high-water # of elements written */
+ nelmts = (hsize_t)ULLONG_MAX;
+ if(H5EA_get_nelmts(ea, &nelmts) < 0)
+ FAIL_STACK_ERROR
+ if(nelmts != 1)
TEST_ERROR
-/* Set first element of array */
+ /* Verify array state */
+ HDmemset(&state, 0, sizeof(state));
+ if(check_stats(ea, &state))
+ TEST_ERROR
-/* Verify # of elements */
+ /* Retrieve first element of array (set now) */
+ relmt = (uint64_t)0;
+ if(H5EA_get(ea, H5P_DATASET_XFER_DEFAULT, 0, &relmt) < 0)
+ FAIL_STACK_ERROR
-/* Verify array state */
+ /* Verify first element is value written */
+ if(relmt != welmt)
+ TEST_ERROR
/* Close array, delete array, close file & verify file is empty */
if(shutdown(file, f, ea, ea_addr) < 0)