diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2008-11-28 19:16:24 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2008-11-28 19:16:24 (GMT) |
commit | e8e2f47703cfc9427ceea7bfe9e9c0da815053d8 (patch) | |
tree | bc941c3f47976ff45e593d044ad591d0cb541eb1 | |
parent | bd3e89868ad3b4f3c3a45a089675fa4b8250d21f (diff) | |
download | hdf5-e8e2f47703cfc9427ceea7bfe9e9c0da815053d8.zip hdf5-e8e2f47703cfc9427ceea7bfe9e9c0da815053d8.tar.gz hdf5-e8e2f47703cfc9427ceea7bfe9e9c0da815053d8.tar.bz2 |
[svn-r16137] Description:
Add support for paging large data blocks to extensible arrays
Clean up allocation/destroy code for extensible array index, super and
data blocks
Add a couple of routines to set/get bit values in memory buffers
Tested on:
Mac OS X/32 10.5.5 (amazon) in debug mode
Mac OS X/32 10.5.5 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
FreeBSD/32 6.3 (duty) in debug mode
FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | src/H5AC.c | 1 | ||||
-rw-r--r-- | src/H5ACprivate.h | 3 | ||||
-rw-r--r-- | src/H5Cpkg.h | 2 | ||||
-rw-r--r-- | src/H5EA.c | 161 | ||||
-rw-r--r-- | src/H5EAcache.c | 358 | ||||
-rw-r--r-- | src/H5EAdblkpage.c | 313 | ||||
-rw-r--r-- | src/H5EAdblock.c | 100 | ||||
-rw-r--r-- | src/H5EAhdr.c | 2 | ||||
-rw-r--r-- | src/H5EAiblock.c | 62 | ||||
-rw-r--r-- | src/H5EApkg.h | 51 | ||||
-rw-r--r-- | src/H5EAsblock.c | 44 | ||||
-rw-r--r-- | src/H5FDpublic.h | 5 | ||||
-rw-r--r-- | src/H5FLprivate.h | 2 | ||||
-rw-r--r-- | src/H5Vprivate.h | 60 | ||||
-rwxr-xr-x | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/Makefile.in | 65 | ||||
-rw-r--r-- | test/earray.c | 3 |
18 files changed, 1092 insertions, 145 deletions
@@ -499,6 +499,7 @@ ./src/H5EA.c ./src/H5EAcache.c ./src/H5EAdbg.c +./src/H5EAdblkpage.c ./src/H5EAdblock.c ./src/H5EAhdr.c ./src/H5EAiblock.c @@ -495,6 +495,7 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] = "extensible array index blocks", "extensible array super blocks", "extensible array data blocks", + "extensible array data block pages", "test entry" /* for testing only -- not used for actual files */ }; diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 9a479e0..4a6f9f3 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -65,7 +65,8 @@ typedef enum { 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_EARRAY_DBLOCK_ID, /*extensible array data block */ + H5AC_EARRAY_DBLK_PAGE_ID, /*extensible array data block page */ 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 ced02d2..bdbb25e 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 20 +#define H5C__MAX_NUM_TYPE_IDS 21 #define H5C__PREFIX_LEN 32 struct H5C_t @@ -48,6 +48,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5EApkg.h" /* Extensible Arrays */ #include "H5FLprivate.h" /* Free Lists */ +#include "H5Vprivate.h" /* Vector functions */ /****************/ @@ -327,9 +328,11 @@ H5EA_set(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt)) H5EA_iblock_t *iblock = NULL; /* Pointer to index block for EA */ H5EA_sblock_t *sblock = NULL; /* Pointer to super block for EA */ H5EA_dblock_t *dblock = NULL; /* Pointer to data block for EA */ + H5EA_dblk_page_t *dblk_page = NULL; /* Pointer to data block page for EA */ unsigned iblock_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting index block */ unsigned sblock_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting super block */ unsigned dblock_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting data block */ + unsigned dblk_page_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting data block page */ hbool_t hdr_dirty = FALSE; /* Whether header information changed */ #ifdef QAK @@ -438,7 +441,8 @@ HDfprintf(stderr, "%s: dblk_idx = %u, iblock->ndblk_addrs = %Zu\n", FUNC, dblk_i dblock_cache_flags |= H5AC__DIRTIED_FLAG; } /* end if */ else { - unsigned sblk_off; /* Offset of super block in index block array of super blocks */ + unsigned sblk_off; /* Offset of super block in index block array of super blocks */ + void *elmts; /* Buffer for elements */ /* Calculate offset of super block in index block's array */ sblk_off = sblk_idx - iblock->nsblks; @@ -496,16 +500,80 @@ HDfprintf(stderr, "%s: dblk_idx = %u, sblock->ndblks = %Zu\n", FUNC, dblk_idx, s hdr_dirty = TRUE; } /* end if */ - /* Protect data block */ - if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_WRITE))) - H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)sblock->dblk_addrs[dblk_idx]) - +#ifdef QAK +if(sblock->dblk_npages) + HDfprintf(stderr, "%s: Check 1.0: elmt_idx = %Hu\n", FUNC, elmt_idx); +#endif /* QAK */ /* Adjust index to offset in data block */ elmt_idx %= sblock->dblk_nelmts; +#ifdef QAK +if(sblock->dblk_npages) + HDfprintf(stderr, "%s: Check 2.0: elmt_idx = %Hu\n", FUNC, elmt_idx); +#endif /* QAK */ + + /* Check if the data block is paged */ + if(sblock->dblk_npages) { + haddr_t dblk_page_addr; /* Address of data block page */ + size_t page_idx; /* Index of page within data block */ + size_t page_init_idx; /* Index of 'page init' bit */ + + /* Compute page index */ + page_idx = (size_t)elmt_idx / hdr->dblk_page_nelmts; + + /* Compute 'page init' index */ + page_init_idx = (dblk_idx * sblock->dblk_npages) + page_idx; + + /* Adjust index to offset in data block page */ + elmt_idx %= hdr->dblk_page_nelmts; + + /* Compute data block page address */ + dblk_page_addr = sblock->dblk_addrs[dblk_idx] + + H5EA_DBLOCK_PREFIX_SIZE(sblock) + + (page_idx * sblock->dblk_page_size); +#ifdef QAK +HDfprintf(stderr, "%s: sblock->addr = %a\n", FUNC, sblock->addr); +HDfprintf(stderr, "%s: sblock->dblk_addrs[%Zu] = %a\n", FUNC, dblk_idx, sblock->dblk_addrs[dblk_idx]); +HDfprintf(stderr, "%s: H5EA_DBLOCK_PREFIX_SIZE(sblock) = %u\n", FUNC, (unsigned)H5EA_DBLOCK_PREFIX_SIZE(sblock)); +HDfprintf(stderr, "%s: sblock->page_init[%Zu] = %t\n", FUNC, page_init_idx, H5V_bit_get(sblock->page_init, page_init_idx)); +HDfprintf(stderr, "%s: page_idx = %Zu, elmt_idx = %Hu, dblk_page_addr = %a\n", FUNC, page_idx, elmt_idx, dblk_page_addr); +HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_size); +#endif /* QAK */ + + /* Check if page has been initialized yet */ + if(!H5V_bit_get(sblock->page_init, page_init_idx)) { + /* Create the data block page */ + if(H5EA__dblk_page_create(hdr, dxpl_id, dblk_page_addr) < 0) + H5E_THROW(H5E_CANTCREATE, "unable to create data block page") + + /* Mark data block page as initialized in super block */ + H5V_bit_set(sblock->page_init, page_init_idx, TRUE); + sblock_cache_flags |= H5AC__DIRTIED_FLAG; + } /* end if */ + + /* Protect data block page */ + if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, H5AC_WRITE))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long_long)dblk_page_addr) + + /* Set pointer to elements */ + elmts = dblk_page->elmts; + } /* end if */ + else { + /* Protect data block */ + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_WRITE))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)sblock->dblk_addrs[dblk_idx]) + + /* Set pointer to elements */ + elmts = dblock->elmts; + } /* end else */ /* Set element in data block */ - HDmemcpy(((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size); - dblock_cache_flags |= H5AC__DIRTIED_FLAG; + HDmemcpy(((uint8_t *)elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size); + + /* Mark data block/data block page as dirty now */ + if(sblock->dblk_npages) + dblk_page_cache_flags |= H5AC__DIRTIED_FLAG; + else + dblock_cache_flags |= H5AC__DIRTIED_FLAG; } /* end else */ } /* end else */ @@ -531,6 +599,8 @@ CATCH H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array super block") if(dblock && H5EA__dblock_unprotect(dblock, dxpl_id, dblock_cache_flags) < 0) H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block") + if(dblk_page && H5EA__dblk_page_unprotect(dblk_page, dxpl_id, dblk_page_cache_flags) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block page") END_FUNC(PRIV) /* end H5EA_set() */ @@ -557,6 +627,7 @@ H5EA_get(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt)) H5EA_iblock_t *iblock = NULL; /* Pointer to index block for EA */ H5EA_sblock_t *sblock = NULL; /* Pointer to super block for EA */ H5EA_dblock_t *dblock = NULL; /* Pointer to data block for EA */ + H5EA_dblk_page_t *dblk_page = NULL; /* Pointer to data block page for EA */ #ifdef QAK HDfprintf(stderr, "%s: Called\n", FUNC); @@ -670,15 +741,81 @@ HDfprintf(stderr, "%s: dblk_idx = %u, sblock->ndblks = %Zu\n", FUNC, dblk_idx, s 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, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_READ))) - H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)sblock->dblk_addrs[dblk_idx]) + void *elmts; /* Buffer for elements */ +#ifdef QAK +if(sblock->dblk_npages) + HDfprintf(stderr, "%s: Check 1.0: elmt_idx = %Hu\n", FUNC, elmt_idx); +#endif /* QAK */ /* Adjust index to offset in data block */ elmt_idx %= sblock->dblk_nelmts; +#ifdef QAK +if(sblock->dblk_npages) + HDfprintf(stderr, "%s: Check 2.0: elmt_idx = %Hu\n", FUNC, elmt_idx); +#endif /* QAK */ + + /* Check if the data block is paged */ + if(sblock->dblk_npages) { + size_t page_idx; /* Index of page within data block */ + size_t page_init_idx; /* Index of 'page init' bit */ + + /* Compute page index */ + page_idx = (size_t)elmt_idx / hdr->dblk_page_nelmts; + + /* Compute 'page init' index */ + page_init_idx = (dblk_idx * sblock->dblk_npages) + page_idx; + +#ifdef QAK +HDfprintf(stderr, "%s: sblock->addr = %a\n", FUNC, sblock->addr); +HDfprintf(stderr, "%s: sblock->dblk_addrs[%Zu] = %a\n", FUNC, dblk_idx, sblock->dblk_addrs[dblk_idx]); +HDfprintf(stderr, "%s: H5EA_DBLOCK_PREFIX_SIZE(sblock) = %u\n", FUNC, (unsigned)H5EA_DBLOCK_PREFIX_SIZE(sblock)); +HDfprintf(stderr, "%s: sblock->page_init[%Zu] = %t\n", FUNC, page_init_idx, H5V_bit_get(sblock->page_init, page_init_idx)); +HDfprintf(stderr, "%s: page_idx = %Zu\n", FUNC, page_idx); +HDfprintf(stderr, "%s: sblock->dblk_page_size = %Zu\n", FUNC, sblock->dblk_page_size); +#endif /* QAK */ + + /* Check if page has been initialized yet */ + if(!H5V_bit_get(sblock->page_init, page_init_idx)) { + /* Call the class's 'fill' callback */ + if((hdr->cparam.cls->fill)(elmt, (size_t)1) < 0) + H5E_THROW(H5E_CANTSET, "can't set element to class's fill value") + + /* We've retrieved the value, leave now */ + H5_LEAVE(SUCCEED) + } /* end if */ + else { + haddr_t dblk_page_addr; /* Address of data block page */ + + /* Adjust index to offset in data block page */ + elmt_idx %= hdr->dblk_page_nelmts; + + /* Compute data block page address */ + dblk_page_addr = sblock->dblk_addrs[dblk_idx] + + H5EA_DBLOCK_PREFIX_SIZE(sblock) + + (page_idx * sblock->dblk_page_size); +#ifdef QAK +HDfprintf(stderr, "%s: elmt_idx = %Hu, dblk_page_addr = %a\n", FUNC, elmt_idx, dblk_page_addr); +#endif /* QAK */ + + /* Protect data block page */ + if(NULL == (dblk_page = H5EA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long_long)dblk_page_addr) + + /* Set pointer to elements */ + elmts = dblk_page->elmts; + } /* end else */ + } /* end if */ + else { + /* Protect data block */ + if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, sblock->dblk_addrs[dblk_idx], sblock->dblk_nelmts, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)sblock->dblk_addrs[dblk_idx]) + + /* Set pointer to elements */ + elmts = dblock->elmts; + } /* end else */ /* Retrieve element from data block */ - HDmemcpy(elmt, ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), hdr->cparam.cls->nat_elmt_size); + HDmemcpy(elmt, ((uint8_t *)elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), hdr->cparam.cls->nat_elmt_size); } /* end else */ } /* end else */ } /* end else */ @@ -692,6 +829,8 @@ CATCH H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array super 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") + if(dblk_page && H5EA__dblk_page_unprotect(dblk_page, dxpl_id, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array data block page") END_FUNC(PRIV) /* end H5EA_set() */ diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 2590edc..a3c9f87 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -62,6 +62,7 @@ #define H5EA_IBLOCK_BUF_SIZE 512 #define H5EA_SBLOCK_BUF_SIZE 512 #define H5EA_DBLOCK_BUF_SIZE 512 +#define H5EA_DBLK_PAGE_BUF_SIZE 512 /******************/ @@ -99,6 +100,11 @@ static herr_t H5EA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, static herr_t H5EA__cache_dblock_clear(H5F_t *f, H5EA_dblock_t *dblock, hbool_t destroy); static herr_t H5EA__cache_dblock_size(const H5F_t *f, const H5EA_dblock_t *dblock, size_t *size_ptr); static herr_t H5EA__cache_dblock_dest(H5F_t *f, H5EA_dblock_t *dblock); +static H5EA_dblk_page_t *H5EA__cache_dblk_page_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); +static herr_t H5EA__cache_dblk_page_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5EA_dblk_page_t *dblk_page, unsigned * flags_ptr); +static herr_t H5EA__cache_dblk_page_clear(H5F_t *f, H5EA_dblk_page_t *dblk_page, hbool_t destroy); +static herr_t H5EA__cache_dblk_page_size(const H5F_t *f, const H5EA_dblk_page_t *dblk_page, size_t *size_ptr); +static herr_t H5EA__cache_dblk_page_dest(H5F_t *f, H5EA_dblk_page_t *dblk_page); /*********************/ @@ -145,6 +151,16 @@ const H5AC_class_t H5AC_EARRAY_DBLOCK[1] = {{ (H5AC_size_func_t)H5EA__cache_dblock_size, }}; +/* H5EA data block page inherits cache-like properties from H5AC */ +const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1] = {{ + H5AC_EARRAY_DBLK_PAGE_ID, + (H5AC_load_func_t)H5EA__cache_dblk_page_load, + (H5AC_flush_func_t)H5EA__cache_dblk_page_flush, + (H5AC_dest_func_t)H5EA__cache_dblk_page_dest, + (H5AC_clear_func_t)H5EA__cache_dblk_page_clear, + (H5AC_size_func_t)H5EA__cache_dblk_page_size, +}}; + /*****************************/ /* Library Private Variables */ @@ -1267,7 +1283,10 @@ H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, H5E_THROW(H5E_CANTINIT, "can't wrap buffer") /* Compute the size of the extensible array data block on disk */ - size = H5EA_DBLOCK_SIZE(dblock); + if(!dblock->npages) + size = H5EA_DBLOCK_SIZE(dblock); + else + size = H5EA_DBLOCK_PREFIX_SIZE(dblock); /* Get a pointer to a buffer that's large enough for serialized info */ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) @@ -1303,18 +1322,21 @@ H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, /* Internal information */ - /* Decode elements in data block */ - /* Convert from raw elements on disk into native elements in memory */ - if((hdr->cparam.cls->decode)(p, dblock->elmts, *nelmts) < 0) - H5E_THROW(H5E_CANTDECODE, "can't decode extensible array data elements") - p += (*nelmts * hdr->cparam.raw_elmt_size); + /* Only decode elements if the data block is not paged */ + if(!dblock->npages) { + /* Decode elements in data block */ + /* Convert from raw elements on disk into native elements in memory */ + if((hdr->cparam.cls->decode)(p, dblock->elmts, *nelmts) < 0) + H5E_THROW(H5E_CANTDECODE, "can't decode extensible array data elements") + p += (*nelmts * hdr->cparam.raw_elmt_size); + } /* end if */ /* Sanity check */ /* (allow for checksum not decoded yet) */ HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM)); - /* Save the data block's size */ - dblock->size = size; + /* Set the data block's size */ + dblock->size = H5EA_DBLOCK_SIZE(dblock); /* Compute checksum on data block */ computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); @@ -1323,7 +1345,7 @@ H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, UINT32DECODE(p, stored_chksum); /* Sanity check */ - HDassert((size_t)(p - buf) == dblock->size); + HDassert((size_t)(p - buf) == size); /* Verify checksum */ if(stored_chksum != computed_chksum) @@ -1383,7 +1405,10 @@ H5EA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5E_THROW(H5E_CANTINIT, "can't wrap buffer") /* Compute the size of the data block on disk */ - size = dblock->size; + if(!dblock->npages) + size = dblock->size; + else + size = H5EA_DBLOCK_PREFIX_SIZE(dblock); /* Get a pointer to a buffer that's large enough for serialized info */ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) @@ -1410,12 +1435,15 @@ H5EA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, /* Internal information */ - /* Encode elements in data block */ + /* Only encode elements if the data block is not paged */ + if(!dblock->npages) { + /* Encode elements in data block */ - /* Convert from native elements in memory into raw elements on disk */ - if((dblock->hdr->cparam.cls->encode)(p, dblock->elmts, dblock->nelmts) < 0) - H5E_THROW(H5E_CANTENCODE, "can't encode extensible array data elements") - p += (dblock->nelmts * dblock->hdr->cparam.raw_elmt_size); + /* Convert from native elements in memory into raw elements on disk */ + if((dblock->hdr->cparam.cls->encode)(p, dblock->elmts, dblock->nelmts) < 0) + H5E_THROW(H5E_CANTENCODE, "can't encode extensible array data elements") + p += (dblock->nelmts * dblock->hdr->cparam.raw_elmt_size); + } /* end if */ /* Compute metadata checksum */ metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); @@ -1503,7 +1531,10 @@ H5EA__cache_dblock_size(const H5F_t UNUSED *f, const H5EA_dblock_t *dblock, HDassert(size_ptr); /* Set size value */ - *size_ptr = dblock->size; + if(!dblock->npages) + *size_ptr = dblock->size; + else + *size_ptr = H5EA_DBLOCK_PREFIX_SIZE(dblock); END_FUNC(STATIC) /* end H5EA__cache_dblock_size() */ @@ -1542,6 +1573,7 @@ H5EA__cache_dblock_dest(H5F_t *f, H5EA_dblock_t *dblock)) HDassert(H5F_addr_eq(dblock->addr, dblock->cache_info.addr)); /* Release the space on disk */ + /* (Includes space for pages!) */ /* (XXX: Nasty usage of internal DXPL value! -QAK) */ if(H5MF_xfree(f, H5FD_MEM_EARRAY_DBLOCK, H5AC_dxpl_id, dblock->cache_info.addr, (hsize_t)dblock->size) < 0) H5E_THROW(H5E_CANTFREE, "unable to free extensible array data block") @@ -1555,3 +1587,297 @@ CATCH END_FUNC(STATIC) /* end H5EA__cache_dblock_dest() */ + +/*------------------------------------------------------------------------- + * Function: H5EA__cache_dblk_page_load + * + * Purpose: Loads an extensible array data block page from the disk. + * + * Return: Success: Pointer to a new extensible array data block page + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +H5EA_dblk_page_t *, NULL, NULL, +H5EA__cache_dblk_page_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_dblk_page_t *dblk_page = NULL; /* Data block page info */ + size_t size; /* Data block page size */ + H5WB_t *wb = NULL; /* Wrapped buffer for data block page data */ + uint8_t dblk_page_buf[H5EA_DBLK_PAGE_BUF_SIZE]; /* Buffer for data block page */ + uint8_t *buf; /* Pointer to data block page 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); +#ifdef QAK +HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr); +#endif /* QAK */ + + /* Allocate the extensible array data block page */ + if(NULL == (dblk_page = H5EA__dblk_page_alloc(hdr))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block page") + + /* Set the extensible array data block's information */ + dblk_page->addr = addr; + + /* Wrap the local buffer for serialized info */ + if(NULL == (wb = H5WB_wrap(dblk_page_buf, sizeof(dblk_page_buf)))) + H5E_THROW(H5E_CANTINIT, "can't wrap buffer") + + /* Compute the size of the extensible array data block page on disk */ + size = H5EA_DBLK_PAGE_SIZE(dblk_page); + + /* 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 data block page from disk */ + if(H5F_block_read(f, H5FD_MEM_EARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_READERROR, "can't read extensible array data block page") + + /* Get temporary pointer to serialized header */ + p = buf; + + /* Internal information */ + + /* Decode elements in data block page */ + /* Convert from raw elements on disk into native elements in memory */ + if((hdr->cparam.cls->decode)(p, dblk_page->elmts, hdr->dblk_page_nelmts) < 0) + H5E_THROW(H5E_CANTDECODE, "can't decode extensible array data elements") + p += (hdr->dblk_page_nelmts * hdr->cparam.raw_elmt_size); + + /* Sanity check */ + /* (allow for checksum not decoded yet) */ + HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM)); + + /* Set the data block page's size */ + dblk_page->size = size; + + /* Compute checksum on data 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) == dblk_page->size); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) +{ +HDfprintf(stderr, "%s: stored_chksum = %8x, computed_chksum = %8x\n", FUNC, stored_chksum, computed_chksum); + H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array data block page") +} + + /* Set return value */ + ret_value = dblk_page; + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + if(!ret_value) + if(dblk_page && H5EA__cache_dblk_page_dest(f, dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block page") + +END_FUNC(STATIC) /* end H5EA__cache_dblk_page_load() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__cache_dblk_page_flush + * + * Purpose: Flushes a dirty extensible array data block page to disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5EA__cache_dblk_page_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, + H5EA_dblk_page_t *dblk_page, unsigned UNUSED * flags_ptr)) + + /* Local variables */ + H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */ + uint8_t ser_buf[H5EA_DBLK_PAGE_BUF_SIZE]; /* Serialization buffer */ + + /* Sanity check */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(dblk_page); + HDassert(dblk_page->hdr); + + if(dblk_page->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 data block on disk */ + size = dblk_page->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; + + /* Internal information */ + + /* Encode elements in data block page */ + + /* Convert from native elements in memory into raw elements on disk */ + if((dblk_page->hdr->cparam.cls->encode)(p, dblk_page->elmts, dblk_page->hdr->dblk_page_nelmts) < 0) + H5E_THROW(H5E_CANTENCODE, "can't encode extensible array data elements") + p += (dblk_page->hdr->dblk_page_nelmts * dblk_page->hdr->cparam.raw_elmt_size); + + /* Compute metadata checksum */ + metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); + + /* Write the data block */ + HDassert((size_t)(p - buf) == size); + if(H5F_block_write(f, H5FD_MEM_EARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_WRITEERROR, "unable to save extensible array data block page to disk") + + dblk_page->cache_info.is_dirty = FALSE; + } /* end if */ + + if(destroy) + if(H5EA__cache_dblk_page_dest(f, dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block page") + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + +END_FUNC(STATIC) /* end H5EA__cache_dblk_page_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__cache_dblk_page_clear + * + * Purpose: Mark a extensible array data block page in memory as non-dirty. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5EA__cache_dblk_page_clear(H5F_t *f, H5EA_dblk_page_t *dblk_page, hbool_t destroy)) + + /* Sanity check */ + HDassert(dblk_page); + + /* Reset the dirty flag */ + dblk_page->cache_info.is_dirty = FALSE; + + if(destroy) + if(H5EA__cache_dblk_page_dest(f, dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block page") + +CATCH + +END_FUNC(STATIC) /* end H5EA__cache_dblk_page_clear() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__cache_dblk_page_size + * + * Purpose: Compute the size in bytes of a extensible array data block page + * 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 + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5EA__cache_dblk_page_size(const H5F_t UNUSED *f, const H5EA_dblk_page_t *dblk_page, + size_t *size_ptr)) + + /* Sanity check */ + HDassert(f); + HDassert(dblk_page); + HDassert(size_ptr); + + /* Set size value */ + *size_ptr = dblk_page->size; + +END_FUNC(STATIC) /* end H5EA__cache_dblk_page_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__cache_dblk_page_dest + * + * Purpose: Destroys an extensible array data block page in memory. + * + * Note: Does _not_ free the space for the page on disk, that is + * handled through the data block that "owns" the page. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5EA__cache_dblk_page_dest(H5F_t UNUSED *f, H5EA_dblk_page_t *dblk_page)) + + /* Sanity check */ + HDassert(f); + HDassert(dblk_page); + + /* Verify that data block page is clean */ + HDassert(dblk_page->cache_info.is_dirty == FALSE); + + /* Release the data block page */ + if(H5EA__dblk_page_dest(dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "can't free extensible array data block page") + +CATCH + +END_FUNC(STATIC) /* end H5EA__cache_dblk_page_dest() */ + diff --git a/src/H5EAdblkpage.c b/src/H5EAdblkpage.c new file mode 100644 index 0000000..4b9cc9d --- /dev/null +++ b/src/H5EAdblkpage.c @@ -0,0 +1,313 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: H5EAdblkpage.c + * Nov 20 2008 + * Quincey Koziol <koziol@hdfgroup.org> + * + * Purpose: Data block page 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 "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_dblk_page_t struct */ +H5FL_DEFINE_STATIC(H5EA_dblk_page_t); + + + +/*------------------------------------------------------------------------- + * Function: H5EA__dblk_page_alloc + * + * Purpose: Allocate extensible array data block page + * + * Return: Non-NULL pointer to data block on success/NULL on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5EA_dblk_page_t *, NULL, NULL, +H5EA__dblk_page_alloc(H5EA_hdr_t *hdr)) + + /* Local variables */ + H5EA_dblk_page_t *dblk_page = NULL; /* Extensible array data block page */ + + /* Check arguments */ + HDassert(hdr); + + /* Allocate memory for the data block */ + if(NULL == (dblk_page = H5FL_CALLOC(H5EA_dblk_page_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block page") + + /* Share common array information */ + if(H5EA__hdr_incr(hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + dblk_page->hdr = hdr; + + /* Set non-zero internal fields */ + /* <none> */ + + /* Allocate buffer for elements in data block page */ + if(NULL == (dblk_page->elmts = H5EA__hdr_alloc_elmts(hdr, hdr->dblk_page_nelmts))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block page element buffer") + + /* Set the return value */ + ret_value = dblk_page; + +CATCH + if(!ret_value) + if(dblk_page && H5EA__dblk_page_dest(dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block page") + +END_FUNC(PKG) /* end H5EA__dblk_page_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__dblk_page_create + * + * Purpose: Creates a new extensible array data block page in the file + * + * Return: Valid file address on success/HADDR_UNDEF on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5EA__dblk_page_create(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t addr)) + + /* Local variables */ + H5EA_dblk_page_t *dblk_page = NULL; /* Extensible array data block page */ + +#ifdef QAK +HDfprintf(stderr, "%s: Called, addr = %a\n", FUNC, addr); +#endif /* QAK */ + + /* Sanity check */ + HDassert(hdr); + + /* Allocate the data block page */ + if(NULL == (dblk_page = H5EA__dblk_page_alloc(hdr))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block page") + + /* Set info about data block page on disk */ + dblk_page->addr = addr; + dblk_page->size = H5EA_DBLK_PAGE_SIZE(dblk_page); +#ifdef QAK +HDfprintf(stderr, "%s: dblk_page->size = %Zu\n", FUNC, dblk_page->size); +#endif /* QAK */ + + /* Clear any elements in data block page to fill value */ + if((hdr->cparam.cls->fill)(dblk_page->elmts, (size_t)hdr->dblk_page_nelmts) < 0) + H5E_THROW(H5E_CANTSET, "can't set extensible array data block page elements to class's fill value") + + /* Cache the new extensible array data block page */ + if(H5AC_set(hdr->f, dxpl_id, H5AC_EARRAY_DBLK_PAGE, dblk_page->addr, dblk_page, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTINSERT, "can't add extensible array data block page to cache") + +CATCH + if(ret_value < 0) + if(dblk_page) { + /* Destroy data block page */ + if(H5EA__dblk_page_dest(dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy extensible array data block page") + } /* end if */ + +END_FUNC(PKG) /* end H5EA__dblk_page_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__dblk_page_protect + * + * Purpose: Convenience wrapper around protecting extensible array data + * block page + * + * Return: Non-NULL pointer to data block page on success/NULL on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5EA_dblk_page_t *, NULL, NULL, +H5EA__dblk_page_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_page_addr, + H5AC_protect_t rw)) + + /* Local variables */ + +#ifdef QAK +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* QAK */ + + /* Sanity check */ + HDassert(hdr); + HDassert(H5F_addr_defined(dblk_page_addr)); + + /* Protect the data block page */ + if(NULL == (ret_value = (H5EA_dblk_page_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_EARRAY_DBLK_PAGE, dblk_page_addr, NULL, hdr, rw))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block page, address = %llu", (unsigned long_long)dblk_page_addr) + +CATCH + +END_FUNC(PKG) /* end H5EA__dblk_page_protect() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__dblk_page_unprotect + * + * Purpose: Convenience wrapper around unprotecting extensible array + * data block page + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5EA__dblk_page_unprotect(H5EA_dblk_page_t *dblk_page, hid_t dxpl_id, + unsigned cache_flags)) + + /* Local variables */ + +#ifdef QAK +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* QAK */ + + /* Sanity check */ + HDassert(dblk_page); + + /* Unprotect the data block page */ + if(H5AC_unprotect(dblk_page->hdr->f, dxpl_id, H5AC_EARRAY_DBLK_PAGE, dblk_page->addr, dblk_page, cache_flags) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect extensible array data block page, address = %llu", (unsigned long_long)dblk_page->addr) + +CATCH + +END_FUNC(PKG) /* end H5EA__dblk_page_unprotect() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA__dblk_page_dest + * + * Purpose: Destroys an extensible array data block page in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 20 2008 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5EA__dblk_page_dest(H5EA_dblk_page_t *dblk_page)) + + /* Sanity check */ + HDassert(dblk_page); + + /* Check if header field has been initialized */ + if(dblk_page->hdr) { + /* Check if buffer for data block page elements has been initialized */ + if(dblk_page->elmts) { + /* Free buffer for data block page elements */ + if(H5EA__hdr_free_elmts(dblk_page->hdr, dblk_page->hdr->dblk_page_nelmts, dblk_page->elmts) < 0) + H5E_THROW(H5E_CANTFREE, "unable to free extensible array data block element buffer") + dblk_page->elmts = NULL; + } /* end if */ + + /* Decrement reference count on shared info */ + if(H5EA__hdr_decr(dblk_page->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + dblk_page->hdr = NULL; + } /* end if */ + + /* Free the data block page itself */ + (void)H5FL_FREE(H5EA_dblk_page_t, dblk_page); + +CATCH + +END_FUNC(PKG) /* end H5EA__dblk_page_dest() */ + diff --git a/src/H5EAdblock.c b/src/H5EAdblock.c index 12897bf..b64cb7d 100644 --- a/src/H5EAdblock.c +++ b/src/H5EAdblock.c @@ -104,7 +104,7 @@ H5EA_dblock_t *, NULL, NULL, H5EA__dblock_alloc(H5EA_hdr_t *hdr, size_t nelmts)) /* Local variables */ - H5EA_dblock_t *dblock = NULL; /* Extensible array index block */ + H5EA_dblock_t *dblock = NULL; /* Extensible array data block */ /* Check arguments */ HDassert(hdr); @@ -114,17 +114,25 @@ H5EA__dblock_alloc(H5EA_hdr_t *hdr, size_t nelmts)) if(NULL == (dblock = H5FL_CALLOC(H5EA_dblock_t))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array data block") - /* Set non-zero internal fields */ - dblock->nelmts = nelmts; - - /* Allocate buffer for elements in index block */ - if(NULL == (dblock->elmts = H5EA__hdr_alloc_elmts(hdr, nelmts))) - H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block element buffer") - /* Share common array information */ - dblock->hdr = hdr; if(H5EA__hdr_incr(hdr) < 0) H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + dblock->hdr = hdr; + + /* Set non-zero internal fields */ + dblock->nelmts = nelmts; + + /* Check if the data block is not going to be paged */ + if(nelmts > hdr->dblk_page_nelmts) { + /* Set the # of pages in the direct block */ + dblock->npages = nelmts / hdr->dblk_page_nelmts; + HDassert(nelmts == (dblock->npages * hdr->dblk_page_nelmts)); + } /* end if */ + else { + /* Allocate buffer for elements in data block */ + if(NULL == (dblock->elmts = H5EA__hdr_alloc_elmts(hdr, nelmts))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block element buffer") + } /* end else */ /* Set the return value */ ret_value = dblock; @@ -158,7 +166,7 @@ H5EA__dblock_create(H5EA_hdr_t *hdr, hid_t dxpl_id, hsize_t dblk_off, size_t nel H5EA_dblock_t *dblock = NULL; /* Extensible array data block */ #ifdef QAK -HDfprintf(stderr, "%s: Called\n", FUNC); +HDfprintf(stderr, "%s: Called, hdr->dblk_page_nelmts = %Zu, nelmts = %Zu\n", FUNC, hdr->dblk_page_nelmts, nelmts); #endif /* QAK */ /* Sanity check */ @@ -185,15 +193,17 @@ HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off); 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((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") + /* Don't initialize elements if paged */ + if(!dblock->npages) + /* Clear any elements in data block to fill value */ + 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(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") + H5E_THROW(H5E_CANTINSERT, "can't add extensible array data block to cache") - /* Set address of index block to return */ + /* Set address of data block to return */ ret_value = dblock->addr; CATCH @@ -369,6 +379,36 @@ HDfprintf(stderr, "%s: Called\n", FUNC); if(NULL == (dblock = H5EA__dblock_protect(hdr, dxpl_id, dblk_addr, dblk_nelmts, H5AC_WRITE))) H5E_THROW(H5E_CANTPROTECT, "unable to protect extensible array data block, address = %llu", (unsigned long_long)dblk_addr) + /* Check if this is a paged data block */ + if(dblk_nelmts > hdr->dblk_page_nelmts) { + size_t npages = dblk_nelmts / hdr->dblk_page_nelmts; /* Number of pages in data block */ + haddr_t dblk_page_addr; /* Address of each data block page */ + size_t dblk_page_size; /* Size of each data block page */ + size_t u; /* Local index variable */ + + /* Set up initial state */ + dblk_page_addr = dblk_addr + H5EA_DBLOCK_PREFIX_SIZE(dblock); + dblk_page_size = (hdr->dblk_page_nelmts * hdr->cparam.raw_elmt_size) + + H5EA_SIZEOF_CHKSUM; + + /* Iterate over pages in data block */ + for(u = 0; u < npages; u++) { +#ifdef QAK +HDfprintf(stderr, "%s: Expunging data block page from cache\n", FUNC); +#endif /* QAK */ + /* Evict the data block page from the metadata cache */ + /* (OK to call if it doesn't exist in the cache) */ + if(H5AC_expunge_entry(hdr->f, dxpl_id, H5AC_EARRAY_DBLK_PAGE, dblk_page_addr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTEXPUNGE, "unable to remove array data block page from metadata cache") +#ifdef QAK +HDfprintf(stderr, "%s: Done expunging data block page from cache\n", FUNC); +#endif /* QAK */ + + /* Advance to next page address */ + dblk_page_addr += dblk_page_size; + } /* end for */ + } /* end if */ + CATCH /* Finished deleting data block in metadata cache */ if(dblock && H5EA__dblock_unprotect(dblock, dxpl_id, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) @@ -397,20 +437,24 @@ H5EA__dblock_dest(H5F_t UNUSED *f, H5EA_dblock_t *dblock)) /* Sanity check */ HDassert(dblock); - HDassert(dblock->hdr); - - /* Check if we've got elements in the index block */ - if(dblock->nelmts > 0) { - /* Free buffer for data block elements */ - HDassert(dblock->elmts); - if(H5EA__hdr_free_elmts(dblock->hdr, dblock->nelmts, dblock->elmts) < 0) - H5E_THROW(H5E_CANTFREE, "unable to free extensible array data block element buffer") - dblock->elmts = NULL; - } /* end if */ - /* Decrement reference count on shared info */ - if(H5EA__hdr_decr(dblock->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + /* Check if shared header field has been initialized */ + if(dblock->hdr) { + /* Check if we've got elements in the data block */ + if(dblock->elmts && !dblock->npages) { + /* Free buffer for data block elements */ + HDassert(dblock->nelmts > 0); + if(H5EA__hdr_free_elmts(dblock->hdr, dblock->nelmts, dblock->elmts) < 0) + H5E_THROW(H5E_CANTFREE, "unable to free extensible array data block element buffer") + dblock->elmts = NULL; + dblock->nelmts = 0; + } /* end if */ + + /* Decrement reference count on shared info */ + if(H5EA__hdr_decr(dblock->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + dblock->hdr = NULL; + } /* end if */ /* Free the data block itself */ (void)H5FL_FREE(H5EA_dblock_t, dblock); diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c index c6cda2c..19cd196 100644 --- a/src/H5EAhdr.c +++ b/src/H5EAhdr.c @@ -205,7 +205,7 @@ H5EA__hdr_init(H5EA_hdr_t *hdr)) /* Compute general information */ hdr->nsblks = 1 + (hdr->cparam.max_nelmts_bits - H5V_log2_of2(hdr->cparam.data_blk_min_elmts)); hdr->dblk_page_nelmts = (size_t)1 << hdr->cparam.max_dblk_page_nelmts_bits; - hdr->arr_off_size = H5EA_SIZEOF_OFFSET_BITS(hdr->cparam.max_nelmts_bits); + hdr->arr_off_size = (unsigned char)H5EA_SIZEOF_OFFSET_BITS(hdr->cparam.max_nelmts_bits); #ifdef QAK HDfprintf(stderr, "%s: hdr->nsblks = %Zu\n", FUNC, hdr->nsblks); #endif /* QAK */ diff --git a/src/H5EAiblock.c b/src/H5EAiblock.c index 823e8b0..dcb75d1 100644 --- a/src/H5EAiblock.c +++ b/src/H5EAiblock.c @@ -119,6 +119,11 @@ H5EA__iblock_alloc(H5EA_hdr_t *hdr)) if(NULL == (iblock = H5FL_CALLOC(H5EA_iblock_t))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array index block") + /* Share common array information */ + if(H5EA__hdr_incr(hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + iblock->hdr = hdr; + /* Set non-zero internal fields */ iblock->addr = HADDR_UNDEF; @@ -147,11 +152,6 @@ HDfprintf(stderr, "%s: iblock->nsblk_addrs = %Zu\n", FUNC, iblock->nsblk_addrs); if(NULL == (iblock->sblk_addrs = H5FL_SEQ_MALLOC(haddr_t, iblock->nsblk_addrs))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for index block super block addresses") - /* 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 return value */ ret_value = iblock; @@ -425,33 +425,39 @@ H5EA__iblock_dest(H5F_t *f, H5EA_iblock_t *iblock)) HDassert(iblock); HDassert(iblock->rc == 0); - /* Set the shared array header's file context for this operation */ - iblock->hdr->f = f; + /* Check if shared header field has been initialized */ + if(iblock->hdr) { + /* 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->cparam.idx_blk_elmts > 0) { - /* Free buffer for index block elements */ - HDassert(iblock->elmts); - (void)H5FL_BLK_FREE(idx_blk_elmt_buf, iblock->elmts); - } /* end if */ + /* Check if we've got elements in the index block */ + if(iblock->elmts) { + /* Free buffer for index block elements */ + HDassert(iblock->hdr->cparam.idx_blk_elmts > 0); + iblock->elmts = H5FL_BLK_FREE(idx_blk_elmt_buf, iblock->elmts); + } /* end if */ - /* Check if we've got data block addresses in the index block */ - if(iblock->ndblk_addrs > 0) { - /* Free buffer for index block data block addresses */ - HDassert(iblock->dblk_addrs); - (void)H5FL_SEQ_FREE(haddr_t, iblock->dblk_addrs); - } /* end if */ + /* Check if we've got data block addresses in the index block */ + if(iblock->dblk_addrs) { + /* Free buffer for index block data block addresses */ + HDassert(iblock->ndblk_addrs > 0); + iblock->dblk_addrs = H5FL_SEQ_FREE(haddr_t, iblock->dblk_addrs); + iblock->ndblk_addrs = 0; + } /* end if */ - /* Check if we've got super block addresses in the index block */ - if(iblock->nsblk_addrs > 0) { - /* Free buffer for index block super block addresses */ - HDassert(iblock->sblk_addrs); - (void)H5FL_SEQ_FREE(haddr_t, iblock->sblk_addrs); - } /* end if */ + /* Check if we've got super block addresses in the index block */ + if(iblock->sblk_addrs) { + /* Free buffer for index block super block addresses */ + HDassert(iblock->nsblk_addrs > 0); + iblock->sblk_addrs = H5FL_SEQ_FREE(haddr_t, iblock->sblk_addrs); + iblock->nsblk_addrs = 0; + } /* 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") + /* 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") + iblock->hdr = NULL; + } /* end if */ /* Free the index block itself */ (void)H5FL_FREE(H5EA_iblock_t, iblock); diff --git a/src/H5EApkg.h b/src/H5EApkg.h index 6c70323..51305c4 100644 --- a/src/H5EApkg.h +++ b/src/H5EApkg.h @@ -411,8 +411,8 @@ func_init_failed: \ + ((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) ( \ +/* Size of the extensible array data block prefix on disk */ +#define H5EA_DBLOCK_PREFIX_SIZE(d) ( \ /* General metadata fields */ \ H5EA_METADATA_PREFIX_SIZE(TRUE) \ \ @@ -420,9 +420,22 @@ func_init_failed: \ + 1 /* Array type */ \ + (d)->hdr->sizeof_addr /* File address of array owning the block */ \ + (d)->hdr->arr_off_size /* Offset of the block in the array */ \ + ) + +/* Size of the extensible array data block on disk */ +#define H5EA_DBLOCK_SIZE(d) ( \ + /* Data block prefix size */ \ + H5EA_DBLOCK_PREFIX_SIZE(d) \ \ /* Extensible Array Data Block specific fields */ \ - + ((d)->nelmts * (size_t)(d)->hdr->cparam.raw_elmt_size) /* Elements in index block */ \ + + ((d)->nelmts * (size_t)(d)->hdr->cparam.raw_elmt_size) /* Elements in data block */ \ + + ((d)->npages * H5EA_SIZEOF_CHKSUM) /* Checksum for each page */ \ + ) + +/* Size of the extensible array data block page on disk */ +#define H5EA_DBLK_PAGE_SIZE(p) ( \ + + ((p)->hdr->dblk_page_nelmts * (size_t)(p)->hdr->cparam.raw_elmt_size) /* Elements in data block page */ \ + + H5EA_SIZEOF_CHKSUM /* Checksum for each page */ \ ) /* Compute the # of bytes required to store an offset into a given buffer size */ @@ -529,6 +542,7 @@ typedef struct H5EA_sblock_t { size_t dblk_nelmts; /* # of elements for data blocks reachable through this super block */ size_t dblk_npages; /* # of pages in each data block */ size_t dblk_page_init_size; /* Size of 'page init' bitmask for each data block */ + size_t dblk_page_size; /* Size of a data block page */ } H5EA_sblock_t; /* The extensible array data block information */ @@ -547,8 +561,26 @@ typedef struct H5EA_dblock_t { /* Computed/cached values (not stored) */ size_t nelmts; /* Number of elements in block */ + size_t npages; /* Nummber of pages in a block (zero if not paged) */ } H5EA_dblock_t; +/* The extensible array data block page information */ +typedef struct H5EA_dbk_page_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 data block page */ + + /* Internal array information (not stored) */ + H5EA_hdr_t *hdr; /* Shared array header info */ + haddr_t addr; /* Address of this data block page on disk */ + size_t size; /* Size of data block page on disk */ + + /* Computed/cached values (not stored) */ + /* <none> */ +} H5EA_dblk_page_t; + /* Extensible array */ struct H5EA_t { H5EA_hdr_t *hdr; /* Pointer to internal extensible array header info */ @@ -572,6 +604,9 @@ 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]; +/* H5EA data block page inherits cache-like properties from H5AC */ +H5_DLLVAR const H5AC_class_t H5AC_EARRAY_DBLK_PAGE[1]; + /* Internal extensible array testing class */ #ifdef H5EA_TESTING H5_DLLVAR const H5EA_class_t H5EA_CLS_TEST[1]; @@ -630,6 +665,16 @@ H5_DLL herr_t H5EA__dblock_delete(H5EA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_addr, size_t dblk_nelmts); H5_DLL herr_t H5EA__dblock_dest(H5F_t *f, H5EA_dblock_t *dblock); +/* Data block page routines */ +H5_DLL H5EA_dblk_page_t *H5EA__dblk_page_alloc(H5EA_hdr_t *hdr); +H5_DLL herr_t H5EA__dblk_page_create(H5EA_hdr_t *hdr, hid_t dxpl_id, + haddr_t addr); +H5_DLL H5EA_dblk_page_t *H5EA__dblk_page_protect(H5EA_hdr_t *hdr, hid_t dxpl_id, + haddr_t dblk_page_addr, H5AC_protect_t rw); +H5_DLL herr_t H5EA__dblk_page_unprotect(H5EA_dblk_page_t *dblk_page, + hid_t dxpl_id, unsigned cache_flags); +H5_DLL herr_t H5EA__dblk_page_dest(H5EA_dblk_page_t *dblk_page); + /* Debugging routines for dumping file structures */ H5_DLL herr_t H5EA__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, const H5EA_class_t *cls); diff --git a/src/H5EAsblock.c b/src/H5EAsblock.c index 955788a..3d3d4e3 100644 --- a/src/H5EAsblock.c +++ b/src/H5EAsblock.c @@ -119,6 +119,11 @@ H5EA__sblock_alloc(H5EA_hdr_t *hdr, unsigned sblk_idx)) if(NULL == (sblock = H5FL_CALLOC(H5EA_sblock_t))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array super block") + /* Share common array information */ + if(H5EA__hdr_incr(hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + sblock->hdr = hdr; + /* Set non-zero internal fields */ sblock->addr = HADDR_UNDEF; @@ -153,12 +158,11 @@ HDfprintf(stderr, "%s: hdr->dblk_page_nelmts = %Zu, sblock->ndblks = %Zu, sblock /* Allocate buffer for all 'page init' bitmasks in super block */ if(NULL == (sblock->page_init = H5FL_BLK_CALLOC(page_init, sblock->ndblks * sblock->dblk_page_init_size))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for super block page init bitmask") - } /* end if */ - /* 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") + /* Compute data block page size */ + sblock->dblk_page_size = (hdr->dblk_page_nelmts * hdr->cparam.raw_elmt_size) + + H5EA_SIZEOF_CHKSUM; + } /* end if */ /* Set the return value */ ret_value = sblock; @@ -394,22 +398,26 @@ H5EA__sblock_dest(H5F_t *f, H5EA_sblock_t *sblock)) HDfprintf(stderr, "%s: sblock->hdr->dblk_page_nelmts = %Zu, sblock->ndblks = %Zu, sblock->dblk_nelmts = %Zu\n", FUNC, sblock->hdr->dblk_page_nelmts, sblock->ndblks, sblock->dblk_nelmts); #endif /* QAK */ - /* Set the shared array header's file context for this operation */ - sblock->hdr->f = f; + /* Check if shared header field has been initialized */ + if(sblock->hdr) { + /* Set the shared array header's file context for this operation */ + sblock->hdr->f = f; - /* Free buffer for super block data block addresses, if there are any */ - if(sblock->dblk_addrs) - (void)H5FL_SEQ_FREE(haddr_t, sblock->dblk_addrs); + /* Free buffer for super block data block addresses, if there are any */ + if(sblock->dblk_addrs) + sblock->dblk_addrs = H5FL_SEQ_FREE(haddr_t, sblock->dblk_addrs); - /* Free buffer for super block 'page init' bitmask, if there is one */ - if(sblock->page_init) { - HDassert(sblock->dblk_npages > 0); - (void)H5FL_BLK_FREE(page_init, sblock->page_init); - } /* end if */ + /* Free buffer for super block 'page init' bitmask, if there is one */ + if(sblock->page_init) { + HDassert(sblock->dblk_npages > 0); + sblock->page_init = H5FL_BLK_FREE(page_init, sblock->page_init); + } /* 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") + /* 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") + sblock->hdr = NULL; + } /* end if */ /* Free the super block itself */ (void)H5FL_FREE(H5EA_sblock_t, sblock); diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index fa30202..b1e1482 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -99,8 +99,8 @@ typedef enum H5FD_mem_t { * 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. + * Map "extensible array" data blocks & pages to 'lheap' type file memory, since + * they are similar enough to local heap info. * * -QAK */ @@ -108,6 +108,7 @@ typedef enum H5FD_mem_t { #define H5FD_MEM_EARRAY_IBLOCK H5FD_MEM_OHDR #define H5FD_MEM_EARRAY_SBLOCK H5FD_MEM_BTREE #define H5FD_MEM_EARRAY_DBLOCK H5FD_MEM_LHEAP +#define H5FD_MEM_EARRAY_DBLK_PAGE H5FD_MEM_LHEAP /* * A free-list map which maps all types of allocation requests to a single diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h index c8c5051..446c852 100644 --- a/src/H5FLprivate.h +++ b/src/H5FLprivate.h @@ -331,7 +331,7 @@ typedef struct H5FL_seq_head_t { #define H5FL_SEQ_CALLOC(t,elem) (t *)H5FL_seq_calloc(&(H5FL_SEQ_NAME(t)),elem H5FL_TRACK_INFO) /* Free a sequence of type 't' */ -#define H5FL_SEQ_FREE(t,obj) H5FL_seq_free(&(H5FL_SEQ_NAME(t)),obj) +#define H5FL_SEQ_FREE(t,obj) (t *)H5FL_seq_free(&(H5FL_SEQ_NAME(t)),obj) /* Re-allocate a sequence of type 't' */ #define H5FL_SEQ_REALLOC(t,obj,new_elem) (t *)H5FL_seq_realloc(&(H5FL_SEQ_NAME(t)),obj,new_elem H5FL_TRACK_INFO) diff --git a/src/H5Vprivate.h b/src/H5Vprivate.h index 2390584..1dec0c0 100644 --- a/src/H5Vprivate.h +++ b/src/H5Vprivate.h @@ -428,5 +428,65 @@ H5V_limit_enc_size(uint64_t limit) return (H5V_log2_gen(limit) / 8) + 1; } /* end H5V_limit_enc_size() */ +static const unsigned char H5V_bit_set_g[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; +static const unsigned char H5V_bit_clear_g[8] = {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}; + + +/*------------------------------------------------------------------------- + * Function: H5V_bit_get + * + * Purpose: Determine the value of the n'th bit in a buffer. + * + * Note: No range checking on <offset> is performed! + * + * Note #2: Bits are sequentially stored in the buffer, starting with bit + * offset 0 in the first byte's high-bit position, proceeding down + * to bit offset 7 in the first byte's low-bit position, then to + * bit offset 8 in the second byte's high-bit position, etc. + * + * Return: TRUE/FALSE + * + * Programmer: Quincey Koziol + * Tuesday, November 25, 2008 + * + *------------------------------------------------------------------------- + */ +static H5_inline hbool_t UNUSED +H5V_bit_get(const unsigned char *buf, size_t offset) +{ + /* Test the appropriate bit in the buffer */ + return (hbool_t)((buf[offset / 8] & (H5V_bit_set_g[offset % 8])) ? TRUE : FALSE); +} /* end H5V_bit_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5V_bit_set + * + * Purpose: Set/reset the n'th bit in a buffer. + * + * Note: No range checking on <offset> is performed! + * + * Note #2: Bits are sequentially stored in the buffer, starting with bit + * offset 0 in the first byte's high-bit position, proceeding down + * to bit offset 7 in the first byte's low-bit position, then to + * bit offset 8 in the second byte's high-bit position, etc. + * + * Return: None + * + * Programmer: Quincey Koziol + * Tuesday, November 25, 2008 + * + *------------------------------------------------------------------------- + */ +static H5_inline void UNUSED +H5V_bit_set(unsigned char *buf, size_t offset, hbool_t val) +{ + /* Set/reset the appropriate bit in the buffer */ + if(val) + buf[offset / 8] |= H5V_bit_set_g[offset % 8]; + else + buf[offset / 8] &= H5V_bit_clear_g[offset % 8]; +} /* end H5V_bit_set() */ + #endif /* H5Vprivate_H */ diff --git a/src/Makefile.am b/src/Makefile.am index ccdb189..b59918c 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,8 +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 H5EAdbg.c H5EAdblock.c H5EAhdr.c H5EAiblock.c \ - H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ + H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ + H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Ftest.c \ H5FD.c H5FDcore.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 60aacd4..5340904 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -86,36 +86,36 @@ 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 H5EAdbg.lo H5EAdblock.lo \ - H5EAhdr.lo H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo \ - H5EAtest.lo H5F.lo H5Faccum.lo H5Fdbg.lo H5Ffake.lo H5Fio.lo \ - H5Fmount.lo H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.lo \ - H5Ftest.lo H5FD.lo H5FDcore.lo H5FDdirect.lo H5FDfamily.lo \ - H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo H5FDmpiposix.lo \ - H5FDmulti.lo H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo \ - H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo H5FSsection.lo \ - H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo H5Gcache.lo \ - H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo H5Gint.lo \ - H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo \ - H5Gstab.lo H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo \ - H5HFcache.lo H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo \ - H5HFhuge.lo H5HFiblock.lo H5HFiter.lo H5HFman.lo \ - H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \ - H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HL.lo \ - H5HLcache.lo H5HLdbg.lo H5HP.lo H5I.lo H5L.lo H5Lexternal.lo \ - H5MF.lo H5MFaggr.lo H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo \ - H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ - H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ - H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo \ - H5Oefl.lo H5Ofill.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo \ - H5Olink.lo H5Omessage.lo H5Omtime.lo H5Oname.lo H5Onull.lo \ - H5Opline.lo H5Orefcount.lo H5Osdspace.lo H5Oshared.lo \ - H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo \ - H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo \ - H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \ - H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \ - H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo \ - H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ + H5Eint.lo H5EA.lo H5EAcache.lo H5EAdbg.lo H5EAdblkpage.lo \ + H5EAdblock.lo H5EAhdr.lo H5EAiblock.lo H5EAint.lo \ + H5EAsblock.lo H5EAstat.lo H5EAtest.lo H5F.lo H5Faccum.lo \ + H5Fdbg.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ + H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Ftest.lo H5FD.lo \ + H5FDcore.lo H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo \ + H5FDmpi.lo H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo \ + H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo \ + H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \ + H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ + H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ + H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \ + H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo \ + H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ + H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \ + H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \ + H5HGcache.lo H5HGdbg.lo H5HL.lo H5HLcache.lo H5HLdbg.lo \ + H5HP.lo H5I.lo H5L.lo H5Lexternal.lo H5MF.lo H5MFaggr.lo \ + H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ + H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \ + H5Obtreek.lo H5Ocache.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo \ + H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \ + H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo \ + H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ + H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \ + H5P.lo H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo \ + H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo \ + H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo \ + H5Pstrcpl.lo H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo \ + H5S.lo H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ H5Spoint.lo H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo \ H5SMbtree2.lo H5SMcache.lo H5SMtest.lo H5ST.lo H5T.lo \ H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo \ @@ -434,8 +434,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 H5EAdbg.c H5EAdblock.c H5EAhdr.c H5EAiblock.c \ - H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ + H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ + H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Ftest.c \ H5FD.c H5FDcore.c \ @@ -653,6 +653,7 @@ 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)/H5EAdbg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAdblkpage.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAdblock.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@ diff --git a/test/earray.c b/test/earray.c index 053fc14..c80352d 100644 --- a/test/earray.c +++ b/test/earray.c @@ -2325,7 +2325,7 @@ main(void) /* Super Block capacity tests */ ndblks = 0; - for(sblk = 0; sblk < 8; sblk++) { + for(sblk = 0; sblk < 9; sblk++) { for(dblk = 0; dblk < tparam.sblk_info[sblk].ndblks; dblk ++) { /* Test first element in data block */ nelmts = (hsize_t)(1 + cparam.idx_blk_elmts + @@ -2354,6 +2354,7 @@ main(void) nerrors += test_skip_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (31 * cparam.data_blk_min_elmts) + 1), "skipping 1st super block elements"); nerrors += test_skip_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (63 * cparam.data_blk_min_elmts) + 1), "skipping 2nd super block elements"); nerrors += test_skip_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (127 * cparam.data_blk_min_elmts) + 1), "skipping 3rd super block elements"); + nerrors += test_skip_elmts(fapl, &cparam, &tparam, (hsize_t)(cparam.idx_blk_elmts + (255 * cparam.data_blk_min_elmts) + 1), "skipping 4th super block elements"); /* Close down testing parameters */ finish_tparam(&tparam); |