summaryrefslogtreecommitdiffstats
path: root/src/H5EA.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5EA.c')
-rw-r--r--src/H5EA.c145
1 files changed, 133 insertions, 12 deletions
diff --git a/src/H5EA.c b/src/H5EA.c
index 22be79a..d12a0c6 100644
--- a/src/H5EA.c
+++ b/src/H5EA.c
@@ -47,6 +47,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5EApkg.h" /* Extensible Arrays */
+#include "H5FLprivate.h" /* Free Lists */
/****************/
@@ -263,7 +264,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
HDassert(nelmts);
/* Retrieve the max. index set */
- *nelmts = ea->hdr->max_idx_set;
+ *nelmts = ea->hdr->stats.max_idx_set;
END_FUNC(PRIV) /* end H5EA_get_nelmts() */
@@ -324,6 +325,9 @@ 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 */
+ H5EA_dblock_t *dblock = NULL; /* Pointer to data block for EA */
+ unsigned iblock_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting index block */
+ unsigned dblock_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting data block */
hbool_t hdr_dirty = FALSE; /* Whether header information changed */
#ifdef QAK
@@ -350,6 +354,9 @@ HDfprintf(stderr, "%s: Index block address not defined!\n", FUNC, idx);
if(!H5F_addr_defined(hdr->idx_blk_addr))
H5E_THROW(H5E_CANTCREATE, "unable to create index block")
+ /* Increment count of elements "realized" */
+ hdr->stats.nelmts += hdr->idx_blk_elmts;
+
/* Mark the header dirty */
hdr_dirty = TRUE;
} /* end if */
@@ -361,19 +368,81 @@ HDfprintf(stderr, "%s: Index block address is: %a\n", FUNC, hdr->idx_blk_addr);
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 */
+ /* Check if element is in index block */
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);
+ iblock_cache_flags |= H5AC__DIRTIED_FLAG;
} /* end if */
else {
-HDfprintf(stderr, "%s: Index %Hu not supported yet!\n", FUNC, idx);
-HDassert(0 && "Index location not supported!");
+ unsigned sblk_idx; /* Which superblock does this index fall in? */
+ hsize_t elmt_idx; /* Offset of element in super block */
+
+ /* Get super block index where element is located */
+ sblk_idx = H5EA__dblock_sblk_idx(hdr, idx);
+
+ /* Adjust index to offset in super block */
+ elmt_idx = idx - hdr->idx_blk_elmts + hdr->sblk_info[sblk_idx].start_idx;
+#ifdef QAK
+HDfprintf(stderr, "%s: after adjusting for super block elements, elmt_idx = %Hu\n", FUNC, elmt_idx);
+#endif /* QAK */
+
+ /* Check for data block containing element address in the index block */
+ if(sblk_idx < iblock->nsblks) {
+ size_t dblk_idx; /* Data block index */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Element in data block pointed to by address in index block\n", FUNC);
+#endif /* QAK */
+ /* Compute the data block index in index block */
+ dblk_idx = (size_t)(hdr->sblk_info[sblk_idx].start_dblk + (elmt_idx / hdr->sblk_info[sblk_idx].dblk_nelmts));
+#ifdef QAK
+HDfprintf(stderr, "%s: dblk_idx = %u\n", FUNC, dblk_idx);
+#endif /* QAK */
+ HDassert(dblk_idx < iblock->ndblk_addrs);
+
+ /* Check if the data block has been allocated on disk yet */
+ if(!H5F_addr_defined(iblock->dblk_addrs[dblk_idx])) {
+ 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);
+ if(!H5F_addr_defined(dblk_addr))
+ H5E_THROW(H5E_CANTCREATE, "unable to create extensible array data block")
+
+ /* Set data block address in index block */
+ iblock->dblk_addrs[dblk_idx] = dblk_addr;
+ iblock_cache_flags |= H5AC__DIRTIED_FLAG;
+
+ /* Increment count of elements "realized" and actual data blocks created */
+ hdr->stats.ndata_blks++;
+ hdr->stats.nelmts += hdr->sblk_info[sblk_idx].dblk_nelmts;
+ hdr_dirty = TRUE;
+ } /* end if */
+
+ /* Protect data block */
+ if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, iblock->dblk_addrs[dblk_idx], hdr->sblk_info[sblk_idx].dblk_nelmts, H5AC_WRITE)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)iblock->dblk_addrs[dblk_idx])
+
+ /* Adjust index to offset in data block */
+ elmt_idx %= hdr->sblk_info[sblk_idx].dblk_nelmts;
+
+ /* Set element in data block */
+ HDmemcpy(((uint8_t *)dblock->elmts) + (hdr->cls->nat_elmt_size * elmt_idx), elmt, hdr->cls->nat_elmt_size);
+ dblock_cache_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+ else {
+HDfprintf(stderr, "%s: Super block index %Hu not supported yet!\n", FUNC, sblk_idx);
+HDassert(0 && "Super block index location not supported!");
+ } /* end else */
} /* end else */
/* Update max. element set in array, if appropriate */
- if(idx >= hdr->max_idx_set) {
- hdr->max_idx_set = idx + 1;
+#ifdef QAK
+HDfprintf(stderr, "%s: idx = %Hu, hdr->stats.max_idx_set = %Hu\n", FUNC, idx, hdr->stats.max_idx_set);
+#endif /* QAK */
+ if(idx >= hdr->stats.max_idx_set) {
+ hdr->stats.max_idx_set = idx + 1;
hdr_dirty = TRUE;
} /* end if */
@@ -383,8 +452,11 @@ CATCH
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)
+ /* Release resources */
+ if(iblock && H5EA__iblock_unprotect(iblock, dxpl_id, iblock_cache_flags) < 0)
H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array index block")
+ if(dblock && H5EA__dblock_unprotect(dblock, dxpl_id, dblock_cache_flags) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block")
END_FUNC(PRIV) /* end H5EA_set() */
@@ -409,6 +481,7 @@ H5EA_get(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt))
/* Local variables */
H5EA_hdr_t *hdr = ea->hdr; /* Header for EA */
H5EA_iblock_t *iblock = NULL; /* Pointer to index block for EA */
+ H5EA_dblock_t *dblock = NULL; /* Pointer to data block for EA */
#ifdef QAK
HDfprintf(stderr, "%s: Called\n", FUNC);
@@ -425,9 +498,9 @@ HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx);
hdr->f = ea->f;
/* Check for element beyond max. element in array */
- if(idx >= hdr->max_idx_set) {
+ if(idx >= hdr->stats.max_idx_set) {
#ifdef QAK
-HDfprintf(stderr, "%s: Element beyond max. index set\n", FUNC, idx);
+HDfprintf(stderr, "%s: Element beyond max. index set, hdr->stats.max_idx_set = %Hu, idx = %Hu\n", FUNC, hdr->stats.max_idx_set, idx);
#endif /* QAK */
/* Call the class's 'fill' callback */
if((hdr->cls->fill)(elmt, (size_t)1) < 0)
@@ -442,20 +515,68 @@ HDfprintf(stderr, "%s: Index block address is: %a\n", FUNC, hdr->idx_blk_addr);
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)
- /* Determine where the element to set falls */
+ /* Check if element is in index block */
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!");
+ unsigned sblk_idx; /* Which superblock does this index fall in? */
+ hsize_t elmt_idx; /* Offset of element in super block */
+
+ /* Get super block index where element is located */
+ sblk_idx = H5EA__dblock_sblk_idx(hdr, idx);
+
+ /* Adjust index to offset in super block */
+ elmt_idx = idx - hdr->idx_blk_elmts + hdr->sblk_info[sblk_idx].start_idx;
+#ifdef QAK
+HDfprintf(stderr, "%s: after adjusting for super block elements, elmt_idx = %Hu\n", FUNC, elmt_idx);
+#endif /* QAK */
+
+ /* Check for data block containing element address in the index block */
+ if(sblk_idx < iblock->nsblks) {
+ size_t dblk_idx; /* Data block index */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Element in data block pointed to by address in index block\n", FUNC);
+#endif /* QAK */
+ /* Compute the data block index in index block */
+ dblk_idx = (size_t)(hdr->sblk_info[sblk_idx].start_dblk + (elmt_idx / hdr->sblk_info[sblk_idx].dblk_nelmts));
+#ifdef QAK
+HDfprintf(stderr, "%s: dblk_idx = %u\n", FUNC, dblk_idx);
+#endif /* QAK */
+ HDassert(dblk_idx < iblock->ndblk_addrs);
+
+ /* Check if the data block has been allocated on disk yet */
+ if(!H5F_addr_defined(iblock->dblk_addrs[dblk_idx])) {
+ /* 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 {
+ /* Protect data block */
+ if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, iblock->dblk_addrs[dblk_idx], hdr->sblk_info[sblk_idx].dblk_nelmts, H5AC_READ)))
+ H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)iblock->dblk_addrs[dblk_idx])
+
+ /* Adjust index to offset in data block */
+ elmt_idx %= hdr->sblk_info[sblk_idx].dblk_nelmts;
+
+ /* Retrieve element from data block */
+ HDmemcpy(elmt, ((uint8_t *)dblock->elmts) + (hdr->cls->nat_elmt_size * elmt_idx), hdr->cls->nat_elmt_size);
+ } /* end else */
+ } /* end if */
+ else {
+HDfprintf(stderr, "%s: Super block index %Hu not supported yet!\n", FUNC, sblk_idx);
+HDassert(0 && "Super block index location not supported!");
+ } /* end else */
} /* end else */
} /* end else */
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")
+ if(dblock && H5EA__dblock_unprotect(dblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
+ H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block")
END_FUNC(PRIV) /* end H5EA_set() */